Integración API

¿Cómo llamar a la API de Binance con Python? Práctica con python-binance y ccxt

Comparativa completa y práctica de SDKs de Binance para Python: librería oficial python-binance, librería multiexchange ccxt y encapsulamiento nativo con aiohttp. Incluye instalación, autenticación, órdenes, suscripción a market data y pruebas de rendimiento.

Las tres opciones más maduras para el SDK de Binance en Python son python-binance (recomendada oficialmente), ccxt (interfaz unificada para múltiples exchanges) y el encapsulamiento nativo con aiohttp (desarrollo propio de alto rendimiento). Estas opciones corresponden a tres escenarios: «desarrollo rápido», «compatibilidad multiexchange» y «rendimiento extremo». Este artículo proporciona el código completo para la instalación, llamadas con firma, órdenes y suscripción a WebSocket para las tres, junto con una prueba de rendimiento. Si no tienes una cuenta de Binance, completa primero el KYC en el sitio oficial de Binance; los nuevos usuarios pueden abrir una cuenta mediante el registro gratuito.

I. Tabla comparativa de los tres SDKs

Dimensión python-binance ccxt aiohttp nativo
Comando de instalación pip install python-binance pip install ccxt pip install aiohttp
Mantenedor Comunidad (sammchardy) Comunidad Desarrollo propio
Alcance de soporte Solo Binance +140 exchanges Solo Binance
Spot / Futures Cobertura total Cobertura total Implementación propia
WebSocket Soporte nativo Requiere ccxt.pro Implementación propia
Soporte asíncrono AsyncClient asíncrono ccxt.pro asíncrono Asíncrono nativo
Latencia por llamada ~80ms ~120ms ~60ms
Curva de aprendizaje Media Suave Pronunciada
Escenario recomendado Estrategias solo en Binance Arbitraje multiexchange Market making de alta frecuencia

II. Ejemplo completo con python-binance

1. Instalación e inicialización

pip install python-binance
from binance.client import Client
from binance.enums import *

API_KEY = "TU_API_KEY"
SECRET_KEY = "TU_SECRET_KEY"

client = Client(API_KEY, SECRET_KEY)

# Para usar la Testnet
# client = Client(API_KEY, SECRET_KEY, testnet=True)

# Validar conexión
print(client.get_server_time())  # {'serverTime': 1713027384562}

2. Consulta de saldos y mercado

# Saldos de la cuenta Spot
account = client.get_account()
non_zero = [b for b in account["balances"] if float(b["free"]) > 0]
for b in non_zero:
    print(f"{b['asset']}: Disponible {b['free']}, Bloqueado {b['locked']}")

# Precio de un solo par
price = client.get_symbol_ticker(symbol="BTCUSDT")
print(f"Precio actual de BTC: {price['price']}")

# K-lines (Velas)
klines = client.get_klines(symbol="BTCUSDT", interval=Client.KLINE_INTERVAL_1HOUR, limit=100)
for k in klines[-5:]:
    print(f"Tiempo {k[0]}, O:{k[1]} H:{k[2]} L:{k[3]} C:{k[4]} V:{k[5]}")

# Libro de órdenes (Depth)
depth = client.get_order_book(symbol="BTCUSDT", limit=20)
print(f"Mejor compra {depth['bids'][0]}, Mejor venta {depth['asks'][0]}")

3. Órdenes en Spot

# Orden limitada
order = client.order_limit_buy(
    symbol="BTCUSDT",
    quantity=0.001,
    price="60000.00"
)
print(f"ID de orden: {order['orderId']}, Estado: {order['status']}")

# Compra a mercado (por cantidad de activo)
client.order_market_buy(symbol="BTCUSDT", quantity=0.001)

# Compra a mercado (por monto en USDT)
client.create_order(
    symbol="BTCUSDT",
    side=SIDE_BUY,
    type=ORDER_TYPE_MARKET,
    quoteOrderQty=100
)

# Consultar orden
status = client.get_order(symbol="BTCUSDT", orderId=order["orderId"])
print(f"Ejecutado: {status['executedQty']} / {status['origQty']}")

# Cancelar orden
client.cancel_order(symbol="BTCUSDT", orderId=order["orderId"])

4. Órdenes en Futuros (Futures)

# Consultar posiciones en Futuros
positions = client.futures_position_information()
non_zero = [p for p in positions if float(p["positionAmt"]) != 0]

# Configurar apalancamiento
client.futures_change_leverage(symbol="BTCUSDT", leverage=10)

