Runbook de incidentes
Cinco escenarios. Cada uno con cómo se detecta, qué hacer y cómo provocarlo a propósito para comprobar que el procedimiento funciona (meta: cada escenario probado una vez durante la observación). Todo lo manual se hace desde Telegram o desde la web de GitHub; no hace falta la PC.
1. El job no corre (GitHub Actions caído, cron retrasado o workflow en rojo)
- Detectar. No llega el resumen de las 16:15 ET ni el ciclo de las 9:35; en
https://github.com/keudhhdnfustedeyfbgbf-ctrl/trading-bot/actions la última fila es de ayer o
está en rojo. La página de métricas muestra la fiabilidad del mes. Si configuraste
HEALTHCHECK_URL, healthchecks.io avisa por correo. - Hacer. Abre la fila roja → paso en rojo → lee el error. Si es de claves (401), corrige el
secreto. Si es de GitHub (runner no disponible), Re-run all jobs. Si el cron simplemente se
retrasó (hasta 30 min en horas punta) no hay que hacer nada:
bot job autohace catch-up. Los stops viven en Alpaca: un job perdido no deja posiciones sin protección. - Probar. Deshabilita el workflow (Actions → Bot → ··· → Disable workflow) un día hábil entero, vuelve a habilitarlo al día siguiente y comprueba que el primer job hace el ciclo por catch-up y que la fiabilidad del mes baja un día.
2. Orden desconocida en Alpaca
- Detectar. El resumen diario dice "⚠️ N orden(es) desconocida(s)" o "solo en Alpaca: SYM".
- Hacer. Entra en la web de Alpaca (paper) → Orders. Si la orden la pusiste tú a mano,
cancélala o deja que se ejecute y anota
/nota orden manual SYM motivo. Si no la reconoces, cambia las claves de Alpaca inmediatamente (Paper trading → API keys → Regenerate), actualiza los secretos en GitHub y activa/killhasta entender el origen. - Probar. Pon una orden límite a mano en la web de Alpaca muy lejos del precio (no se ejecutará) y espera el resumen: debe aparecer como desconocida. Luego cancélala.
3. Alpaca caído o rechazando (401, 403, 5xx)
- Detectar. El paso "Job" falla con
HTTPError,401 Unauthorizedo503; Telegram recibe "🚨 Job … falló". - Hacer. 401/403 → claves mal o regeneradas: actualiza los secretos. 5xx o timeout → no hacer nada; el siguiente job vuelve a intentarlo y el sync reconcilia. Nunca reenvíes órdenes a mano: el bot no repite una orden del mismo día (id idempotente) y el bracket protege la posición.
- Probar. Cambia temporalmente
ALPACA_SECRET_KEYen los secretos por un valor falso, lanza Run workflow y comprueba el aviso; restaura la clave y vuelve a lanzar.
4. Kill switch activado por pérdida diaria
- Detectar. Telegram: "🛑 Kill switch activo" en el ciclo;
/statuslo muestra; en el panel aparece la píldora roja. - Hacer. Nada el mismo día: el kill diario caduca solo al día siguiente. Las salidas siguen
funcionando (stop, take-profit, cruce). Si quieres reanudar antes,
/resume. Anota en el journal qué pasó (/nota …). Si se activa dos veces en una semana, revisa los umbrales dedocs/STRATEGY.mdantes de tocar parámetros. - Probar. Envía
/kill, comprueba que el siguiente ciclo no compra y que/statuslo refleja; luego/resume.
5. Base de datos corrupta o rama state rota
- Detectar. El paso "Restaurar estado" o "Guardar estado" falla; el panel muestra datos
de hace días;
sqlite3.DatabaseErroren el registro. - Hacer. La BD tiene tres copias: la rama
state(commit por job),backups/en la ramastate(una por día, 14) y los snapshots de equity. Restaurar: en la ramastate, vuelve al commit anterior (History → commit → Browse files → descargatrading.db) o usabackups/trading-FECHA.db, súbelo comotrading.dba la ramastatey lanza Run workflow. El sync reconstruye el estado de las posiciones desde Alpaca; se pierden como mucho las notas del journal posteriores a la copia. - Probar. Descarga
trading.dbde la ramastate, guárdalo aparte, y sube en su lugar un archivo vacío llamadotrading.db. Lanza Run workflow: debe fallar en "Restaurar estado" o en el job. Restaura el archivo guardado y vuelve a lanzar: verde.
Rutina diaria (3 minutos)
- Leer el resumen de las 16:15 ET en Telegram: P&L, posiciones, línea de reconciliación.
- Si la reconciliación no dice "sin diferencias", ir al escenario 2.
- Si no llegó el resumen, ir al escenario 1.
- Anotar cualquier anomalía con
/nota. Meta: 20 días hábiles seguidos de rutina cumplida.
Fuente: docs/RUNBOOK.md · modificado hace 0 min. Se lee del disco en cada carga: git pull lo actualiza sin reiniciar.