Bot de trading de cripto con IA: de testnet a VPS

Crea un bot de trading de cripto con IA: Python y ccxt, testnet, backtesting, claves de API solo para operar, registros, VPS y alertas de Telegram, con avisos de riesgo.

Solviera Teknoloji 9 min de lectura

Crear un bot de trading de cripto con IA es realmente fácil hoy: un agente de código como Claude Code o Codex puede escribir un bot en Python que se conecte a un exchange mediante ccxt, ejecute una estrategia simple y coloque órdenes. El trabajo de verdad es todo lo que rodea al código: probar en un testnet y con backtests, limitar la clave de API solo a operar y pasar a dinero real con cantidades diminutas.

Esta guía va paso a paso desde una carpeta vacía hasta un bot que funciona 24/7 en un servidor y te envía alertas por Telegram. Antes, sin embargo, la parte sobre la que tengo que ser franco.

Primero el riesgo: esto no es asesoramiento financiero

Esto es un tutorial de software, no asesoramiento de inversión. Unos cuantos hechos de entrada:

  • La mayoría de los bots de trading pierden dinero. Sobre todo las estrategias simples que encuentras en internet, una vez que cuentas comisiones, deslizamiento y movimientos bruscos.
  • Una estrategia que luce genial en un backtest suele fallar en real. Las estrategias ajustadas a datos pasados (sobreajuste) se desmoronan enseguida.
  • El código escrito por IA puede contener errores costosos. Una unidad de cantidad equivocada, una condición de compra/venta invertida o un bucle de reintentos que sigue colocando órdenes pueden vaciar una cuenta en minutos.
  • Dale a un bot solo dinero que puedas permitirte perder. Empieza en testnet y luego pasa a real con la cantidad mínima que permita el exchange.

La estrategia de este artículo es un ejemplo de código. No la presento como una forma de ganar dinero.

Qué stack elegir

Cuando haces vibe coding de un bot, elige el stack que mejor conozca el agente. Mi elección:

  • Python 3.11+: el ecosistema más maduro para datos (pandas), backtesting y bibliotecas de exchanges, y el lenguaje del que los agentes han visto más ejemplos.
  • ccxt: una biblioteca de código abierto que habla con muchos exchanges mediante una sola interfaz. El código escrito para un exchange suele pasar a otro cambiando unas pocas líneas, y admite el modo testnet/sandbox de muchos exchanges.
  • pandas: para trabajar con los datos de velas (OHLCV) como una tabla.
  • python-dotenv: para guardar las claves de API en un archivo .env, fuera del código.
  • SQLite: para registrar posiciones abiertas y órdenes sin ejecutar un servidor de base de datos.

Configuración:

mkdir crypto-bot && cd crypto-bot
git init
python3 -m venv .venv && source .venv/bin/activate
pip install ccxt pandas python-dotenv requests
echo ".env" >> .gitignore
echo ".venv/" >> .gitignore

Añade esas líneas a .gitignore en el primer minuto. Subir por accidente una clave de API a GitHub es el error más común y más caro de todo este ámbito.

Paso 1: una cuenta de testnet y una clave de API con los permisos justos

Muchos exchanges grandes ofrecen un entorno de pruebas (testnet o sandbox) donde no se mueve dinero real. Busca «testnet» o «sandbox» en la documentación para desarrolladores del exchange y crea allí una cuenta de pruebas y una clave de API de pruebas independientes. Si no hay testnet, o tu par no está en él, haremos que el agente construya un modo de paper trading que lea precios reales pero solo registre las órdenes en local.

Cuando por fin crees una clave en la cuenta real:

  • Activa solo lectura y operar. Nunca actives las retiradas. Si la clave se filtra, nadie podrá enviar tus fondos a otro sitio.
  • Usa la lista blanca de IP. Si el exchange lo permite, ata la clave a la IP estática de tu VPS.
  • Mantén desactivados los futuros y el margen. Empieza con spot.
  • Crea una clave por bot, para poder revocar solo esa si algo sale mal.

Un archivo .env se ve así:

