{ "cells": [ { "cell_type": "markdown", "id": "45f026b5", "metadata": {}, "source": [ "# 02 — Streaming de Datos en Tiempo Real (Binance WebSocket)\n", "\n", "Binance ofrece WebSocket streams push-based para datos de mercado en tiempo real.\n", "\n", "**Base URLs:**\n", "- Produccion: `wss://stream.binance.com:9443/ws/`\n", "- Testnet: `wss://testnet.binance.vision/ws/`\n", "- Multi-stream: `wss://stream.binance.com:9443/stream?streams=/`\n", "\n", "**Streams principales:**\n", "| Stream | Nombre | Frecuencia |\n", "|---|---|---|\n", "| Trades individuales | `@trade` | Cada trade |\n", "| Klines en vivo | `@kline_` | Cada cambio en vela |\n", "| Mini ticker 24h | `@miniTicker` | ~1s |\n", "| Book ticker (best bid/ask) | `@bookTicker` | Cada cambio |\n", "| Todos los tickers | `!miniTicker@arr` | ~1s |\n", "\n", "**Reglas de conexion:**\n", "- Ping cada 3 min desde Binance, pong requerido\n", "- Desconexion automatica a las 24h — reconectar periodicamente\n", "- Se puede suscribir/desuscribir dinamicamente via JSON" ] }, { "cell_type": "code", "execution_count": null, "id": "6bb48c2e", "metadata": {}, "outputs": [], "source": [ "import asyncio\n", "import json\n", "import websockets\n", "import pandas as pd\n", "from datetime import datetime, timezone\n", "from collections import deque\n", "\n", "WS_BASE = \"wss://stream.binance.com:9443/ws\"" ] }, { "cell_type": "markdown", "id": "2b2d9b2d", "metadata": {}, "source": [ "## Stream de Trades individuales\n", "\n", "`@trade` — recibe cada trade ejecutado en tiempo real.\n", "\n", "Campos clave:\n", "- `p` = precio, `q` = cantidad\n", "- `m` = true si el buyer es maker (es decir, fue un sell market order que impacto un bid)\n", "- `t` = trade ID, `T` = timestamp" ] }, { "cell_type": "code", "execution_count": null, "id": "aaed9f77", "metadata": {}, "outputs": [], "source": [ "async def stream_trades(symbol: str, max_trades: int = 100) -> list[dict]:\n", " \"\"\"Captura N trades en tiempo real y retorna como lista.\"\"\"\n", " url = f\"{WS_BASE}/{symbol.lower()}@trade\"\n", " trades = []\n", "\n", " async with websockets.connect(url) as ws:\n", " while len(trades) < max_trades:\n", " msg = json.loads(await ws.recv())\n", " trades.append({\n", " \"trade_id\": msg[\"t\"],\n", " \"time\": datetime.fromtimestamp(msg[\"T\"] / 1000, tz=timezone.utc),\n", " \"price\": float(msg[\"p\"]),\n", " \"qty\": float(msg[\"q\"]),\n", " \"is_buyer_maker\": msg[\"m\"],\n", " \"side\": \"SELL\" if msg[\"m\"] else \"BUY\",\n", " })\n", "\n", " return trades" ] } ], "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 }