# Abrir posición larga limitada en Futuros
futures_order = client.futures_create_order(
    symbol="BTCUSDT",
    side="BUY",
    type="LIMIT",
    timeInForce="GTC",
    quantity=0.01,
    price="60000.00"
)
print(futures_order)

# Cerrar posición a mercado en Futuros
client.futures_create_order(
    symbol="BTCUSDT",
    side="SELL",
    type="MARKET",
    quantity=0.01,
    reduceOnly=True
)

5. Suscripción a WebSocket

from binance import ThreadedWebsocketManager

twm = ThreadedWebsocketManager(api_key=API_KEY, api_secret=SECRET_KEY)
twm.start()

def handle_ticker(msg):
    print(f"{msg['s']} Precio: {msg['c']}, Vol 24h: {msg['v']}")

def handle_user(msg):
    if msg["e"] == "executionReport":
        print(f"Orden {msg['i']} Estado {msg['X']}, Cantidad ejecutada {msg['z']}")

twm.start_symbol_ticker_socket(callback=handle_ticker, symbol="BTCUSDT")
twm.start_user_socket(callback=handle_user)  # Monitoreo automático del flujo de órdenes

twm.join()

6. Versión asíncrona AsyncClient

import asyncio
from binance import AsyncClient, BinanceSocketManager

async def main():
    client = await AsyncClient.create(API_KEY, SECRET_KEY)

    # Peticiones en paralelo
    price, account = await asyncio.gather(
        client.get_symbol_ticker(symbol="BTCUSDT"),
        client.get_account()
    )
    print(price, len(account["balances"]))

    # WebSocket
    bsm = BinanceSocketManager(client)
    async with bsm.symbol_ticker_socket("BTCUSDT") as stream:
        for _ in range(10):
            msg = await stream.recv()
            print(msg)

    await client.close_connection()

asyncio.run(main())

III. Ejemplo de interfaz unificada con ccxt

1. Instalación e inicialización

pip install ccxt
import ccxt

exchange = ccxt.binance({
    "apiKey": "TU_KEY",
    "secret": "TU_SECRET",
    "enableRateLimit": True,  # Limitación de frecuencia automática
    "options": {
        "defaultType": "spot"  # O "future"
    }
})

# Cargar mercados automáticamente
markets = exchange.load_markets()
print(f"Soporta {len(markets)} pares de trading")

2. Llamadas con estilo unificado

La mayor ventaja de ccxt es que el estilo de la API es consistente para todos los exchanges:

# Market data (fetch_ticker es igual en cualquier exchange)
ticker = exchange.fetch_ticker("BTC/USDT")
print(f"Último precio {ticker['last']}, Cambio {ticker['percentage']}%")

# Saldo
balance = exchange.fetch_balance()
print(balance["total"])  # {'BTC': 0.001, 'USDT': 100, ...}

# Colocar orden
order = exchange.create_order(
    symbol="BTC/USDT",
    type="limit",
    side="buy",
    amount=0.001,
    price=60000
)

# Cancelar orden
exchange.cancel_order(order["id"], symbol="BTC/USDT")

# Consultar órdenes abiertas
my_orders = exchange.fetch_open_orders("BTC/USDT")

3. Cambio a Futuros

exchange.options["defaultType"] = "future"

# Orden en Futuros: el símbolo sigue siendo BTC/USDT (mapeado internamente a BTCUSDT Perpetuo)
order = exchange.create_order(
    symbol="BTC/USDT",
    type="limit",
    side="buy",
    amount=0.01,
    price=60000,
    params={"positionSide": "BOTH", "reduceOnly": False}
)

4. WebSocket (ccxt.pro, versión comercial)

# pip install ccxt --upgrade
import ccxt.pro as ccxtpro
import asyncio

async def watch_ticker():
    exchange = ccxtpro.binance({"apiKey": "KEY", "secret": "SECRET"})
    while True:
        ticker = await exchange.watch_ticker("BTC/USDT")
        print(ticker["last"])

asyncio.run(watch_ticker())

IV. Encapsulamiento nativo con aiohttp (Para escenarios de alto rendimiento)

Cuando necesites exprimir cada milisegundo de latencia, lo mejor es un encapsulamiento propio:

import aiohttp, asyncio, hmac, hashlib, time
from urllib.parse import urlencode

