Práctica: Script para monitorear precios de criptomonedas

Lectura
30 min~5 min lectura

Concepto clave

El monitoreo de precios en tiempo real es el sistema nervioso de cualquier bot de trading algorítmico. Imagina que estás construyendo un radar financiero que escanea constantemente el mercado, similar a cómo un controlador aéreo monitorea aviones en un aeropuerto. Este script no toma decisiones de trading por sí solo, sino que proporciona los datos crudos necesarios para que tus estrategias funcionen.

La conexión con la API de Binance funciona como una suscripción a un servicio de noticias financieras en tiempo real. En lugar de recibir periódicos cada día, obtienes actualizaciones de precios cada segundo o incluso más rápido. La clave está en establecer una conexión eficiente que pueda manejar múltiples pares de trading simultáneamente sin consumir recursos excesivos o violar los límites de la API.

Cómo funciona en la práctica

Vamos a construir un script que monitoree tres criptomonedas principales: BTC/USDT, ETH/USDT y SOL/USDT. El proceso sigue estos pasos:

  1. Configuración de credenciales API de Binance (clave y secreto)
  2. Establecimiento de conexión usando la biblioteca python-binance
  3. Implementación de un bucle que consulta precios periódicamente
  4. Procesamiento y almacenamiento de datos para análisis posterior
  5. Manejo de errores y reconexiones automáticas

Antes de comenzar, necesitas tener una cuenta en Binance con API habilitada. La configuración inicial es similar a obtener credenciales de acceso para un sistema bancario online: necesitas un identificador único (API Key) y una contraseña (Secret Key) que nunca debes compartir.

Código en acción

Primero, instalemos las dependencias necesarias:

pip install python-binance pandas

Ahora el script principal. Versión inicial básica:

from binance.client import Client
from binance.exceptions import BinanceAPIException
import pandas as pd
import time

# Configuración inicial (NO hardcodear en producción)
API_KEY = 'tu_api_key_aqui'
API_SECRET = 'tu_api_secret_aqui'

client = Client(API_KEY, API_SECRET)

symbols = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT']

print("Iniciando monitoreo de precios...")
for _ in range(5):  # Ejecutar 5 iteraciones como ejemplo
    for symbol in symbols:
        try:
            ticker = client.get_symbol_ticker(symbol=symbol)
            price = float(ticker['price'])
            print(f"{symbol}: ${price:.2f}")
        except BinanceAPIException as e:
            print(f"Error obteniendo {symbol}: {e}")
    time.sleep(2)  # Esperar 2 segundos entre consultas

Versión mejorada con manejo profesional:

from binance.client import Client
from binance.exceptions import BinanceAPIException, BinanceRequestException
import pandas as pd
import time
from datetime import datetime
import json

class CryptoPriceMonitor:
    def __init__(self, api_key, api_secret):
        self.client = Client(api_key, api_secret)
        self.price_history = {}
        
    def fetch_prices(self, symbols):
        """Obtiene precios actuales para múltiples símbolos"""
        prices = {}
        timestamp = datetime.now()
        
        for symbol in symbols:
            try:
                ticker = self.client.get_symbol_ticker(symbol=symbol)
                price = float(ticker['price'])
                prices[symbol] = {
                    'price': price,
                    'timestamp': timestamp
                }
                
                # Almacenar en historial
                if symbol not in self.price_history:
                    self.price_history[symbol] = []
                self.price_history[symbol].append({
                    'timestamp': timestamp,
                    'price': price
                })
                
            except (BinanceAPIException, BinanceRequestException) as e:
                print(f"Error con {symbol}: {e.status_code} - {e.message}")
                prices[symbol] = None
                
        return prices
    
    def monitor(self, symbols, interval=2, duration=60):
        """Monitorea precios por un período específico"""
        start_time = time.time()
        
        while time.time() - start_time < duration:
            prices = self.fetch_prices(symbols)
            
            # Mostrar resultados formateados
            print(f"\n--- {datetime.now().strftime('%H:%M:%S')} ---")
            for symbol, data in prices.items():
                if data:
                    print(f"{symbol}: ${data['price']:.2f}")
            
            time.sleep(interval)
        
        return self.price_history