EXCHANGE=binance
API_KEY=your-test-key
API_SECRET=your-test-secret
USE_TESTNET=true
TELEGRAM_TOKEN=
TELEGRAM_CHAT_ID=

No pegues estos valores en el chat con el agente. El agente necesita saber que .env existe, no lo que contiene.

Paso 2: el primer prompt

Abre el agente en la carpeta del proyecto (claude o codex) y pide el bot por capas, no todo de una vez. Un primer prompt que puedes copiar:

Set up a skeleton for a simple spot trading bot in Python 3.11 with ccxt.
Rules:
- Read settings from .env with python-dotenv. Never open or print .env.
- If USE_TESTNET=true, enable ccxt sandbox mode; otherwise print a
  "LIVE MODE" warning on start and wait 10 seconds.
- Modules: config.py, exchange.py (connection, balance, candles, orders),
  strategy.py (returns a signal, never places orders), risk.py (position
  size, daily loss limit), bot.py (main loop), storage.py (SQLite log).
- Every order must pass risk.py first. Max 2% of balance per order;
  stop the bot if the daily loss exceeds 5%.
- With DRY_RUN=true, never place orders, only log them.
- Use Python logging to logs/bot.log and the console.
- No strategy yet: strategy.py should always return "hold".
When done, summarize the file layout and how to run it.

¿Por qué primero un esqueleto? Mantener la estrategia, la colocación de órdenes y las reglas de riesgo en archivos separados hace que el código sea más fácil de revisar y que los errores se detecten mejor. Si la estrategia no puede colocar órdenes, un error ahí produce, como mucho, una señal equivocada, y la capa de riesgo limita el daño.

Paso 3: una estrategia de ejemplo (cruce de medias móviles)

De nuevo: esto es un ejemplo, no un consejo. Un cruce de medias móviles es una de las estrategias más claras para mostrar la estructura. Cuando la media rápida cruza por encima de la lenta emite «comprar»; cuando cruza por debajo, «vender».

# strategy.py — example only, not financial advice
import pandas as pd

def signal(ohlcv: list, fast: int = 20, slow: int = 50) -> str:
    df = pd.DataFrame(ohlcv, columns=["ts", "open", "high", "low", "close", "volume"])
    if len(df) < slow + 2:
        return "hold"
    df["fast"] = df["close"].rolling(fast).mean()
    df["slow"] = df["close"].rolling(slow).mean()
    prev, last = df.iloc[-3], df.iloc[-2]  # the last candle is still open, skip it
    if prev.fast <= prev.slow and last.fast > last.slow:
        return "buy"
    if prev.fast >= prev.slow and last.fast < last.slow:
        return "sell"
    return "hold"

Un detalle que conviene notar: la señal se calcula a partir de la última vela cerrada, porque la más reciente aún se mueve. Los agentes lo pasan por alto a menudo y el bot acaba entrando y saliendo dentro de una misma vela.

Prompt para añadirla:

Add a 20/50 moving average crossover to strategy.py. Compute signals from
closed candles only. Write pytest tests for the signal function: cross up,
cross down, not enough data and a flat market. Run the tests and show me
the output.

Paso 4: backtesting

Antes de pasar a real, ejecuta la estrategia con datos históricos. Puedes hacer que el agente obtenga velas con ccxt y escriba un bucle de backtest sencillo. Para algo más serio, mira backtesting.py, vectorbt o Freqtrade; Freqtrade es un framework de bots de código abierto maduro que ya incluye backtesting, dry-run y control por Telegram.

Un prompt:

Write backtest.py. Fetch the last year of BTC/USDT 1h candles with ccxt,
paginating, and save them as CSV under data/. Apply strategy.signal candle
by candle without looking ahead. Deduct 0.1% fee and 0.05% slippage per
trade. Report total return, number of trades, win rate, max drawdown and
buy-and-hold return over the same period.

Al leer los resultados:

  • Incluye siempre comisiones y deslizamiento. Sin ellos casi cualquier estrategia parece buena.
  • Compara con comprar y mantener. Si el bot rinde menos que simplemente mantener, no merece el esfuerzo.
  • Comprueba tú mismo el sesgo de anticipación. Lee el bucle y asegúrate de que nunca usa datos que aún no existían.
  • No retoques los parámetros hasta que la curva quede bonita. Si 17/43 supera a 20/50, lo más probable es que sea casualidad.

