Reiniciamos una estrategia de paper trading a mitad de una operación y obtuvimos una secuencia de órdenes distinta de la que había generado antes del reinicio. Los mismos datos de mercado, la misma versión de la estrategia y el mismo saldo de la cuenta. El cálculo de la señal coincidía. La memoria de la estrategia sobre su posición y las órdenes pendientes, no.
Seguimos el rastro de la discrepancia durante un día de reproducción. La lección útil era sencilla: para el software, un reinicio es un evento de mercado. Si no pruebas cómo reconstruye la estrategia su estado, un backtest limpio puede ocultar un sistema de paper trading que olvida lo que tiene.
09:10 — Elegimos una posición sencilla
La estrategia de prueba operaba un contrato perpetuo líquido: abría una posición larga cuando una media móvil corta cruzaba por encima de una más larga y la cerraba con el cruce inverso. Iniciamos la reproducción con una posición pequeña ya abierta y una orden límite reduce-only pendiente para reducirla. Así, la recuperación tenía que reconstruir dos datos: qué teníamos y qué ya habíamos pedido al mercado que hiciera.
En el punto de control, la cuenta tenía 0.04 contratos. La orden abierta era por 0.01. El proceso de la estrategia había guardado ambos valores en memoria, pero al iniciarse solo consultaba la posición. Dio por hecho que la orden guardada ya no existía.
09:25 — Apareció la primera orden duplicada
Al reiniciarse, la estrategia detectó la posición larga existente, ejecutó la lógica de señales y envió otra orden de reducción por 0.01. Ahora, el mercado de paper trading tenía dos órdenes activas. Ninguna era incorrecta por sí sola. Juntas, podían vender el doble de la cantidad prevista si ambas se ejecutaban.
Al principio culpamos al ciclo de señales. El problema no era el ciclo, sino que la instantánea estaba incompleta. La estrategia preguntó: «¿Qué posición tengo?», pero nunca preguntó: «¿Qué órdenes siguen activas?».
| Estado tras el reinicio | Lo que creía el proceso | Lo que tenía la cuenta |
|---|---|---|
| Posición | Larga de 0.04 | Larga de 0.04 |
| Órdenes de reducción abiertas | Ninguna | Dos de 0.01 cada una |
| Exposición prevista tras una ejecución | Larga de 0.03 | Podría quedar larga de 0.02 |
10:00 — Corregimos la recuperación y encontramos un problema de sincronización
Cambiamos el inicio para reconstruir el estado a partir de las posiciones y las órdenes abiertas de la cuenta antes de permitir nuevas decisiones. Así eliminamos el duplicado. Luego complicamos la desconexión: una orden se ejecutó mientras la estrategia estaba fuera de línea y la notificación de ejecución llegó después de la reconexión.
La instantánea de la cuenta ya reflejaba la ejecución. Cuando llegó la notificación retrasada, volvió a reducir la posición local. Durante unos segundos, la estrategia creyó que tenía 0.02 contratos cuando la cuenta tenía 0.03. El siguiente rebalanceo se basó en una falta ficticia.
Añadimos reglas de conciliación: tomar la instantánea de la cuenta como punto de partida, usar identificadores de evento para ignorar las ejecuciones que ya estuvieran reflejadas allí y no enviar órdenes hasta terminar la sincronización inicial. Una notificación puede llegar tarde o dos veces. La recuperación debe tolerar ambas cosas.
13:40 — La reproducción detectó una discrepancia sutil
Reprodujimos la misma trayectoria de precios en la ejecución original y en la reiniciada. Comparar el P&L final no habría revelado el problema: ambas versiones terminaron con la misma posición después de que el mercado se diera la vuelta. La comparación de los eventos de órdenes sí lo dejó al descubierto.
Registramos cada decisión junto con el estado que consultaba: posición, órdenes abiertas, último identificador de ejecución procesado, valor de la señal y versión de la estrategia. Así pudimos explicar el primer evento divergente. Una ejecución veía una orden activa; la otra veía una lista vacía. Más tarde, una de ellas aplicó dos veces una ejecución.
Que el saldo final coincida no demuestra que el comportamiento haya sido el mismo. Compara la secuencia de decisiones y órdenes, sobre todo en torno a los momentos de recuperación.
16:20 — Qué haríamos distinto la próxima vez
Dedicamos demasiado tiempo a reproducir los datos de precios antes de revisar las transiciones de estado de la cuenta. La próxima vez, introduciríamos primero los casos de fallo y mantendríamos casi plana la trayectoria del mercado. Así, el error del software se ve con claridad, sin que un movimiento volátil enturbie el diagnóstico.
- Reinicia con una posición y una orden ejecutada parcialmente.
- Desconecta después de enviar la orden y reconecta antes de que llegue la notificación de ejecución.
- Entrega dos veces el mismo evento de ejecución y comprueba que solo cambie el estado una vez.
- Bloquea las órdenes nuevas hasta conciliar las posiciones y las órdenes abiertas.
- Compara los registros de decisiones y órdenes entre las ejecuciones ininterrumpidas y las reiniciadas.
También aprendimos a guardar una instantánea de recuperación junto con la versión de la estrategia y el registro de eventos. Así pudimos reproducir el fallo en minutos, sin depender de que alguien recordara la secuencia exacta de reconexión.
Una estrategia de paper trading que solo funciona correctamente mientras su proceso sigue activo no ha superado un ensayo completo. Reiníciala en mitad de una posición, haz que las ejecuciones lleguen tarde y revisa cada orden que envíe después. El objetivo no es demostrar que nunca falla, sino hacer visible su recuperación antes de que la cuenta de paper trading tenga que darte esa misma lección por sorpresa.
← Todos los artículos


