Pipeline cuantitativo end-to-end multi-modelo para validar estrategias algorítmicas con rigor institucional sobre crypto futuros: ingesta multi-fuente con validación de calidad en 3 capas → feature engineering + 9 subsistemas de confluence VETO/VOTE → ensemble multi-modelo (LSTM advanced + TCN + XGBoost + Reinforcement Learning con PPO) → agente de gobernanza con safety gates, kill-switches y reconciliation FSM. Diseñado con principios de grado institucional: audit trail completo, walk-forward con embargo y purge, idempotencia determinista, fail-safe defaults, observabilidad con 7 SLOs formales. Stack extensible a contextos multi-tenant / fondos de inversión.
Para founding / staff AI roles — pipeline cuantitativo end-to-end multi-modelo (LSTM advanced + TCN + XGBoost + PPO) con walk-forward + embargo + purge, ensemble con voting + meta-agent RL, 9 subsistemas de confluence VETO/VOTE, agente de gobernanza con safety gates y kill-switches, 40+ ADRs versionadas, 7 SLOs formales, audit trail completo, idempotencia determinista, fail-safe defaults. Stack extensible a contextos multi-tenant / fondos de inversión.
| STACK MULTI-MODELO LSTM advanced + TCN + XGBoost + PPO ensemble con voting + meta-agent RL |
METODOLOGÍA + DOCTRINA 40+ ADRs · 7 SLOs formales walk-forward + embargo/purge + ablation |
GOBERNANZA ARQUITECTÓNICA 12 safety gates testeados circuit breaker · feature gates · kill-switch · drawdown guard · reconciliation FSM |
Cualquier estrategia algorítmica de trading puede mostrar resultados favorables en un backtest aislado. La pregunta real es: ¿tiene edge estadísticamente significativo o es ruido?
La industria está llena de bots y modelos que muestran un Profit Factor favorable en un período concreto, se despliegan, y queman capital semanas después. Las causas suelen ser sistémicas y silenciosas. Futuros se construyó para bloquear cada una de ellas por diseño:
| Antipatrón sistémico de la industria | Patrón aplicado en Futuros |
|---|---|
| Target leakage en labels: rolling windows mal alineados que filtran información futura al training | Labels look-forward puras (rolling().shift(-N)) verificadas con tests de no-leakage |
| Train/test shuffle aleatorio sobre series temporales: contaminación cross-period | Split temporal estricto + walk-forward rolling con re-entreno mensual |
| Cross-validation sin embargo ni purge: feature autocorrelation se cuela entre folds | PurgedTimeSeriesSplit custom con embargo + purge explícitos |
| Subsystems "ensemble" tóxicos sin attribution analysis: componentes con lift cero o negativo se cuentan en el voto | Ablation analysis sistemático por subsystem; lift validado con bootstrap CI antes de aprobar la composición |
| Cost model fragmentado entre labeler y backtest engine; en estrategias de bajo edge esto invierte el signo del Profit Factor | Single Source of Truth para costes + test de parity (PnL labeler == PnL backtest) bloqueante |
| Race conditions en idempotencia de órdenes: retry sobre timeout duplica posición silenciosamente | clientOrderId determinista SHA-based; el exchange rechaza duplicados server-side |
| State drift local ↔ exchange: bot reinicia con estado parcial, opera sobre posiciones fantasma | Reconciliation FSM al startup con 4 acciones explícitas (report / adopt / cancel orphans / abort) |
| Fail-open en flags de seguridad: ausencia de configuración interpretada como permiso para live trading | DRY_RUN unset → True (fail-safe). Defense-in-depth con 3 capas, todas fail-safe |
Sin un framework que bloquee sistemáticamente estos antipatrones, cualquier número favorable en backtest es ruido sin valor.
Futuros es el framework. Su propósito real no es generar señales rentables — es determinar si una estrategia algorítmica tiene edge real antes de poner capital.
El pipeline aplica disciplina de ingeniería seria al trading sistemático en seis fases:
- Ingesta multi-fuente con cache + validación: ingest multi-modo (boost, live, parallel, prefetch) sobre CCXT (KuCoin Futures como validation venue, Binance como smoke test).
- Depuración + clasificación de calidad: 3 capas de validación (feed integrity + OHLCV validator + quality scoring) + winsorización con tests específicos de quality, validación y winsorizer.
- Algoritmos financieros + feature engineering: 9 subsistemas de confluence en patrón VETO/VOTE (3 vetos: volatility, liquidations, funding; 6 votos: trend, momentum, volume, structure, orderflow, regime) + indicadores TA estándar (EMA, RSI, ATR, Bollinger, MACD, Stochastic) con extracción strict no-lookahead.
- Deep learning + ensemble + reinforcement learning: modelos LSTM advanced + TCN (Temporal Convolutional Network) + XGBoost wrappers + ensemble con voting + meta-agent RL (PPO via
stable_baselines3) con dos versiones (v1 + v2.2 Ex-Ante Control). - Agente de gobernanza con gates múltiples: decision layer + agent + core + alerts + 12 safety gates testeados (circuit breaker, feature gates, ML live gate, ML gate fallback, safe mode, drawdown guard, no over-leverage, single position enforcement, fallback when no model, legacy decision, paper strategy, costs policy) + reconciliation FSM al startup.
- Validación rigurosa pre-deployment: walk-forward rolling con embargo + purge, Lockbox gates con bootstrap CI, ablation analysis por subsystem (attribution lift vs random), cost model parity entre labeler y backtest engine.
Si una sola pieza falla, el sistema queda parado por diseño (fail-safe defaults).
flowchart LR
EXT[Exchange APIs<br/>KuCoin · Binance<br/>via CCXT]
INGEST[Ingest Layer<br/>boost · live · parallel · prefetch]
QUALITY[Quality Layer<br/>feed_integrity<br/>ohlcv_validator<br/>quality.py<br/>winsorizer]
FEAT[Feature Engineering<br/>EMA · RSI · ATR · BB · MACD · Stochastic<br/>strict no-lookahead]
CONF[Confluence Engine<br/>3 VETO + 6 VOTE<br/>9 subsystems]
DL[ML Ensemble Layer<br/>LSTM advanced + TCN<br/>+ XGBoost wrappers<br/>+ Meta-agent RL PPO]
GOV[Governance Agent<br/>12 safety gates<br/>circuit breaker · kill-switch<br/>reconciliation FSM]
EXEC[Execution Router<br/>idempotent orders<br/>SHA-based clientOid]
AUDIT[(Audit Log<br/>append-only<br/>+ State Store SQLite)]
EXT --> INGEST --> QUALITY --> FEAT --> CONF --> DL --> GOV --> EXEC
EXEC -.-> EXT
GOV --> AUDIT
EXEC --> AUDIT
style GOV fill:#fee,stroke:#c00
style DL fill:#eef,stroke:#06c
style QUALITY fill:#efe,stroke:#0a0
Mockup del /dashboard real-time del bot con datos completamente sintéticos (sin valores absolutos de PnL, posiciones reales ni timestamps reales). Muestra los 8 paneles del dashboard productivo: equity curve, signals throughput, health checks, 12 safety gates activos, trace del último signal por las 6 fases del pipeline, errores y alertas P1/P2, SLO compliance con bars de 30 días, posiciones + watchdog + reconciliation status. El dashboard real existe pero no se publica porque incluye valores absolutos del paper trading del owner.
| Capa | Tecnología | Notas |
|---|---|---|
| Lenguaje | Python 3.11+ | Poetry para gestión de dependencias |
| Exchange connectivity | CCXT (broker-agnostic) | KuCoin Futures como validation venue, Binance como smoke test |
| Data quality | NumPy + Pandas + custom validators | 3 capas: feed integrity, OHLCV validator, quality |
| Indicators (TA) | pandas-ta + ta-lib | EMA, RSI, ATR, Bollinger, MACD, Stochastic |
| ML clásico | XGBoost + scikit-learn | Wrapper estándar como baseline del ensemble |
| Deep learning | LSTM advanced + TCN (Temporal Convolutional Network) | Módulo DL con clase base + variantes avanzadas |
| Ensemble | Voting con peso por confianza | Combinación multi-modelo de outputs |
| Reinforcement learning | PPO via stable_baselines3 |
Meta-agent v1 + v2.2 Ex-Ante Control |
| Backtesting | Custom candidate pipeline | Determinista, walk-forward, costs parity con labeler |
| Validation rigor | Walk-forward rolling con embargo + purge | PurgedTimeSeriesSplit custom + bootstrap CI |
| State persistence | SQLite con TTL + atomic writes | Módulo de file locking propio para safety state |
| Idempotencia | clientOid determinista SHA-based | Hash combinando intent + símbolo + lado + cantidad + precio + bucket temporal |
| Observabilidad | JSONL estructurado + Prometheus /metrics + Telegram alerts + /dashboard |
7 SLOs formales documentados |
| Deploy target | Oracle Cloud Always Free Tier | VM.Standard.E2.1.Micro · ~0 €/mes |
| CI | GitHub Actions + pre-commit hooks (ruff, lint) |
flowchart TB
subgraph ext["External Systems"]
EXCHANGE["Crypto Exchange<br/>KuCoin Futures · Binance<br/>via CCXT REST"]
DATA_HIST["Historical Data Sources<br/>OHLCV multi-timeframe"]
TG["Telegram Bot API<br/>(alerting channel)"]
end
subgraph actors["Actors"]
OPERATOR["Operator<br/>(strategy researcher)"]
AUDITOR["Auditor / Reviewer<br/>(post-mortem analysis)"]
end
FUTUROS["Futuros<br/>Quantitative Validation Pipeline<br/>Multi-model + Governance Agent"]
OPERATOR -->|"deploy · monitor · retrain"| FUTUROS
AUDITOR -->|"review audit log · replay decisions"| FUTUROS
FUTUROS -->|"OHLCV fetch · orders (paper)<br/>reconciliation"| EXCHANGE
DATA_HIST -->|"training datasets<br/>WFO splits"| FUTUROS
FUTUROS -->|"alerts P1/P2/P3<br/>health · drawdown · kill-switch"| TG
classDef system fill:#2962FF,stroke:#1E88E5,color:white
classDef external fill:#00C853,stroke:#00E676,color:white
classDef actor fill:#757575,stroke:#9E9E9E,color:white
class FUTUROS system
class EXCHANGE,DATA_HIST,TG external
class OPERATOR,AUDITOR actor
flowchart TB
subgraph boundary["Futuros Pipeline"]
subgraph data_tier["Data Tier"]
INGEST["Ingest Layer<br/>boost · live · parallel · prefetch"]
QUALITY["Quality Layer<br/>3-capa validation + winsorizer"]
CACHE[("OHLCV Cache<br/>+ Paper Trading Collector")]
end
subgraph feat_tier["Signal Tier"]
FEAT["Feature Engineering<br/>TA indicators<br/>strict no-lookahead"]
CONF["Confluence Engine<br/>9 subsystems VETO/VOTE"]
CANDIDATE["Candidate Generator + Labeler"]
end
subgraph ml_tier["ML Tier"]
DL_MODELS["DL Models<br/>LSTM advanced · TCN<br/>XGBoost wrappers"]
ENSEMBLE["Ensemble Voting<br/>(confidence-weighted)"]
META_RL["Meta-agent RL<br/>PPO v1 + v2.2"]
INFERENCE["Inference Predictor"]
end
subgraph gov_tier["Governance Tier"]
DECISION["Decision Engine"]
AGENT["Governance Agent<br/>12 safety gates"]
RISK["Risk Envelope<br/>kill-switch · drawdown guard<br/>no over-leverage"]
RECONCILE["Reconciliation FSM<br/>report · adopt · cancel_orphans · abort"]
end
subgraph exec_tier["Execution Tier"]
ROUTER["Execution Router<br/>idempotent clientOid<br/>bracket orders"]
STATE[("State Store SQLite<br/>safety state + TTL<br/>atomic writes")]
end
subgraph obs_tier["Observability"]
METRICS["Metrics SQLite<br/>+ Prometheus /metrics"]
DASHBOARD["Dashboard<br/>(8 panels real-time)"]
ALERTS["Telegram Alerts<br/>P1/P2/P3 channels"]
AUDIT[("Audit Log JSONL<br/>append-only + redacting")]
end
end
subgraph external["External"]
EXCHANGE["Exchange (CCXT)"]
OPERATOR["Operator"]
end
EXCHANGE --> INGEST
INGEST --> QUALITY
QUALITY --> CACHE
CACHE --> FEAT
FEAT --> CONF
CONF --> CANDIDATE
CANDIDATE --> DL_MODELS
DL_MODELS --> ENSEMBLE
META_RL --> ENSEMBLE
ENSEMBLE --> INFERENCE
INFERENCE --> DECISION
DECISION --> AGENT
AGENT --> RISK
RISK -->|allowed| ROUTER
RISK -->|blocked| AUDIT
ROUTER -->|orders| EXCHANGE
ROUTER --> STATE
STATE -->|on startup| RECONCILE
RECONCILE --> EXCHANGE
AGENT --> METRICS
ROUTER --> METRICS
METRICS --> DASHBOARD
METRICS --> ALERTS
ALERTS -->|notify| OPERATOR
DASHBOARD -->|view| OPERATOR
ROUTER --> AUDIT
DECISION --> AUDIT
classDef data fill:#FF6D00,stroke:#FF9100,color:white
classDef signal fill:#7C4DFF,stroke:#651FFF,color:white
classDef ml fill:#2962FF,stroke:#1E88E5,color:white
classDef gov fill:#D32F2F,stroke:#B71C1C,color:white
classDef exec fill:#388E3C,stroke:#1B5E20,color:white
classDef obs fill:#00BFA5,stroke:#1DE9B6,color:white
classDef external fill:#757575,stroke:#9E9E9E,color:white
class INGEST,QUALITY,CACHE data
class FEAT,CONF,CANDIDATE signal
class DL_MODELS,ENSEMBLE,META_RL,INFERENCE ml
class DECISION,AGENT,RISK,RECONCILE gov
class ROUTER,STATE exec
class METRICS,DASHBOARD,ALERTS,AUDIT obs
class EXCHANGE,OPERATOR external
Detalles arquitectónicos:
- Pipeline de 6 capas con responsabilidades estrictamente separadas (Data → Signal → ML → Governance → Execution → Observability).
- Cada capa es testable de forma independiente; los gates de governance funcionan aunque el modelo esté caído (fallback strategy).
- Idempotencia determinista enforced a nivel exchange via
clientOidSHA-based (anti-duplicación en retries). - Reconciliation FSM al startup garantiza coherencia local-exchange tras cualquier crash (4 acciones: report, adopt, cancel_orphans, abort).
- Audit log append-only con redacting formatter automático (cero secrets en logs).
El proyecto mantiene 40+ ADRs versionadas (nomenclatura ADR-FTS-<CATEGORÍA>-<NÚMERO>). Siete que ejemplifican el criterio aplicado:
| ADR | Decisión | Por qué importa |
|---|---|---|
| ADR-FTS-VALIDATION-001 rolling-wfo |
Reemplazar single-pass backtest con walk-forward rolling (90 días train, 30 step) + gates estadísticos (PF median, DD percentile, bootstrap CI) | Metodología gold-standard. Democratiza la aprobación de estrategias con p-values en lugar de "feels good". Aplicable a cualquier sistema cuantitativo. |
| ADR-FTS-ML-CORRECTION-001 + 002 |
Tres bugs críticos en ML (target leakage, train/test shuffle, CV sin embargo) → implementar purged walk-forward con gaps explícitos (embargo = ventana de feature autocorrelation, purge = horizon de labels) | Validación temporal de ML requiere tres dimensiones: temporal order, forward-only labels, embargo entre train/test. Omitir uno invalida el modelo. Aplicable a ML temporal en cualquier dominio (finanzas, predicción de demanda, anomaly detection). |
| ADR-FTS-DETECTOR-002 (Market State Detector V2) |
Reemplazar lógica OR (1-de-3) con votación mayoritaria (K-de-N) y umbrales tighter para clasificar régimen de mercado | Patrón K-de-N como gate de confirmación es replicable en cualquier sistema con múltiples señales que necesita evitar falsos positivos. Trade-off explícito sensibilidad vs ruido. |
| ADR-FTS-PHASE-GATES | Definir contrato explícito de cada fase (F1 = deterministic generator, F2 = decision layer, F3 = execution + risk) | Articulación de responsabilidades por capa. Útil como template para architecture reviews en ML pipelines o data systems en general. |
| ADR-FTS-F1-OPS-RELIABILITY | Atomic writes (temp + rename) + deterministic trade UIDs basados en inputs inmutables | Garantiza "resumability" sin corrupción en sistemas con crash recovery. UID determinista permite deduplicación en re-runs. Schema versioning explícito. Aplicable a cualquier ETL / pipeline crítico. |
| ADR-FTS-OPS-STATE-001 | SQLite state store durable con TTL para safety state (cooldown, circuit breaker, day equity) | Patrón "no perder estado crítico en crash" sin overhead de base de datos completa. Volumen Docker persistente. Aplicable a cualquier servicio que necesita durabilidad entre reinicios. |
| ADR-FTS-SAFETY-DEFAULTS-001 | DRY_RUN env unset → True (fail-safe). Para activar live: MUST ser explícito DRY_RUN=false. Defense-in-depth: 3 capas (env, app mode, ensure check) son ahora fail-safe |
Principio OWASP de defaults seguros. Ausencia ≠ permiso. Una línea de código de diferencia entre un bot seguro y uno que opera real por olvido. |
(Las ADRs restantes cubren ML model selection por uplift económico, dataset generation strategy, F2 pipeline stabilization, position sizing graduado, lockbox gates con CI bootstrap, shadow runner simulation framework, risk envelope + kill-switch calibration, GDPR-equivalent retention policies. No se publican individualmente para preservar IP, pero la metodología es replicable.)
Ocho incidentes / decisiones técnicas resueltas durante el proyecto. Estructura fija Síntoma → Causa raíz → Fix → Lección. El primero abierto como muestra; los demás expandibles con click.
1. Threshold logic override bug — cierre lógico de invariantes
- Síntoma: el scoring del Confluence Engine sobrescribía rechazos duros de threshold validation. Trades que deberían bloquearse por política (alignment y confidence por debajo de umbrales estrictos del policy gate, parametrizados, no publicados) pasaban porque el score post-asignaba
meets_threshold = Truedespués de que el chequeo de policy lo había fijado enFalse. - Causa raíz: lógica condicional invertida — el segundo chequeo (scoring) podía invalidar el primero (policy). Invariante violada: hard thresholds deben ser duros.
- Fix: refactorización de flujo con precedencia explícita. El scoring solo puede AGREGAR rechazos, nunca remover. Tests de invariante añadidos: una decisión de policy a
Falseno puede ser flipped aTruepor capas posteriores. - Lección: en sistemas multi-etapa con múltiples decisiones, la composición lógica requiere definición explícita de precedencia y direccionalidad (solo agregación vs sobrescritura). Las invariantes de policy deben declararse formalmente como tests.
2. Subsystem ablation — identificación de componentes tóxicos via attribution analysis
- Síntoma: Win Rate total bajo en un período representativo; algunos subsystems predecían probabilidades opuestas. Attribution analysis reveló un subsystem con lift cero o negativo sostenido — peor que random.
- Causa raíz: indicadores de mean-reversion conflictando con subsystem de trend-following. Contradicción arquitectónica enmascarada por el agregado del voto.
- Fix: implementar ablation study sistemático por subsystem. Retirar el subsystem tóxico mejoró Win Rate, Profit Factor y redujo pérdidas totales en magnitudes significativas validadas con bootstrap CI sobre los deltas. Causalidad validada (no correlación espuria).
- Lección: ensemble systems requieren attribution analysis antes de solo agregar votos. Componentes pueden ser saboteadores silenciosos si no se mide su lift vs baseline. Diversidad ≠ beneficio automático.
3. Cost model fragmentation — Single Source of Truth roto en 4 módulos
- Síntoma: el PnL reportado variaba según qué módulo lo calculaba (capa de riesgo, motor de backtest, script de validación rigurosa de fase 1, esquemas del shadow runner). En estrategias de bajo edge, esto era suficiente para invertir el signo del Profit Factor entre training y validación.
- Causa raíz: ausencia de Single Source of Truth. Cuatro módulos con defaults ligeramente distintos en fee y slippage produciendo round-trip combinado con dispersión amplia.
- Fix: crear un módulo canónico (
DEFAULT_COST_MODELdataclass frozen, parametrizado) en el backtest engine e importarlo en todos los módulos relevantes. Test de parity valida que labeler PnL == backtest PnL sobre fixtures conocidos. - Lección: variables de negocio críticas (costos, thresholds, riesgos) deben tener SoT único. Fragmentación silenciosa es más peligrosa que duplicación audible. Patrón: dataclass única + importar en todos los puntos + tests de parity.
4. Race condition en idempotencia de órdenes
- Síntoma: bot envía orden sin
clientOrderId. Network timeout antes de respuesta. Bot interpreta timeout como fallo → retry. Misma orden abierta 2 veces en exchange → posición duplicada, riesgo de liquidación. - Causa raíz: la función de envío de órdenes no implementaba idempotencia. El exchange (KuCoin Futures) soporta
clientOidpara prevenir duplicación pero no se usaba. Antipatrón: retry sin idempotencia = multiplicación accidental. - Fix: generar
clientOrderIddeterminista combinando metadata del intent (símbolo, lado, cantidad, precio, bucket temporal) en un hash SHA-based. Mismo intent + misma ventana temporal → mismo id → el exchange rechaza el duplicado server-side. - Lección: en sistemas distribuidos con retry, la idempotencia debe ser explícita y determinista. UUID nonce no es suficiente (cada retry genera UUID nuevo). Bucketing por tiempo + intent permite deduplicación en el exchange (source of truth).
5. State drift detection — local cache vs exchange desincronización silenciosa
- Síntoma: bot crashea mid-flight (orden enviada, sin respuesta). Reinicia. Orden abierta en exchange pero no en el state store local. Siguiente decisión usa estado incompleto → crea posición duplicada o no cierra SL/TP.
- Causa raíz: sin reconciliación explícita, el bot asume coherencia local ↔ exchange. Realidad: network partitions, container shutdowns, manual operator trades, rejected orders son comunes. Sin detección, drift es silencioso.
- Fix: máquina de estados explícita de reconciliación al startup con 4 acciones:
report(solo log),adopt(exchange como SoT),cancel_orphans(con filtro de prefijo propio del bot),abort(paranoid mode). Detecta orphans, missing y position mismatch. - Lección: sistemas distribuidos requieren explicitación de "qué es source of truth". Local cache ≠ authority. Reconciliación declarativa (report/adopt/cancel/abort) antes de operar es defense-in-depth.
6. Early drawdown attribution — timing mismatch en mode switching
- Síntoma: meta-agent (modo switching automático OFF→ON) triggers bearish override después de que las condiciones se validan. Pero la inmensa mayoría del drawdown observado vino de trades ANTES del override. El modo ON evita pérdidas, pero solo después de que ya ocurrieron.
- Causa raíz: el confirmation window (varias decenas de horas) requiere esperar a que síntomas se confirmen. En mercados volátiles, el daño ocurre antes: el first trade entra cuando el régimen ya cambió internamente pero el sistema no lo ve aún. Información asimétrica.
- Fix: reemplazar switching binario por graduated position sizing ladder: la fracción de tamaño se reduce escalonadamente según número de condiciones bearish presentes (K-de-N, no wait-for-all). Plus shock override: ventana de peor performance < threshold → bloquea entries durante confirmation window.
- Lección: el timing de detección vs ejecución es asimétrico. Confirmation windows causan "first few trades are always wrong". Mejor táctica: reducir exposición gradualmente basado en evidencia acumulada, no buscar certeza + confirmation. Position sizing como variable de control en vez de modo binario.
7. ML validation rigor — tres bugs críticos en testing temporal
- Síntoma: el modelo ML reportaba ROC-AUC favorable en train pero apenas mejor que random en test. Auditoría reveló 3 bugs críticos ocultando la verdad.
- Causa raíz triple:
- Target leakage: rolling window mal compuesto sobre serie shifted mezclaba bars históricos con futuros → label contaminado.
- Random temporal split:
shuffle=Trueen el split mezclaba samples antiguas con recientes en ambos conjunt 8BD0 os → data leak automático. - CV sin embargo: KFold random ignoraba que features tienen ventana de rolling → información cross-fold.
- Fix:
- Look-forward puro:
rolling(N).shift(-N)(rolling primero sobre la serie original, luego shift entero al pasado). - Split temporal cronológico estricto (primeros % = train, últimos % = test, sin shuffle).
PurgedTimeSeriesSplitcustom con purged window dimensionado al horizon de features.
- Look-forward puro:
- Lección: walk-forward validation requiere tres dimensiones simultáneas: temporal order, forward-only labels, embargo entre train/test. Omitir uno invalida el modelo. Tests rojo→verde en cada fix valida causa-efecto.
8. Secure defaults anti-pattern — DRY_RUN fail-open
- Síntoma:
os.getenv("DRY_RUN", "false") == "true". Si la env no estaba seteada (script auxiliar, debugging local, contenedor sin.env), default erafalse→ live trading. El bot podía ejecutar órdenes reales por error. - Causa raíz: antipatrón de seguridad clásico — "ausencia de configuración = permiso". Docker declaraba
ENV APP_MODE=papercorrectamente, pero la primera capaDRY_RUNera fail-open, contradiciendo la intención. - Fix: helper que resuelve: unset →
True(dry-run), explicitfalse→False(live), ambiguous/typos →True(fail-safe). Para activar live: debe ser explícitoDRY_RUN=false. Defense-in-depth con 3 capas (DRY_RUN,APP_MODE, ensure-not-accidentally-live), todas fail-safe. - Lección: security flags deben tener secure defaults. Ausencia ≠ permiso. Patrón: nil-safe resolution + explicit typo handling (ambiguous → safe) + log explícito de qué default se tomó.
| Dimensión | Valor actual | Notas |
|---|---|---|
| Infraestructura | Oracle Cloud Always Free Tier (VM.Standard.E2.1.Micro AMD) · 1/8 vCPU · 1 GB RAM · 50 GB disco | Docker Compose + Caddy reverse proxy. Stack auto-contenido. |
| Coste mensual | 0 €/mes | Free tier permanente. 10 TB bandwidth/mes incluidos. |
| Frecuencia de señales | ≈ 48 por día (30-min candles, 1 símbolo) | Backtest reproducible sobre 29 meses de histórico. |
| Latencia objetivo (P99) | Signal generation < 5 s · Order execution < 2 s · ML inference < 200 ms · Risk guards < 50 ms · Telegram alert < 5 s | 7 SLOs formales documentados según método Google SRE. |
| Data freshness | 99 % de samples con staleness < 5 min | Healthcheck endpoint con detección automática (> 90 min = critical). |
| Availability target | 99.5 % (30 días) · ≈ 3.5 h/mes downtime permitido | Error budget policy explícita. |
| Rate limiting exchange | < 50 % del límite (KuCoin 1800 req/min) | Self-throttling preventivo. |
| Backup / DR | State store SQLite con volumen Docker persistente + reconciliation FSM al startup | Recovery automático tras crash sin pérdida de safety state (cooldown, circuit breaker, day equity). |
| Memory footprint | < 500 MB promedio · < 1 GB pico | Footprint ML diseñado para Free Tier. |
| Observability | JSONL estructurado (con redacting automático) + Prometheus /metrics + Telegram alerts P1/P2/P3 + Dashboard real-time 8 paneles |
Sin overhead de Datadog/NewRelic. |
- 40+ ADRs versionadas documentando arquitectura, alternativas y consecuencias de cada decisión estructural.
- 7 SLOs formales con error budget policy explícita.
- 12 safety gates testeados de forma independiente del modelo (la governance funciona aunque el ML esté caído).
- 3 capas de validación de calidad de datos (feed integrity, OHLCV validator, quality module) con tests específicos por capa.
- Walk-forward con embargo + purge implementado correctamente tras descubrir y fix de 3 bugs críticos en validación temporal.
- Reconciliation FSM al startup garantiza coherencia local-exchange tras crash, con 4 acciones explícitas (report/adopt/cancel/abort).
- Idempotencia determinista end-to-end via
clientOidSHA-based; cero duplicación de órdenes en retries. - Cost model parity validado por test entre labeler y backtest engine.
Métricas absolutas de trading (PnL, profit factor por período, ratio Sharpe) no se publican porque el proyecto está en paper trading con propósito metodológico, no comercial.
| Componente | Estado |
|---|---|
| Plataforma | Paper trading · DRY_RUN = true por defecto |
| Capa de datos | Producción · 3 capas de validación + cache + colector |
| Confluence engine | Producción · 9 subsystems VETO/VOTE |
| Stack ML | Arquitectura completa en código (LSTM advanced + TCN + XGBoost + ensemble + PPO RL). Modelos entrenados activos: XGBoost. LSTM/TCN/PPO construidos como infraestructura disponible. |
| Governance agent | Producción · 12 safety gates + reconciliation FSM |
| Execution router | Producción · idempotente · reconciliation al startup |
| Observabilidad | Producción · 7 SLOs · alerts Telegram · dashboard real-time |
| Deployment | Documentado y desplegable en Oracle Free Tier en < 30 min |
| Research project | Pausado formalmente tras walk-forward determinar que la alpha estudiada no tiene edge estadísticamente significativo en el período analizado. Activos metodológicos y arquitectónicos documentados como aprendizaje standalone. |
Completado
- Pipeline de ingesta multi-modo (boost, live, parallel, prefetch) sobre CCXT.
- 3 capas de validación de calidad de datos + winsorización con tests.
- 9 subsystems de confluence con patrón VETO/VOTE.
- Walk-forward con embargo + purge correctamente implementado.
- Ensemble multi-modelo (LSTM advanced + TCN + XGBoost) con voting.
- Meta-agent RL (PPO via stable_baselines3) v1 + v2.2 Ex-Ante Control.
- 12 safety gates testeados independientes del modelo.
- Reconciliation FSM al startup.
- Idempotencia determinista de órdenes via clientOid SHA-based.
- State store SQLite durable con TTL + atomic writes.
- 7 SLOs formales con error budget policy.
- Deploy plan en Oracle Cloud Always Free Tier (0 €/mes).
- 40+ ADRs documentando cada decisión estructural.
- Ablation analysis sistemático por subsystem.
En investigación
- Distributed tracing cross-component (gap identificado en P1 de observability).
- Error classification por tipo (gap identificado).
- Cardinality controls para Prometheus metrics (anti-explosion).
- SLO dashboard visual (más allá de queries SQL).
Roadmap condicional (si se reactiva el proyecto)
- Re-estudio de hipótesis de edge sobre nuevos features / timeframes.
- Activación de LSTM advanced + TCN como modelos productivos del ensemble.
- Migration plan a multi-tenant si llega caso de uso institutional.
- API pública para terceros que quieran usar el framework de validación con sus propias estrategias.
| Aspecto | Estado |
|---|---|
| Estado regulatorio | Paper trading (no operación con capital, no servicio a terceros, no señales públicas) |
| Secrets management | Redacting formatter automático en JSONL · pre-commit hooks · .env siempre fuera de git |
| Auth en runtime | Telegram bot privado · API keys exchange en env vars · rotación documentada |
| Audit trail | Append-only JSONL con redacting + state store SQLite con TTL |
| Fail-safe defaults | DRY_RUN unset → True · 3 capas defense-in-depth |
| Backup strategy | State store volumen persistente · reconciliation al startup garantiza recovery |
| Health monitoring | /health endpoint con staleness detection · Telegram alerts P1/P2/P3 · dashboard real-time |
- docs/overview.md — visión completa del pipeline, lectura de 5 minutos.
- docs/architecture.md — arquitectura detallada por capas, decisiones de diseño.
- docs/methodology.md — metodología de validación cuantitativa (walk-forward + embargo + purge + ablation + lockbox).
- docs/metrics.md — madurez técnica del proyecto y SLOs detallados.
Futuros es la materialización de un principio: una estrategia algorítmica de trading no se despliega; se valida hasta que el framework de validación dice que tiene edge — o el framework la rechaza.
En este caso, el framework rechazó la alpha estudiada por evidencia estadística insuficiente, evitando el despliegue prematuro de capital sobre un sistema con resultados favorables en backtest puntual pero no estables en walk-forward con embargo y purge.
Eso es el valor del proyecto: un sistema diseñado para descubrir ausencia de edge cuando otros marcos lo enmascararían. La pieza vendible no es la alpha (que el sistema demostró no tener), sino la metodología, la disciplina arquitectónica y los activos reutilizables.
- No es una señal de trading. No emite recomendaciones.
- No es un servicio comercial. No acepta capital de terceros.
- No publica la alpha estudiada ni features/thresholds específicos. La metodología sí; los parámetros propietarios no.
- No promete rentabilidad. Es un framework de validación, no un producto de inversión.
- No es asesoramiento financiero. Es ingeniería cuantitativa aplicada al problema de detectar edge real en estrategias algorítmicas.
Este proyecto sigue un sistema operativo de ingeniería propio del autor, replicado y mejorado cross-proyecto a lo largo de múltiples proyectos del ecosistema. La documentación es activo de primera clase, no afterthought.
5 protocolos doctrinales activos:
- Automation Engineering Protocol — stage-gate horizontal de cambio: change-spec → guard layer → release train → rollback playbook.
- Prompt Engineering Protocol — diseño modular de prompts con estructura fija (required / optional / exclusion keywords + patterns regex + confidence scoring + anti-echo + whitelist validator + schema JSON validation).
- Post-Development Verification Protocol — 4 niveles de verificación tras cada cambio: estática + integración + canarios E2E con datos sintéticos + observabilidad diaria.
- Post-Development Gates — 94 gates pre-merge / pre-deploy / post-deploy con checklist bloqueante.
- Frozen Zones & Regression Prevention — distinción explícita CONFIG (estable) vs HEALTH (móvil), auditoría holística periódica, mapa de zonas frozen para prevenir regresión cross-pieza.
Disciplina cross-proyecto:
- Cada decisión estructural se documenta como ADR versionada con contexto + alternativas evaluadas + consecuencias + plan de rollout.
- Cada cambio significativo pasa por
verify-findingsadversarial (auditoría con segundo agente independiente, ratio de ruido objetivo < 15%). - Documentación arc42 + C4 (Context + Container) + runbooks operativos + postmortems formales. Detalle completo del protocolo en
docs/documentation-protocol.md. - Engineering-playbook propio con 60+ archivos doctrinales cross-proyecto, evolucionado iterativamente desde incidentes reales.
Detalles operativos completos del playbook bajo acuerdo de confidencialidad.
SatData Solutions — Valencia, España
- Email: solutions.satdata@gmail.com
- LinkedIn: Kamil Slodki
- Portfolio: satdata-portfolio
Demos arquitectónicas y revisión del framework metodológico bajo NDA para contrapartes técnicas (fondos de inversión, quant infra teams, plataformas que necesitan validación rigurosa de modelos antes de poner capital).
Este repositorio es la vitrina técnica pública de Futuros. No contiene el código fuente del producto, que se mantiene en repositorio privado. Su propósito es mostrar la arquitectura, decisiones de diseño y madurez técnica para clientes potenciales, partners e interesados en evaluar capacidad técnica en sistemas cuantitativos con rigor metodológico.
Para acceso al producto, demos del framework de validación o conversaciones técnicas detalladas, contactar por los canales arriba.