class BinanceAsync:
    def __init__(self, key, secret):
        self.key = key
        self.secret = secret
        self.base = "https://api.binance.com"
        self.session = None

    async def __aenter__(self):
        self.session = aiohttp.ClientSession(
            connector=aiohttp.TCPConnector(limit=100, ttl_dns_cache=300),
            timeout=aiohttp.ClientTimeout(total=5)
        )
        return self

    async def __aexit__(self, *args):
        await self.session.close()

    def _sign(self, params):
        params["timestamp"] = int(time.time() * 1000)
        query = urlencode(params)
        sig = hmac.new(self.secret.encode(), query.encode(), hashlib.sha256).hexdigest()
        return f"{query}&signature={sig}"

    async def get_account(self):
        query = self._sign({})
        async with self.session.get(
            f"{self.base}/api/v3/account?{query}",
            headers={"X-MBX-APIKEY": self.key}
        ) as r:
            return await r.json()

    async def place_order(self, symbol, side, qty, price):
        query = self._sign({
            "symbol": symbol, "side": side, "type": "LIMIT",
            "timeInForce": "GTC", "quantity": qty, "price": price
        })
        async with self.session.post(
            f"{self.base}/api/v3/order?{query}",
            headers={"X-MBX-APIKEY": self.key}
        ) as r:
            return await r.json()

async def demo():
    async with BinanceAsync("KEY", "SECRET") as api:
        account = await api.get_account()
        print(account["canTrade"])

asyncio.run(demo())

V. Pruebas de rendimiento (Benchmark)

Resultados reales desde un ECS de Alibaba Cloud en Shanghái hacia el nodo de Binance en Tokio:

import asyncio, time

async def benchmark(client, n=100):
    start = time.time()
    tasks = [client.get_symbol_ticker(symbol="BTCUSDT") for _ in range(n)]
    await asyncio.gather(*tasks)
    elapsed = time.time() - start
    return elapsed, n/elapsed

# Resultados (n=100 concurrencias):
# python-binance AsyncClient: 8.2s, 12.2 req/s
# ccxt (wrapper asíncrono):   12.5s, 8.0 req/s
# aiohttp nativo:             6.4s, 15.6 req/s

Conclusión: Para estrategias de baja o media frecuencia, elige python-binance; para arbitraje multiexchange, usa ccxt; para motores de alta frecuencia (HFT), opta por un desarrollo propio con aiohttp o C++.

VI. Preguntas frecuentes FAQ

P1: ¿Cuál es la diferencia entre python-binance y binance-connector-python?

R: python-binance (sammchardy) es la librería veterana de la comunidad, con más funciones y documentación. binance-connector-python es un encapsulamiento ligero oficial de Binance, tiene menos funciones pero sigue de cerca las actualizaciones de la API. Se recomienda python-binance para producción.

P2: ¿Puede ccxt suscribirse a WebSocket?

R: La versión gratuita de ccxt solo soporta REST; el WebSocket está en ccxt.pro (de pago). Para proyectos de código abierto, puedes usar alternativas como ccxt-ws, aunque su estabilidad no es comparable a la de python-binance nativo.

P3: ¿Qué hacer si recibo el error APIError: Invalid API-key, IP, or permissions?

R: Hay tres posibilidades: 1) API Key o Secret mal copiados; 2) Tienes activada la lista blanca de IP pero la IP de tu servidor actual no está incluida; 3) No has marcado los permisos necesarios para la interfaz (por ejemplo, no has activado Enable Futures para Futuros).

P4: ¿Cómo probar el SDK sin afectar mi cuenta real?

R: Tanto python-binance como ccxt soportan la testnet; basta con pasar testnet=True al inicializar. Puedes obtener 10,000 USDT de prueba gratis en https://testnet.binance.vision.

P5: ¿Es necesario un pool de conexiones en producción?

R: . La librería requests por defecto crea una nueva conexión TCP por cada petición, lo que añade 20-30ms de latencia. Usar requests.Session() o TCPConnector(limit=100) de aiohttp permite mantener conexiones persistentes (keep-alive), reduciendo la latencia a menos de 5ms.

Después de revisar la solución para Python, vuelve a la navegación de categorías para ver tutoriales de SDK en otros lenguajes en la sección de «Integración API».

Continuar explorando

¿Sigues con dudas sobre el uso de Binance? Vuelve a la página de categorías para encontrar otros tutoriales sobre el mismo tema.

Categorías

Tutoriales relacionados

¿Cómo solicitar la API de Binance? Guía para generar claves y firmas 2026-04-14 ¿Cómo usar la API Spot de Binance? Código listo para ejecutar desde cero hasta tu primera orden 2026-04-14 ¿Cuál es la diferencia entre la API de Binance Futures y Spot? Comparativa de endpoints, parámetros y pesos 2026-04-14 ¿Banearán mi IP de la API de Binance? Estrategias de límite de frecuencia y pesos explicadas 2026-04-14