VPS para bots de trading: lo que importa
Aprende qué necesita realmente un bot: reinicio con systemd, reloj correcto, claves API seguras, heartbeats y límites reales de latencia.
Qué necesita un bot de trading de un VPS
Un VPS para bots de trading se evalúa según cuatro aspectos: si el proceso vuelve a ejecutarse después de detenerse, si el reloj es correcto, si es difícil robar las claves de las API (interfaces de programación de aplicaciones) y si recibe una notificación cuando se detiene. La velocidad bruta ocupa un lugar muy inferior en esa lista para un bot minorista, porque la parte lenta de la ruta de la orden depende del bróker y de la distancia hasta este, no del host que ejecuta Python.
Esta es una guía de ingeniería. Nada de lo indicado aquí constituye asesoramiento financiero y no se analiza ninguna estrategia.
La disponibilidad depende de una disciplina de reinicio, no de una cifra en una página comercial
Los compromisos de disponibilidad anunciados varían. AWS especifica al menos un 99.5 por ciento para una instancia EC2 individual y un 99.99 por ciento para implementaciones aptas distribuidas entre varias zonas de disponibilidad. Estos compromisos cubren la disponibilidad de la infraestructura, no el estado de su bot. Un bot puede detenerse por una excepción no controlada, una conexión websocket que nunca se restablece o el OOM (out of memory) killer, mientras el servidor permanece operativo todo el tiempo. Por tanto, la pregunta útil es qué ocurre durante los diez segundos posteriores a la salida del proceso.
Ejecute el bot como un servicio de systemd y deje que el sistema init gestione el reinicio. Un archivo de unidad permite hacerlo.
[Unit]
Description=Trading bot
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=bot
WorkingDirectory=/opt/tradingbot
EnvironmentFile=/etc/tradingbot/api.env
ExecStart=/opt/tradingbot/venv/bin/python -m tradingbot
Restart=always
RestartSec=10
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/tradingbot
[Install]
WantedBy=multi-user.targetStartLimitIntervalSec=0 es la línea que muchas personas pasan por alto. De forma predeterminada, systemd permite 5 arranques en 10 segundos, incluido el arranque inicial y los arranques manuales; la configuración del gestor puede cambiar estos valores predeterminados. Al alcanzar el límite, se detienen los intentos de reinicio automático, pero la unidad se puede iniciar manualmente o mediante un temporizador o socket cuando transcurre el intervalo. Establecerlo en 0 desactiva el límite de frecuencia, de modo que un bot que entra en un ciclo de fallos sigue intentándolo en lugar de quedar detenido. RestartSec=10 evita que ese ciclo sobrecargue el exchange con reconexiones.
Compruebe el archivo antes de confiar en él y, después, inícielo:
sudo systemd-analyze verify /etc/systemd/system/tradingbot.service
sudo systemctl daemon-reload
sudo systemctl enable --now tradingbot
systemctl status tradingbotenable es la parte que permanece tras un reinicio, y las actualizaciones del kernel implican reinicios. Para comprobar si el bot se ha estado deteniendo silenciosamente, pida a systemd el contador de reinicios:
systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50NRestarts=0 cuenta los trabajos de reinicio automático desde el último restablecimiento del contador; no demuestra que la semana haya transcurrido sin fallos ni que el servicio esté operativo. Los reinicios manuales y systemctl reset-failed restablecen el contador, y un bot bloqueado todavía puede mostrar cero. NRestarts=812 cuenta 812 trabajos de reinicio, no reconexiones correctas al exchange ni operaciones, y no indica cuándo ocurrieron. Revise el journal para conocer el momento y la causa, incluidos los fallos anteriores a la conexión del bot. La anatomía completa del archivo de unidad, incluidos los temporizadores para trabajos programados como un informe diario, se explica en ejecutar un programa como servicio de systemd.
Configurar el reloj en UTC y demostrar que está sincronizado
Las API de intercambio usan marcas de tiempo para validar las solicitudes firmadas. Binance Spot usa de forma predeterminada una ventana de recepción de 5 segundos y rechaza las marcas de tiempo que están al menos 1 segundo adelantadas respecto a la hora del servidor. Un reloj desincronizado produce errores que parecen fallos de autenticación, por lo que algunas personas rotan las claves durante horas antes de comprobar la hora. En las API de estilo Binance, el mensaje es literal: Timestamp for this request was 1000ms ahead of the server's time.
Configure el servidor para usar UTC. Las zonas horarias locales introducen cambios por el horario de verano en las horas mostradas. Las marcas de tiempo Unix que usan las API no cambian cuando cambia la zona horaria de visualización.
sudo timedatectl set-timezone UTC
timedatectlUbuntu usa chrony de forma predeterminada a partir de la versión 25.10. Las instalaciones anteriores pueden usar systemd-timesyncd, un cliente SNTP (simple network time protocol). systemd-timesyncd ajusta el reloj, pero no puede consultar varios servidores a la vez para detectar una fuente de hora incorrecta. Use chrony en su lugar:
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
chronyc tracking
chronyc sources -vLa línea que debe leer de chronyc tracking es System time, por ejemplo System time : 0.000031415 seconds fast of NTP time. Un valor pequeño indica que queda un ajuste pequeño en el reloj NTP de chrony. Antes de evaluar la precisión, compruebe también la sincronización, Root delay y Root dispersion. Si muestra Leap status : Not synchronised, chrony no está sincronizado, aunque los servidores hayan respondido. Las mediciones pueden rechazarse por ser demasiado imprecisas. Espere un minuto y vuelva a comprobarlo antes de modificar las reglas del firewall.
Mantenga las claves de API fuera de los lugares que copia
Una clave de exchange filtrada es peor que una clave SSH filtrada, porque el permiso de retirada convierte el acceso en dinero de forma inmediata. Dos hábitos cubren la mayor parte del riesgo.
Primero, no conceda nunca permisos de retirada a la clave de un bot. Cuando el exchange lo permita, vincule la clave a la dirección IP del servidor. Este es el único control que hace que una clave robada resulte casi inútil.
Segundo, mantenga el secreto fuera del directorio del código. Todo lo que esté dentro de /opt/tradingbot termina tarde o temprano en un repositorio git o en un archivo de copia de seguridad. Guárdelo en un archivo propiedad de root que systemd lea:
sudo install -d -m 750 -o root -g bot /etc/tradingbot
sudo install -m 640 -o root -g bot /dev/null /etc/tradingbot/api.env
sudo nano /etc/tradingbot/api.envEl archivo contiene líneas simples de KEY=value, sin comillas ni export. El modo 640 proporciona al propietario root permisos de lectura y escritura, y a los miembros del grupo bot permisos de lectura. Los demás usuarios no tienen permisos. Verifíquelo con sudo -u bot cat /etc/tradingbot/api.env y después con un usuario sin privilegios que no pertenezca al grupo bot. En ese caso, debe fallar con Permission denied.
El bot no debe ejecutarse como root ni como su usuario de inicio de sesión. Cree una cuenta de sistema con un shell nologin y /var/lib/tradingbot como directorio principal antes de iniciar el servicio o crear archivos propiedad del grupo bot:
sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home botLa explicación de cada una de esas opciones y del alcance real de ProtectSystem=strict se encuentra en ejecutar servicios con un usuario sin privilegios. El resto de la configuración básica del servidor, las claves SSH y un firewall, debe incluirse en los primeros diez minutos en un VPS nuevo.
Comprueba que está caído antes de que lo detecte tu bróker
systemctl status indica que el proceso está en ejecución. No indica que el bot esté haciendo algo. Un proceso atascado en un bucle de reintentos contra un websocket caído supera las comprobaciones del proceso de la unidad anterior.
Usa un heartbeat. Uptime Kuma admite monitores push: espera que el bot llame a una URL con una periodicidad determinada y genera una alerta cuando dejan de llegar las llamadas. Coloca la llamada al final del bucle principal, después de la parte que demuestra que el bot está activo, como una lectura correcta de datos de mercado.
curl -fsS "http://monitor.example.com:3001/api/push/YOUR_TOKEN?status=up&msg=loop_ok"Configura el intervalo del monitor aproximadamente al doble del tiempo del bucle para que las variaciones normales no generen alertas. Ejecuta el monitor en un servidor distinto del bot, porque un monitor que muere junto con el elemento que supervisa no informa de nada. La configuración se explica en supervisión de estado autoalojada con Uptime Kuma.
Añade también una alerta de disco. Un bot que escribe registros detallados llenará el sistema de archivos raíz en pocas semanas, y un disco lleno impide escribir en la base de datos, no realizar la llamada de red, por lo que los síntomas resultan extraños. journalctl --vacuum-time=14d y una línea SystemMaxUse= en /etc/systemd/journald.conf mantienen acotado el journal.
La parte honesta: la latencia depende sobre todo de factores ajenos a tu host
Aquí es donde el mercado de los productos VPS para trading deja de ser técnico. Las páginas de marketing publican cifras inferiores a un milisegundo e insinúan que el host es lo que se interpone entre tú y una ejecución. Para casi cualquier bot minorista, no es así.
La orden viaja desde el bot hasta el endpoint del exchange o del bróker a través de Internet pública. Ese recorrido está determinado sobre todo por la distancia física y por el peering entre tu proveedor y el suyo. Después, los propios sistemas del bróker añaden su cola, sus comprobaciones de riesgo y sus límites de tasa.
Mídelo en lugar de hacer suposiciones. curl informa de los tiempos de conexión y del primer byte para un endpoint real:
curl -s -o /dev/null -w 'dns=%{time_namelookup}s connect=%{time_connect}s ttfb=%{time_starttransfer}s\n' \
https://api.kraken.com/0/public/Time
mtr -rwzc 100 api.kraken.comEjecuta esto desde un servidor candidato antes de contratarlo. Si connect es 0.180 segundos, incluye la resolución DNS y la conexión TCP; no permite determinar en qué continente te encuentras. Si connect es 0.004 segundos y ttfb es 0.140 segundos, la diferencia incluye la configuración de TLS, la transmisión de la petición, los retrasos de red y el procesamiento del servidor. Un cambio de host puede afectar a algunos de esos componentes, así que compara las mediciones de las ubicaciones candidatas.
Entonces, ¿cuándo importa el host? Cuando estás en colocación o conectado mediante una conexión cruzada al mercado y compites por la posición en la cola. Es un negocio diferente, con un presupuesto diferente. También importa cuando el cuello de botella está en tu propio código: un bot que recalcula indicadores sobre todo el historial en cada tick puede consumir 200 milisegundos de CPU por bucle. Esa es latencia real que puedes controlar sin coste. Perfila el bucle antes de buscar un servidor más rápido.
Lo que sí importa del host que elijas es la ubicación geográfica, una red estable y memoria suficiente para que el OOM killer nunca tenga ocasión de intervenir. Añade memoria si conservas el historial de ticks en una base de datos local.
Una lista de comprobación breve antes de pasar a producción
systemctl is-enabled tradingbotmuestraenabledy el servicio sigue activo después desudo reboot.chronyc trackinginforma de que la sincronización está activa, de una diferencia de hora del sistema inferior a unos pocos milisegundos y de que el retardo y la dispersión de root están dentro del margen previsto para la sincronización.- La clave de API tiene permiso para operar, no tiene permiso de retirada de fondos y usa una lista de IP permitidas si el exchange ofrece esa opción.
- Al finalizar el proceso con
sudo systemctl kill -s SIGKILL tradingbot, vuelve a iniciarse después del retraso deRestartSecy del tiempo de arranque. - El monitor de heartbeat envía una alerta después del intervalo configurado y vuelve a intentarlo cuando detienes el bot de forma deliberada.
- Los registros tienen límites y el sistema de archivos raíz dispone de espacio suficiente en
df -h.
Ejecuta todo en el sandbox del exchange o en modo de operaciones simuladas durante una semana antes de usar fondos reales. Cada elemento anterior falla al menos una vez durante esa semana. Ese es precisamente el objetivo de la semana.
FAQ
¿Un bot de trading necesita un servidor de baja latencia o un servidor bare metal?
Sólo si compite por la velocidad de ejecución con otros participantes automatizados en el mismo mercado, lo que normalmente implica usar colocation en lugar de un VPS de propósito general. En un bot minorista, el tiempo de ida y vuelta depende sobre todo de la ubicación geográfica y del procesamiento del propio bróker. Por tanto, elija un servidor cercano al endpoint de la API y mida con curl y mtr antes de pagar por algo más rápido.
¿Cuánta RAM y CPU necesita un bot de trading?
La mayoría de los bots de una sola estrategia están limitados por la red y permanecen inactivos entre eventos. La memoria se convierte en el límite cuando mantiene el historial de ticks en el proceso o ejecuta una base de datos local. Por tanto, supervise free -h y el journal en busca de mensajes de OOM kill en lugar de hacer suposiciones.
¿Por qué la API de mi exchange rechaza las solicitudes con un error de timestamp?
La marca de tiempo de la solicitud está fuera de la ventana aceptada por el exchange. Tanto el desfase del reloj como los retrasos de las solicitudes influyen. Instale chrony y confirme que chronyc tracking muestra un desfase System time pequeño y un estado de salto sincronizado. Compruebe también el retraso raíz y la dispersión. Configurar la máquina con UTC mantiene coherentes las horas mostradas, pero no corrige el desfase del reloj. Cambiar la API key no soluciona un problema del reloj.
¿Cómo puedo evitar que mi bot se detenga durante la noche sin que yo lo sepa?
Ejecútelo con systemd usando Restart=always y StartLimitIntervalSec=0, de modo que un bucle de fallos siga reintentando en lugar de alcanzar el límite de frecuencia de arranque. Después, añada un heartbeat que el bot envíe al final de cada ciclo completado correctamente. El reinicio gestiona el proceso. El heartbeat detecta el caso en que el proceso sigue activo, pero está bloqueado.
¿Puedo ejecutar el bot y la monitorización en el mismo VPS?
Puede hacerlo, pero la monitorización le dará una falsa sensación de seguridad precisamente cuando más la necesite, porque una interrupción que detenga el bot también detendrá la monitorización. Mantenga las alertas en otra máquina, preferiblemente con otro proveedor o en otra región, y use el servidor del bot sólo para el bot y sus logs.