# Uso del monitor
if __name__ == "__main__":
    # En producción, cargar desde variables de entorno
    monitor = CryptoPriceMonitor('API_KEY', 'API_SECRET')
    
    symbols_to_monitor = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT']
    
    print(f"Monitoreando {len(symbols_to_monitor)} símbolos por 60 segundos...")
    history = monitor.monitor(symbols_to_monitor, interval=1, duration=60)
    
    # Convertir a DataFrame para análisis
    df = pd.DataFrame([
        {'symbol': sym, 'timestamp': entry['timestamp'], 'price': entry['price']}
        for sym, entries in history.items()
        for entry in entries
    ])
    
    print(f"\nDatos recolectados: {len(df)} registros")
    print(df.head())

Errores comunes

1. Hardcodear credenciales API: Nunca incluyas tus claves directamente en el código. Usa variables de entorno o archivos de configuración externos. Solución: import os; API_KEY = os.getenv('BINANCE_API_KEY')

2. No manejar límites de rate limiting: Binance tiene límites estrictos de solicitudes por minuto. Excederlos resulta en baneo temporal. Solución: Implementar delays entre requests y usar WebSockets para datos en tiempo real.

3. Ignorar el manejo de excepciones: Las conexiones de red fallan, las APIs cambian. Sin try-except, tu script crasheará ante el primer problema. Solución: Capturar específicamente BinanceAPIException y BinanceRequestException.

4. Consultar símbolos inexistentes: Intentar obtener precios de pares que no existen devuelve errores. Solución: Validar símbolos con client.get_exchange_info() antes de monitorear.

5. No validar precios recibidos: A veces la API devuelve valores nulos o erróneos. Solución: Verificar que el precio sea un número positivo y dentro de rangos razonables antes de procesarlo.

Checklist de dominio

  • ✓ Configurar conexión a Binance API usando python-binance sin errores de autenticación
  • ✓ Implementar monitoreo simultáneo de al menos 5 pares de trading diferentes
  • ✓ Manejar correctamente excepciones de red y límites de API
  • ✓ Almacenar datos históricos en estructura adecuada para análisis posterior
  • ✓ Calcular métricas básicas como spread y volatilidad en tiempo real
  • ✓ Implementar sistema de logging para diagnóstico de problemas
  • ✓ Optimizar consultas para minimizar latencia y uso de recursos

Implementa un monitor de precios con alertas y análisis básico

Objetivo: Extiende el script de monitoreo para incluir alertas de precio y análisis en tiempo real.

  1. Configura el entorno: Crea un nuevo script Python basado en el ejemplo proporcionado. Asegúrate de tener instaladas las bibliotecas necesarias.
  2. Implementa alertas de precio: Añade funcionalidad para que el script emita alertas cuando:
    • Un activo supera un precio máximo configurable
    • Un activo cae por debajo de un precio mínimo configurable
    • La variación de precio en un período (ej: 1 minuto) excede un porcentaje determinado
  3. Añade análisis básico: Calcula y muestra en tiempo real:
    • Spread entre bid y ask para cada símbolo
    • Volatilidad (desviación estándar) de los últimos 10 precios
    • Cambio porcentual desde el inicio del monitoreo
  4. Mejora la salida: En lugar de solo imprimir en consola, guarda los datos en un archivo CSV con timestamp y crea un sistema de logging profesional.
  5. Optimiza el rendimiento: Implementa consultas por lotes usando client.get_symbol_ticker() para múltiples símbolos en una sola llamada a la API.

Entrega esperada: Script Python funcional que cumpla todos los requisitos, más un breve informe explicando tus decisiones de diseño.

Pistas
  • Usa el método get_symbol_ticker() sin parámetro de símbolo para obtener todos los tickers disponibles y filtra los que necesitas
  • Implementa las alertas como una clase separada que pueda ser reutilizada en otros proyectos
  • Para el cálculo de volatilidad, mantén una cola de los últimos N precios usando collections.deque

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.