{ "cells": [ { "cell_type": "markdown", "id": "c4c1bfe6", "metadata": {}, "source": [ "# 04 — Trading Programatico (Binance API)\n", "\n", "Operaciones de trading via REST API con autenticacion HMAC-SHA256.\n", "\n", "**Autenticacion:** Cada request firmado necesita:\n", "1. Header `X-MBX-APIKEY` con tu API key\n", "2. Parametro `timestamp` (unix ms, dentro de 5000ms del server)\n", "3. Parametro `signature` = HMAC-SHA256(query_string, secret_key)\n", "\n", "**Endpoints de trading (Spot):**\n", "| Accion | Metodo | Endpoint | Weight |\n", "|---|---|---|---|\n", "| Crear orden | POST | `/api/v3/order` | 1 |\n", "| Test orden | POST | `/api/v3/order/test` | 1 |\n", "| Cancelar orden | DELETE | `/api/v3/order` | 1 |\n", "| Cancelar todas | DELETE | `/api/v3/openOrders` | 1 |\n", "| Ver orden | GET | `/api/v3/order` | 4 |\n", "| Ordenes abiertas | GET | `/api/v3/openOrders` | 6 |\n", "| Cuenta/balances | GET | `/api/v3/account` | 20 |\n", "| Mis trades | GET | `/api/v3/myTrades` | 20 |\n", "\n", "**Tipos de orden:** MARKET, LIMIT (GTC/IOC/FOK), STOP_LOSS_LIMIT, TAKE_PROFIT_LIMIT, LIMIT_MAKER\n", "\n", "**TESTNET:** `https://testnet.binance.vision` — mismo API, balances gratis, keys via GitHub login" ] }, { "cell_type": "code", "execution_count": null, "id": "599a54e7", "metadata": {}, "outputs": [], "source": [ "import hashlib\n", "import hmac\n", "import time\n", "import math\n", "import requests\n", "import pandas as pd\n", "\n", "# --- CONFIGURACION ---\n", "# Para testnet (seguro para pruebas):\n", "BASE = \"https://testnet.binance.vision\"\n", "# Para produccion (dinero real):\n", "# BASE = \"https://api.binance.com\"\n", "\n", "# Crea tus keys en https://testnet.binance.vision (login con GitHub)\n", "API_KEY = \"\" # <-- tu API key aqui\n", "API_SECRET = \"\" # <-- tu secret aqui" ] }, { "cell_type": "markdown", "id": "acc0b354", "metadata": {}, "source": [ "## Firma HMAC-SHA256\n", "\n", "Toda request autenticada requiere `timestamp` + `signature`. La firma es HMAC del query string completo." ] }, { "cell_type": "code", "execution_count": null, "id": "3fa09567", "metadata": {}, "outputs": [], "source": [ "def signed_request(method: str, endpoint: str, params: dict | None = None) -> dict:\n", " \"\"\"Request firmado a Binance API (funciona con testnet y produccion).\"\"\"\n", " if params is None:\n", " params = {}\n", "\n", " params[\"timestamp\"] = int(time.time() * 1000)\n", " params[\"recvWindow\"] = 5000\n", "\n", " query_string = \"&\".join(f\"{k}={v}\" for k, v in params.items())\n", " signature = hmac.new(\n", " API_SECRET.encode(), query_string.encode(), hashlib.sha256\n", " ).hexdigest()\n", " params[\"signature\"] = signature\n", "\n", " headers = {\"X-MBX-APIKEY\": API_KEY}\n", "\n", " if method == \"GET\":\n", " resp = requests.get(f\"{BASE}{endpoint}\", params=params, headers=headers)\n", " elif method == \"POST\":\n", " resp = requests.post(f\"{BASE}{endpoint}\", params=params, headers=headers)\n", " elif method == \"DELETE\":\n", " resp = requests.delete(f\"{BASE}{endpoint}\", params=params, headers=headers)\n", " else:\n", " raise ValueError(f\"Metodo no soportado: {method}\")\n", "\n", " resp.raise_for_status()\n", " return resp.json()" ] }, { "cell_type": "markdown", "id": "725c3d14", "metadata": {}, "source": [ "## Consultar informacion del simbolo (filtros de ordenes)\n", "\n", "Antes de operar, hay que conocer los filtros: `LOT_SIZE` (min/max qty, step), `PRICE_FILTER` (tick size), `NOTIONAL` (min valor en quote)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.7" } }, "nbformat": 4, "nbformat_minor": 5 }