Paso 5: testnet y paper trading

Tras el backtest, ejecuta el bot en testnet durante al menos unos días:

DRY_RUN=false USE_TESTNET=true python bot.py

En esta fase compruebas el comportamiento, no el beneficio. ¿Salen las órdenes con la cantidad correcta? ¿Recuerda el bot una posición abierta tras un reinicio? Cuando el exchange devuelve un error, ¿se bloquea o espera y reintenta? ¿Entra de verdad en acción el límite de pérdida diaria?

Provoca un fallo a propósito, por ejemplo una orden mayor que tu saldo, y observa cómo el bot lo registra con limpieza y se detiene.

Paso 6: límites de frecuencia, gestión de errores y registros

Los exchanges limitan las peticiones a la API. Un bot que los supera recibe errores primero y puede quedar bloqueado temporalmente si insiste. La opción enableRateLimit de ccxt espacia las peticiones automáticamente; haz que el agente confirme que está activada.

Review exchange.py:
- Make sure ccxt enableRateLimit is on.
- On NetworkError and RateLimitExceeded, retry up to 5 times with
  increasing backoff. On InsufficientFunds and InvalidOrder, do not retry;
  log it and send a Telegram alert.
- Log the request, exchange response and order id for every order.
- Prevent a second order for the same signal (idempotency).

Una buena línea de registro responde después a «¿por qué hizo eso el bot?»: hora, señal, precio, cantidad calculada, resultado de la comprobación de riesgo, id de la orden. Nunca registres claves de API ni secretos.

Paso 7: alertas de Telegram

El bot debería contarte lo que hace. La forma más simple es una llamada HTTP normal a la API de bots de Telegram:

# notify.py
import os, requests

def send(text: str) -> None:
    token, chat = os.getenv("TELEGRAM_TOKEN"), os.getenv("TELEGRAM_CHAT_ID")
    if not token or not chat:
        return
    try:
        requests.post(f"https://api.telegram.org/bot{token}/sendMessage",
                      json={"chat_id": chat, "text": text}, timeout=10)
    except requests.RequestException:
        pass  # a failed alert must not stop the bot

El token lo obtienes con el flujo oficial de creación de bots de Telegram. Eventos que merecen una alerta: bot iniciado/detenido, orden colocada, error, límite de pérdida diaria alcanzado. Mi guía para crear un bot de Telegram con IA explica cómo añadir comandos, como detener el bot de forma remota.

Paso 8: ejecutar 24/7 en un VPS

Cuando tu portátil se suspende, el bot también. Basta un VPS Linux pequeño; una IP estática importa para la lista blanca de IP.

Con systemd

# /etc/systemd/system/crypto-bot.service
[Unit]
Description=Crypto bot
After=network-online.target

[Service]
User=bot
WorkingDirectory=/home/bot/crypto-bot
EnvironmentFile=/home/bot/crypto-bot/.env
ExecStart=/home/bot/crypto-bot/.venv/bin/python bot.py
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now crypto-bot
journalctl -u crypto-bot -f

Ejecuta el bot con su propio usuario, no con root, y protege el archivo de entorno con chmod 600 .env.

Con Docker

Si prefieres Docker, haz que el agente escriba un Dockerfile y un docker-compose.yml con restart: unless-stopped, env_file para .env y volúmenes para logs/ y el archivo SQLite, de modo que el bot y sus registros sobrevivan a un reinicio del servidor.

Errores comunes: lo que la IA suele hacer mal

  • Cantidades y precisión. Los exchanges imponen una cantidad mínima y una precisión decimal por par. Los agentes lo omiten y obtienen órdenes rechazadas, o redondean en el sentido equivocado. Haz que use amount_to_precision de ccxt y los límites del mercado.
  • Usar la vela abierta. Las señales de una vela que aún se mueve son ruido.
  • La marca de testnet activada en producción, o desactivada en las pruebas. Registra el modo de forma bien visible al arrancar.
  • Perder el estado al reiniciar. Si el bot olvida una posición abierta, puede comprar de nuevo. Guarda el estado en SQLite y concílialo con el exchange al arrancar.
  • Órdenes dentro de un bucle de reintentos. Si la lógica de reintento envuelve la colocación de la orden, la misma orden puede salir muchas veces.
  • Errores tragados. Un except: pass por todas partes da un bot que parece vivo y no hace nada.
  • Fiarse de «las pruebas pasaron». Mira tú mismo la salida.

Lista de comprobación de seguridad

  • Las claves de API viven solo en .env, y .env está en .gitignore.
  • Nunca pegues claves en el agente, en un chat ni en una captura de pantalla.
  • Retiradas desactivadas, lista blanca de IP activada, margen desactivado.
  • Lee los comandos que el agente quiere ejecutar antes de aprobarlos, sobre todo los que leen .env, suben archivos o hacen llamadas de red.
  • Si sospechas que una clave se filtró, revócala en el exchange de inmediato y crea una nueva.
  • Activa la autenticación en dos pasos en la cuenta del exchange.
  • Instala dependencias que reconozcas; revisa cualquier nombre de paquete que el agente sugiera y que nunca hayas oído.

Hacerlo con AgentVera

En proyectos como este ejecuto más de un agente en paralelo. En una cuadrícula de AgentVera puedes hacer que Claude Code trabaje en la estrategia y el backtest en un worktree mientras Codex construye las alertas de Telegram y los archivos de Docker en otro, sin tocar los archivos del otro. Tras cada turno, la revisión de código automática hace que un segundo modelo lea lo que escribió el agente, lo que sirve como un segundo par de ojos para las cuentas de cantidades y las condiciones de compra/venta. Revisas el diff en el panel de Git antes de fusionar y ves el uso de tokens por agente. Cuando el bot está listo, SSH y SFTP lleva los archivos al VPS y el gestor de Docker muestra el contenedor en local.

Nada de esto es obligatorio; dos terminales y git también sirven. Si te interesa la configuración en paralelo, consulta agentes de código en paralelo.

Para terminar

La parte de código de crear un bot de trading de cripto con IA son unas horas: Python, ccxt, módulos claramente separados, una capa de riesgo y buenos registros. Lo que lleva tiempo y de verdad importa son las pruebas: backtest, testnet, paper trading y solo después una cantidad real diminuta. Limita la clave de API a operar, desactiva las retiradas y lee cada línea de órdenes que escriba el agente. Y recuerda que la mayoría de los bots pierden dinero; construye este para aprender, no para hacerte rico.

Preguntas frecuentes

¿Puede la IA crear un bot de trading de cripto?

Sí. Un agente de código puede escribir en una tarde un bot en Python con ccxt que se conecte a un exchange, ejecute una estrategia y coloque órdenes. Lo difícil no es el código, sino saber si la estrategia gana dinero y si el código esconde un error costoso.

¿Qué permisos debe tener la clave de API de un bot de trading?

Solo lectura y operar; nunca actives las retiradas. Si el exchange lo permite, restringe la clave a la dirección IP del servidor donde se ejecuta el bot.

¿Cómo pruebo un bot de trading sin dinero real?

Primero haz un backtest con datos históricos y luego ejecútalo durante días en el testnet del exchange o en un modo de paper trading que solo registre las órdenes. Pasa a dinero real solo después, con una cantidad que puedas permitirte perder.

¿Ganan dinero los bots de trading de cripto?

La mayoría no. Las estrategias simples suelen perder tras las comisiones y el deslizamiento, y un backtest con buen aspecto dice poco sobre el futuro. Este artículo no es asesoramiento financiero.

¿Dónde debo ejecutar un bot de cripto 24/7?

Basta un VPS Linux pequeño. Ejecutar el bot como servicio de systemd o como contenedor Docker lo reinicia tras un fallo y mantiene sus registros en un solo lugar.

Reúne a tus agentes en un mismo escritorio.

Descarga AgentVera gratis; tus CLI instaladas ya están listas.

Más artículos