branch main commit 349280e built last · fix(ranking): only canonical reference gets PROD badge — not every V66 baseline
🟢 En producción (resaltadas)
V2 · GRU Ensemble (always-invested)7,641% compound · α —
V3 · hybrid_v3 (GRU + DailyRSI>80 + Trail 10%)7,128% compound · α —
V4 · hybrid_v5 (GRU 3-Regime V5.4 Robust-5)30,174% compound · α +117.0
V5 · V115_cmp (GRU + peak_drop + ratchet + regime cooldown)168,759% compound · α +238.0
V6 · V66 Cooldown(4,48)42,636% compound · α +193.0
Por qué los números altos arriba ≠ candidatos reales: rondas pre-R173 (R130-R172) corren bajo el engine viejo con intra-bar lookahead + apalancamiento sin coste. R154 muestra +250K compound pero es la MISMA estrategia R151-A bajo bug-fixed engine que da +113K (R174). El número alto es artefacto. Por eso los CANDIDATOS reales (azul) son R174+. Filtra "ocultar buggy-engine" si quieres ver solo resultados honestos.
144 estrategias
Round Variant Compound % Min α Beats BH Trades WR OOT α
R154 skip shorts if 21d return > +15%BUGGY-ENGINE 250,538% +245.1 4/4 88 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)1,055.4%+951.4%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=88 · WR=—

Métricas y config crudas (metadata.json)

lookback
21
return_th
0.15
shorts_skipped
243

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R154 skip shorts if 7d return > +10%BUGGY-ENGINE 234,511% +245.1 4/4 90 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)981.5%+877.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=90 · WR=—

Métricas y config crudas (metadata.json)

lookback
7
return_th
0.1
shorts_skipped
160

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R154 skip shorts if 21d return > +20%BUGGY-ENGINE 213,591% +245.1 4/4 89 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)885.1%+781.1%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=89 · WR=—

Métricas y config crudas (metadata.json)

lookback
21
return_th
0.2
shorts_skipped
219

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R151 short P(SL)>0.65, exit P(TP)>0.35, sl=8%, max=40hBUGGY-ENGINE 212,591% +245.1 4/4 93 sh 56.6%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)880.5%+776.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=56.550925925925924%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 longs (canonical) + SHORT module: cuando V66 está en cash, si P(SL)>0.65 (3/5 seeds), abre short. Cierra en P(TP)>0.35, stop 8%, o 40h timeout.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r151_shorts_in_gaps.py
Experimento: R151: V66 long + SHORT during cash gaps
Origen: outputs/round_151_shorts_gaps/metadata.json · → ver detalle de la ronda
R154 R151-A (no regime filter)BUGGY-ENGINE 212,591% +245.1 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)880.5%+776.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

shorts_skipped
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R160 R151-A no friction (baseline)BUGGY-ENGINE 212,591% +245.1 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)880.5%+776.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

funding
0.0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r160_funding_stress.py
Experimento: R160: friction stress on R151-A
Origen: outputs/round_160_friction_stress/metadata.json · → ver detalle de la ronda
R160 + funding 0.01%/8hBUGGY-ENGINE 191,908% +234.1 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)834.7%+730.7%104%
F1 Bull (2019-21)845.4%-316.6%1162%
F2 Recovery (2022-24)468.5%+234.5%234%
F3 Lateral (2024-25)282.2%+282.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

funding
0.0001

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r160_funding_stress.py
Experimento: R160: friction stress on R151-A
Origen: outputs/round_160_friction_stress/metadata.json · → ver detalle de la ronda
R154 skip shorts if 7d return > +5%BUGGY-ENGINE 181,144% +245.1 4/4 88 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)735.5%+631.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=88 · WR=—

Métricas y config crudas (metadata.json)

lookback
7
return_th
0.05
shorts_skipped
254

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R137 R117 MACD_div local reproductionBUGGY-ENGINE 179,453% -42.0 3/4 6,544
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)+480.5%104%
F1 Bull (2019-21)+2,405.6%1162%
F2 Recovery (2022-24)-42.0%234%
F3 Lateral (2024-25)+270.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=6544 · WR=—

Métricas y config crudas (metadata.json)

folds_trades
[1658, 1624, 1639, 1623]
folds_wr
[44.27020506634499, 45.19704433497537, 44.05125076266016,...
folds_mdd
[23.591372375173027, 18.580826219207594, 19.8152419508006...
bh_per_fold
[59.18068329501152, 99.98283255066114, 228.4183620424153,...
reproduces_r117
True
compound_diff_pct
1.591644913315314e-05
r117_expected
{"compound": 179453.2, "min_alpha": -42.0, "beats_bh": 3,...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r137_macd_repro.py
Experimento: R117 MACD_div local reproduction
Origen: outputs/round_137/metadata.json · → ver detalle de la ronda
R137 R117 MACD_div local reproductionBUGGY-ENGINE 179,453% -42.0 3/4 6,544
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)+480.5%104%
F1 Bull (2019-21)+2,405.6%1162%
F2 Recovery (2022-24)-42.0%234%
F3 Lateral (2024-25)+270.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=6544 · WR=—

Métricas y config crudas (metadata.json)

folds_trades
[1658, 1624, 1639, 1623]
folds_wr
[44.27020506634499, 45.19704433497537, 44.05125076266016,...
folds_mdd
[23.591372375173027, 18.580826219207594, 19.8152419508006...
bh_per_fold
[59.18068329501152, 99.98283255066114, 228.4183620424153,...
reproduces_r117
True
compound_diff_pct
1.591644913315314e-05
r117_expected
{"compound": 179453.2, "min_alpha": -42.0, "beats_bh": 3,...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r137_macd_repro.py
Experimento: R117 MACD_div local reproduction
Origen: outputs/round_137_macd_repro/metadata.json · → ver detalle de la ronda
R154 skip shorts if 14d return > +10%BUGGY-ENGINE 172,844% +245.1 4/4 91 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)697.3%+593.3%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=91 · WR=—

Métricas y config crudas (metadata.json)

lookback
14
return_th
0.1
shorts_skipped
153

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R154 skip shorts if 14d return > +15%BUGGY-ENGINE 170,820% +245.1 4/4 91 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)687.9%+583.9%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=91 · WR=—

Métricas y config crudas (metadata.json)

lookback
14
return_th
0.15
shorts_skipped
109

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Same as R151 + regime filter: skip shorts if recent N-day return > threshold (variants: 7d>+5/+10, 14d>+10/+15, 21d>+15/+20).
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r154_regime_filtered_shorts.py
Experimento: R154: regime-filtered shorts (R151-A base)
Origen: outputs/round_154_regime_shorts/metadata.json · → ver detalle de la ronda
R110 V115_cmp (GRU + peak_drop + ratchet + regime cooldown) — V5 PROD V5BUGGY-ENGINE 168,759% +238.0 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)728.1%+624.1%104%
F1 Bull (2019-21)669.7%-492.3%1162%
F2 Recovery (2022-24)307.3%+73.3%234%
F3 Lateral (2024-25)238.4%+238.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

deployment_status
Active on V5 (V115_cmp (GRU + peak_drop + ratchet + regim...
synthetic_source
SESSION_STATE.md + ROUNDS_LOG.md (canonical round metadat...
note
Higher min α que V66 (+238 vs +193 honest). HybridV115Tra...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r110_local.py
Experimento: Production strategy on V5 bot. Higher min α que V66 (+238 vs +193 honest). HybridV115Trader class compartida con V66 (V6), solo difiere YAML. Validada en R110 (folds 728.1/669.7/307.3/238.4). Pre-audit number — pendiente honest re-eval bajo bug-fixed engine.
Origen: synthetic from SESSION_STATE.md (canonical round R110) · → ver detalle de la ronda
R160 + funding 0.03%/8h (worst case)BUGGY-ENGINE 156,375% +212.8 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)749.5%+645.5%104%
F1 Bull (2019-21)831.3%-330.7%1162%
F2 Recovery (2022-24)447.2%+213.2%234%
F3 Lateral (2024-25)261.5%+261.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

funding
0.0003

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r160_funding_stress.py
Experimento: R160: friction stress on R151-A
Origen: outputs/round_160_friction_stress/metadata.json · → ver detalle de la ronda
R160 + regime slippageBUGGY-ENGINE 143,856% +198.3 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)812.6%+708.6%104%
F1 Bull (2019-21)738.9%-423.1%1162%
F2 Recovery (2022-24)432.7%+198.7%234%
F3 Lateral (2024-25)253.0%+253.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

funding
0.0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r160_funding_stress.py
Experimento: R160: friction stress on R151-A
Origen: outputs/round_160_friction_stress/metadata.json · → ver detalle de la ronda
R181 skip shorts if 21d return > +15% 136,242% +193.8 4/4 89 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)698.2%+641.5%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=89 · WR=—

Métricas y config crudas (metadata.json)

lookback
21
return_th
0.15
shorts_skipped
243

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R160 + funding 0.01% + regime slipBUGGY-ENGINE 129,857% +188.2 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)770.0%+666.0%104%
F1 Bull (2019-21)732.6%-429.4%1162%
F2 Recovery (2022-24)422.6%+188.6%234%
F3 Lateral (2024-25)243.3%+243.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

funding
0.0001

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r160_funding_stress.py
Experimento: R160: friction stress on R151-A
Origen: outputs/round_160_friction_stress/metadata.json · → ver detalle de la ronda
R181 skip shorts if 7d return > +10% 124,625% +193.8 4/4 91 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)630.2%+573.5%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=91 · WR=—

Métricas y config crudas (metadata.json)

lookback
7
return_th
0.1
shorts_skipped
160

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R181 skip shorts if 21d return > +20% 115,235% +193.8 4/4 90 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)575.3%+518.6%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=90 · WR=—

Métricas y config crudas (metadata.json)

lookback
21
return_th
0.2
shorts_skipped
219

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R151 short P(SL)>0.70, exit P(TP)>0.30, sl=10%, max=40hBUGGY-ENGINE 114,349% +321.6 4/4 45 sh 73.6%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)384.7%+280.7%104%
F1 Bull (2019-21)629.5%-532.5%1162%
F2 Recovery (2022-24)657.3%+423.3%234%
F3 Lateral (2024-25)327.4%+327.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=45 · WR=73.61111111111111%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 longs (canonical) + SHORT module: cuando V66 está en cash, si P(SL)>0.65 (3/5 seeds), abre short. Cierra en P(TP)>0.35, stop 8%, o 40h timeout.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r151_shorts_in_gaps.py
Experimento: R151: V66 long + SHORT during cash gaps
Origen: outputs/round_151_shorts_gaps/metadata.json · → ver detalle de la ronda
R174 R151-A shorts (bugfix engine)CANDIDATE 113,981% +193.8 4/4 94 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)567.9%+463.9%104%
F1 Bull (2019-21)853.9%-308.1%1162%
F2 Recovery (2022-24)428.2%+194.2%234%
F3 Lateral (2024-25)239.0%+239.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r174_r151_bugfix.py
Experimento: R174: R151-A re-validated under bug-fixed engine
Origen: outputs/round_174_r151_bugfix/metadata.json · → ver detalle de la ronda
R181 R151-A base (no filter, honest engine) 113,981% +193.8 4/4 94 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)567.9%+511.2%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=—

Métricas y config crudas (metadata.json)

shorts_skipped
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R182 R151-A base (full notional) 113,981% +193.8 4/4 94 sh 54.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)567.9%+511.2%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=54.02777777777777%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + ADAPTIVE Kelly sizing based on rolling short WR (last N shorts). 4 schedules + half-Kelly fixed tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r182_adaptive_kelly.py
Experimento: R182: R151-A with adaptive Kelly sizing based on rolling short WR
Origen: outputs/round_182_adaptive_kelly/metadata.json · → ver detalle de la ronda
R183 R151-A full notional (instrumented, bug-fixed) 113,981% +193.8 4/4 389 55.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)567.9%+511.2%104%101 (L:61, S:40)55.5% (L:56%, S:55%)
F1 Bull (2019-21)853.9%+755.9%1162%109 (L:100, S:9)54.1% (L:53%, S:67%)
F2 Recovery (2022-24)428.2%+193.8%234%78 (L:60, S:18)56.4% (L:62%, S:39%)
F3 Lateral (2024-25)239.0%+233.2%0%101 (L:74, S:27)54.5% (L:54%, S:56%)
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=389 · WR=55.01%

Métricas y config crudas (metadata.json)

folds_wr
[55.45, 54.13, 56.41, 54.46]
folds_longs
[61, 100, 60, 74]
folds_shorts
[40, 9, 18, 27]
folds_long_wr
[55.74, 53.0, 61.67, 54.05]
folds_short_wr
[55.0, 66.67, 38.89, 55.56]
folds_avg_win_pct
[8.25, 8.53, 6.78, 5.1]
folds_avg_loss_pct
[-4.94, -4.57, -3.07, -2.9]
folds_profit_factor
[2.08, 2.2, 2.86, 2.1]

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r183_instrumented_r151a.py
Experimento: R183: R151-A under bug-fixed engine with full per-fold instrumentation
Origen: outputs/round_183_instrumented_r151a/metadata.json · → ver detalle de la ronda
R181 skip shorts if 7d return > +5% 110,320% +193.8 4/4 89 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)546.5%+489.8%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=89 · WR=—

Métricas y config crudas (metadata.json)

lookback
7
return_th
0.05
shorts_skipped
254

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R181 skip shorts if 14d return > +10% 97,054% +193.8 4/4 91 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)468.8%+412.1%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=91 · WR=—

Métricas y config crudas (metadata.json)

lookback
14
return_th
0.1
shorts_skipped
153

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R160 + all + half-Kelly shorts (50%)BUGGY-ENGINE 89,759% +182.9 4/4 93 sh
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)654.0%+550.0%104%
F1 Bull (2019-21)631.2%-530.8%1162%
F2 Recovery (2022-24)417.3%+183.3%234%
F3 Lateral (2024-25)215.1%+215.1%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

funding
0.0001

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r160_funding_stress.py
Experimento: R160: friction stress on R151-A
Origen: outputs/round_160_friction_stress/metadata.json · → ver detalle de la ronda
R181 skip shorts if 14d return > +15% 88,844% +193.8 4/4 93 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)420.7%+364.0%104%
F1 Bull (2019-21)853.9%+755.9%1162%
F2 Recovery (2022-24)428.2%+193.8%234%
F3 Lateral (2024-25)239.0%+233.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

lookback
14
return_th
0.15
shorts_skipped
109

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + regime filter (skip shorts when N-day return > threshold). 7 variants tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r181_regime_filtered_honest.py
Experimento: R181: regime-filtered R151-A under bug-fixed engine
Origen: outputs/round_181_regime_filtered_honest/metadata.json · → ver detalle de la ronda
R182 Adaptive binary (WR last 10, full/30%) 77,859% +157.7 4/4 94 sh 54.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)521.2%+464.5%104%
F1 Bull (2019-21)713.7%+615.7%1162%
F2 Recovery (2022-24)392.1%+157.7%234%
F3 Lateral (2024-25)213.4%+207.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=54.02777777777777%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + ADAPTIVE Kelly sizing based on rolling short WR (last N shorts). 4 schedules + half-Kelly fixed tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r182_adaptive_kelly.py
Experimento: R182: R151-A with adaptive Kelly sizing based on rolling short WR
Origen: outputs/round_182_adaptive_kelly/metadata.json · → ver detalle de la ronda
R174 R151-A + half-Kelly (bugfix)CANDIDATE 76,873% +178.4 4/4 94 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)482.3%+378.3%104%
F1 Bull (2019-21)732.8%-429.2%1162%
F2 Recovery (2022-24)412.8%+178.8%234%
F3 Lateral (2024-25)209.5%+209.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r174_r151_bugfix.py
Experimento: R174: R151-A re-validated under bug-fixed engine
Origen: outputs/round_174_r151_bugfix/metadata.json · → ver detalle de la ronda
R182 Half-Kelly fixed (size=0.5 always) 76,873% +178.4 4/4 94 sh 54.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)482.3%+425.6%104%
F1 Bull (2019-21)732.8%+634.8%1162%
F2 Recovery (2022-24)412.8%+178.4%234%
F3 Lateral (2024-25)209.5%+203.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=54.02777777777777%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + ADAPTIVE Kelly sizing based on rolling short WR (last N shorts). 4 schedules + half-Kelly fixed tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r182_adaptive_kelly.py
Experimento: R182: R151-A with adaptive Kelly sizing based on rolling short WR
Origen: outputs/round_182_adaptive_kelly/metadata.json · → ver detalle de la ronda
R182 Adaptive Kelly (WR last 10, kelly schedule) 72,736% +154.6 4/4 94 sh 54.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)498.7%+442.0%104%
F1 Bull (2019-21)695.8%+597.8%1162%
F2 Recovery (2022-24)389.0%+154.6%234%
F3 Lateral (2024-25)212.6%+206.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=54.02777777777777%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + ADAPTIVE Kelly sizing based on rolling short WR (last N shorts). 4 schedules + half-Kelly fixed tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r182_adaptive_kelly.py
Experimento: R182: R151-A with adaptive Kelly sizing based on rolling short WR
Origen: outputs/round_182_adaptive_kelly/metadata.json · → ver detalle de la ronda
R182 Adaptive Kelly (WR last 20, kelly schedule) 72,044% +159.7 4/4 94 sh 54.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)503.3%+446.6%104%
F1 Bull (2019-21)695.8%+597.8%1162%
F2 Recovery (2022-24)394.1%+159.7%234%
F3 Lateral (2024-25)204.1%+198.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=54.02777777777777%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + ADAPTIVE Kelly sizing based on rolling short WR (last N shorts). 4 schedules + half-Kelly fixed tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r182_adaptive_kelly.py
Experimento: R182: R151-A with adaptive Kelly sizing based on rolling short WR
Origen: outputs/round_182_adaptive_kelly/metadata.json · → ver detalle de la ronda
R110 R110 local reproduction 70,576% +239.2 —/4

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+378.4%104%
F1 Bull (2019-21)537.3%+439.3%1162%
F2 Recovery (2022-24)473.6%+239.2%234%
F3 Lateral (2024-25)261.3%+255.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

expected_compound
70576
expected_min_alpha
245
reproduces
True

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r110_local.py
Experimento: R110 local reproduction
Origen: outputs/round_110_repro/metadata.json · → ver detalle de la ronda
R136 R110 local reproductionBUGGY-ENGINE 70,576% +239.2 —/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+378.4%104%
F1 Bull (2019-21)537.3%+439.3%1162%
F2 Recovery (2022-24)473.6%+239.2%234%
F3 Lateral (2024-25)261.3%+255.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

expected_compound
70576
expected_min_alpha
245
reproduces
True

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Experimento: R110 local reproduction
Origen: outputs/round_136/metadata.json · → ver detalle de la ronda
R146 canonical (10% fixed)BUGGY-ENGINE 70,576% +239.2 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
27.672150676086755

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r146_atr_stops.py
Experimento: R146: ATR-adaptive initial SL on canonical V66
Origen: outputs/round_146_atr_stops/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 70,576% +239.2 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.0
trades_total
300
skip_pct
0.0
avg_mdd
27.672150676086755

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R150 canonical (no breaker)BUGGY-ENGINE 70,576% +239.2 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
27.672150676086755
circuit_triggers
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R151 no shorts (V66 canonical)BUGGY-ENGINE 70,576% +239.2 4/4 0.0%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 longs (canonical) + SHORT module: cuando V66 está en cash, si P(SL)>0.65 (3/5 seeds), abre short. Cierra en P(TP)>0.35, stop 8%, o 40h timeout.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r151_shorts_in_gaps.py
Experimento: R151: V66 long + SHORT during cash gaps
Origen: outputs/round_151_shorts_gaps/metadata.json · → ver detalle de la ronda
R151 short P(SL)>0.80, exit P(TP)>0.20, sl=15%, max=40hBUGGY-ENGINE 70,576% +239.2 4/4 0.0%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 longs (canonical) + SHORT module: cuando V66 está en cash, si P(SL)>0.65 (3/5 seeds), abre short. Cierra en P(TP)>0.35, stop 8%, o 40h timeout.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r151_shorts_in_gaps.py
Experimento: R151: V66 long + SHORT during cash gaps
Origen: outputs/round_151_shorts_gaps/metadata.json · → ver detalle de la ronda
R156 R151-A (canonical R069 for shorts) [baseline]BUGGY-ENGINE 70,576% +239.2 4/4 0.0%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier asymmetric: k_up=7, k_dn=10 → favors P(SL) responsiveness
Entrada / salida
Dual-model: V66 longs use canonical GRU; shorts use R155 short-specific model
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r156_dual_model.py
Experimento: R156: V66 canonical longs + R155 short-trained shorts
Origen: outputs/round_156_dual_model/metadata.json · → ver detalle de la ronda
R156 R155 P(SL)>0.65, exit P(TP)>0.35, sl=8%BUGGY-ENGINE 70,576% +239.2 4/4 0.0%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier asymmetric: k_up=7, k_dn=10 → favors P(SL) responsiveness
Entrada / salida
Dual-model: V66 longs use canonical GRU; shorts use R155 short-specific model
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r156_dual_model.py
Experimento: R156: V66 canonical longs + R155 short-trained shorts
Origen: outputs/round_156_dual_model/metadata.json · → ver detalle de la ronda
R162 canonical V66 (full notional)BUGGY-ENGINE 70,576% +239.2 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r162_r134_size_multiplier.py
Experimento: R162: R134 P(v66_zone) as position size multiplier
Origen: outputs/round_162_r134_size_mult/metadata.json · → ver detalle de la ronda
R156 R155 P(SL)>0.60, exit P(TP)>0.30, sl=8%BUGGY-ENGINE 70,209% +239.2 4/4 11 sh 54.5%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)432.3%+328.3%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=11 · WR=54.54545454545454%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier asymmetric: k_up=7, k_dn=10 → favors P(SL) responsiveness
Entrada / salida
Dual-model: V66 longs use canonical GRU; shorts use R155 short-specific model
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r156_dual_model.py
Experimento: R156: V66 canonical longs + R155 short-trained shorts
Origen: outputs/round_156_dual_model/metadata.json · → ver detalle de la ronda
R182 Adaptive Kelly (WR last 5, kelly schedule) 62,842% +157.9 4/4 94 sh 54.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)407.6%+350.9%104%
F1 Bull (2019-21)734.2%+636.2%1162%
F2 Recovery (2022-24)392.3%+157.9%234%
F3 Lateral (2024-25)201.9%+196.1%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=94 · WR=54.02777777777777%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A under bug-fixed engine + ADAPTIVE Kelly sizing based on rolling short WR (last N shorts). 4 schedules + half-Kelly fixed tested.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r182_adaptive_kelly.py
Experimento: R182: R151-A with adaptive Kelly sizing based on rolling short WR
Origen: outputs/round_182_adaptive_kelly/metadata.json · → ver detalle de la ronda
R174 R151-B more conservative (bugfix) 54,068% +125.3 4/4 46 sh

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)182.0%+78.0%104%
F1 Bull (2019-21)616.7%-545.3%1162%
F2 Recovery (2022-24)568.3%+334.3%234%
F3 Lateral (2024-25)301.1%+301.1%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=46 · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r174_r151_bugfix.py
Experimento: R174: R151-A re-validated under bug-fixed engine
Origen: outputs/round_174_r151_bugfix/metadata.json · → ver detalle de la ronda
R150 DD 30% / pause 30dBUGGY-ENGINE 53,423% +239.2 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)382.6%-779.4%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
25.739174428102647
circuit_triggers
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R156 R155 P(SL)>0.55, exit P(TP)>0.35, sl=8%BUGGY-ENGINE 52,673% +239.2 4/4 185 sh 48.7%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)301.7%+197.7%104%
F1 Bull (2019-21)534.0%-628.0%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=185 · WR=48.728813559322035%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier asymmetric: k_up=7, k_dn=10 → favors P(SL) responsiveness
Entrada / salida
Dual-model: V66 longs use canonical GRU; shorts use R155 short-specific model
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r156_dual_model.py
Experimento: R156: V66 canonical longs + R155 short-trained shorts
Origen: outputs/round_156_dual_model/metadata.json · → ver detalle de la ronda
R151 short P(SL)>0.75, exit P(TP)>0.25, sl=12%, max=40hBUGGY-ENGINE 52,487% +199.3 4/4 9 sh 68.8%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)256.0%+152.0%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)541.5%+307.5%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=9 · WR=68.75%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 longs (canonical) + SHORT module: cuando V66 está en cash, si P(SL)>0.65 (3/5 seeds), abre short. Cierra en P(TP)>0.35, stop 8%, o 40h timeout.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r151_shorts_in_gaps.py
Experimento: R151: V66 long + SHORT during cash gaps
Origen: outputs/round_151_shorts_gaps/metadata.json · → ver detalle de la ronda
R146 ATR 2.5x floor 7%BUGGY-ENGINE 48,939% +230.4 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)325.5%+221.5%104%
F1 Bull (2019-21)505.8%-656.2%1162%
F2 Recovery (2022-24)464.8%+230.8%234%
F3 Lateral (2024-25)236.8%+236.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
32.082204389008545

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r146_atr_stops.py
Experimento: R146: ATR-adaptive initial SL on canonical V66
Origen: outputs/round_146_atr_stops/metadata.json · → ver detalle de la ronda
R156 R155 P(SL)>0.50, exit P(TP)>0.40, sl=8%BUGGY-ENGINE 43,030% +168.3 4/4 487 sh 36.6%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)225.0%+121.0%104%
F1 Bull (2019-21)545.0%-617.0%1162%
F2 Recovery (2022-24)469.4%+235.4%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=487 · WR=36.56055341659624%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier asymmetric: k_up=7, k_dn=10 → favors P(SL) responsiveness
Entrada / salida
Dual-model: V66 longs use canonical GRU; shorts use R155 short-specific model
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r156_dual_model.py
Experimento: R156: V66 canonical longs + R155 short-trained shorts
Origen: outputs/round_156_dual_model/metadata.json · → ver detalle de la ronda
R156 R155 P(SL)>0.50, exit P(TP)>0.40, sl=10%BUGGY-ENGINE 43,030% +168.3 4/4 487 sh 36.6%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)225.0%+121.0%104%
F1 Bull (2019-21)545.0%-617.0%1162%
F2 Recovery (2022-24)469.4%+235.4%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=487 · WR=36.56055341659624%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier asymmetric: k_up=7, k_dn=10 → favors P(SL) responsiveness
Entrada / salida
Dual-model: V66 longs use canonical GRU; shorts use R155 short-specific model
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r156_dual_model.py
Experimento: R156: V66 canonical longs + R155 short-trained shorts
Origen: outputs/round_156_dual_model/metadata.json · → ver detalle de la ronda
R173 V66 canonical (no pyramid) — bugfix enginePROD V6 42,636% +192.8 4/4 302 56.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.0%+171.0%104%
F1 Bull (2019-21)525.2%-636.8%1162%
F2 Recovery (2022-24)427.2%+193.2%234%
F3 Lateral (2024-25)245.8%+245.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=302 · WR=55.960264900662246%

Métricas y config crudas (metadata.json)

pyramid_adds
0
pyramid_blocked
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 canonical UNDER BUG-FIXED ENGINE: detect@close[i] → execute@open[i+1]. Pyramid disabled. Cap properly tracked. THIS IS THE HONEST V66 BASELINE.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r173_bugfix.py
Experimento: R173: bug-fixed engine for V66 + pyramid
Origen: outputs/round_173_bugfix/metadata.json · → ver detalle de la ronda
R173 R170-B (0.12/0.65/1.75x/24h) — bugfix engine 42,636% +192.8 4/4 302 56.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.0%+171.0%104%
F1 Bull (2019-21)525.2%-636.8%1162%
F2 Recovery (2022-24)427.2%+193.2%234%
F3 Lateral (2024-25)245.8%+245.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=302 · WR=55.960264900662246%

Métricas y config crudas (metadata.json)

pyramid_adds
0
pyramid_blocked
517

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 canonical UNDER BUG-FIXED ENGINE: detect@close[i] → execute@open[i+1]. Pyramid disabled. Cap properly tracked. THIS IS THE HONEST V66 BASELINE.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r173_bugfix.py
Experimento: R173: bug-fixed engine for V66 + pyramid
Origen: outputs/round_173_bugfix/metadata.json · → ver detalle de la ronda
R173 R163 baseline (0.10/0.50/1.5x/24h) — bugfix engine 42,636% +192.8 4/4 302 56.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.0%+171.0%104%
F1 Bull (2019-21)525.2%-636.8%1162%
F2 Recovery (2022-24)427.2%+193.2%234%
F3 Lateral (2024-25)245.8%+245.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=302 · WR=55.960264900662246%

Métricas y config crudas (metadata.json)

pyramid_adds
0
pyramid_blocked
583

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 canonical UNDER BUG-FIXED ENGINE: detect@close[i] → execute@open[i+1]. Pyramid disabled. Cap properly tracked. THIS IS THE HONEST V66 BASELINE.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r173_bugfix.py
Experimento: R173: bug-fixed engine for V66 + pyramid
Origen: outputs/round_173_bugfix/metadata.json · → ver detalle de la ronda
R173 More conservative (0.10/0.30/1.3x/24h) — bugfix 42,636% +192.8 4/4 302 56.0%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.0%+171.0%104%
F1 Bull (2019-21)525.2%-636.8%1162%
F2 Recovery (2022-24)427.2%+193.2%234%
F3 Lateral (2024-25)245.8%+245.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=302 · WR=55.960264900662246%

Métricas y config crudas (metadata.json)

pyramid_adds
0
pyramid_blocked
388

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 canonical UNDER BUG-FIXED ENGINE: detect@close[i] → execute@open[i+1]. Pyramid disabled. Cap properly tracked. THIS IS THE HONEST V66 BASELINE.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r173_bugfix.py
Experimento: R173: bug-fixed engine for V66 + pyramid
Origen: outputs/round_173_bugfix/metadata.json · → ver detalle de la ronda
R174 V66 alone (bugfix engine) 42,636% +192.8 4/4

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.0%+171.0%104%
F1 Bull (2019-21)525.2%-636.8%1162%
F2 Recovery (2022-24)427.2%+193.2%234%
F3 Lateral (2024-25)245.8%+245.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r174_r151_bugfix.py
Experimento: R174: R151-A re-validated under bug-fixed engine
Origen: outputs/round_174_r151_bugfix/metadata.json · → ver detalle de la ronda
R099 hybrid_v5 (GRU 3-Regime V5.4 Robust-5) — V4 botPROD V4BUGGY-ENGINE 30,174% +117.0 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

deployment_status
Active on V4 (hybrid_v5 (GRU 3-Regime V5.4 Robust-5))
synthetic_source
SESSION_STATE.md + ROUNDS_LOG.md (canonical round metadat...
note
GRU + 3-regime adaptive: thresholds distintos para bull/l...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Experimento: Production strategy on V4 bot. GRU + 3-regime adaptive: thresholds distintos para bull/lateral/bear detectado vía slope diario. Verificación R099 con production SMATrader. Pre-audit, +117 min α (mucho más bajo que V5/V6 honest).
Origen: synthetic from SESSION_STATE.md (canonical round R99) · → ver detalle de la ronda
R146 ATR 3x floor 5%BUGGY-ENGINE 29,029% +195.1 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)293.8%+189.8%104%
F1 Bull (2019-21)293.1%-868.9%1162%
F2 Recovery (2022-24)474.4%+240.4%234%
F3 Lateral (2024-25)227.7%+227.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
29.14433857637885

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r146_atr_stops.py
Experimento: R146: ATR-adaptive initial SL on canonical V66
Origen: outputs/round_146_atr_stops/metadata.json · → ver detalle de la ronda
R146 ATR 2x floor 5%BUGGY-ENGINE 28,065% +200.8 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.3%+171.3%104%
F1 Bull (2019-21)298.8%-863.2%1162%
F2 Recovery (2022-24)474.4%+240.4%234%
F3 Lateral (2024-25)227.7%+227.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
30.555060552317062

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r146_atr_stops.py
Experimento: R146: ATR-adaptive initial SL on canonical V66
Origen: outputs/round_146_atr_stops/metadata.json · → ver detalle de la ronda
R146 ATR 2x capped 5-15%BUGGY-ENGINE 28,065% +200.8 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)275.3%+171.3%104%
F1 Bull (2019-21)298.8%-863.2%1162%
F2 Recovery (2022-24)474.4%+240.4%234%
F3 Lateral (2024-25)227.7%+227.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
30.555060552317062

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r146_atr_stops.py
Experimento: R146: ATR-adaptive initial SL on canonical V66
Origen: outputs/round_146_atr_stops/metadata.json · → ver detalle de la ronda
R150 DD 25% / pause 30dBUGGY-ENGINE 25,534% +189.7 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)246.4%+142.4%104%
F1 Bull (2019-21)312.6%-849.4%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)212.7%+212.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
24.18901680121595
circuit_triggers
6

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R150 DD 20% / pause 15dBUGGY-ENGINE 20,674% +73.9 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)295.1%+191.1%104%
F1 Bull (2019-21)171.9%-990.1%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)237.0%+237.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
20.213634826794753
circuit_triggers
14

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R150 DD 20% / pause 60dBUGGY-ENGINE 15,747% +113.5 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)204.2%+100.2%104%
F1 Bull (2019-21)211.5%-950.5%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)191.5%+191.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
19.974562037134554
circuit_triggers
8

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R146 ATR 1.5x capped 4-12%BUGGY-ENGINE 14,737% +69.0 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)237.2%+133.2%104%
F1 Bull (2019-21)167.0%-995.0%1162%
F2 Recovery (2022-24)417.3%+183.3%234%
F3 Lateral (2024-25)218.6%+218.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
32.219972142219945

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r146_atr_stops.py
Experimento: R146: ATR-adaptive initial SL on canonical V66
Origen: outputs/round_146_atr_stops/metadata.json · → ver detalle de la ronda
R150 DD 20% / pause 30dBUGGY-ENGINE 12,491% +70.8 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)169.8%+65.8%104%
F1 Bull (2019-21)168.8%-993.2%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)202.7%+202.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
20.29053530619941
circuit_triggers
11

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R081 GRU Ensemble (always-invested) — V2 botPROD V2BUGGY-ENGINE 7,641% 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

deployment_status
Active on V2 (GRU Ensemble (always-invested))
synthetic_source
SESSION_STATE.md + ROUNDS_LOG.md (canonical round metadat...
note
Earliest deployment. Baseline GRU 2x128 5-seed ensemble s...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Experimento: Production strategy on V2 bot. Earliest deployment. Baseline GRU 2x128 5-seed ensemble sin cascade refinements (no V66 cooldown, no trail ratchet, no peak_drop). Always-invested con ensemble voting (3/5 seeds para entry/exit).
Origen: synthetic from SESSION_STATE.md (canonical round R81) · → ver detalle de la ronda
R071 hybrid_v3 (GRU + DailyRSI>80 + Trail 10%) — V3 botPROD V3BUGGY-ENGINE 7,128% 4/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

deployment_status
Active on V3 (hybrid_v3 (GRU + DailyRSI>80 + Trail 10%))
synthetic_source
SESSION_STATE.md + ROUNDS_LOG.md (canonical round metadat...
note
GRU + reglas hardcoded: salir si DailyRSI > 80 (overbough...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Experimento: Production strategy on V3 bot. GRU + reglas hardcoded: salir si DailyRSI > 80 (overbought) o trail-stop 10% del peak. Validado en R071 con +7,128% compound y 4/4 folds BH. Una de las primeras estrategias hybrid GRU+TA. NO ha sido re-validada bajo honest engine.
Origen: synthetic from SESSION_STATE.md (canonical round R71) · → ver detalle de la ronda
R150 DD 15% / pause 30dBUGGY-ENGINE 6,938% -29.8 3/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)168.7%+64.7%104%
F1 Bull (2019-21)68.2%-1,093.8%1162%
F2 Recovery (2022-24)349.7%+115.7%234%
F3 Lateral (2024-25)246.4%+246.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

avg_mdd
17.41430641438786
circuit_triggers
21

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r150_maxdd_circuit.py
Experimento: R150: Max-DD circuit breaker on V66
Origen: outputs/round_150_maxdd/metadata.json · → ver detalle de la ronda
R162 R134 size: hard 25/50/75/100BUGGY-ENGINE 6,278% -90.4 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)65.8%-1,096.2%1162%
F2 Recovery (2022-24)144.0%-90.0%234%
F3 Lateral (2024-25)194.6%+194.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r162_r134_size_multiplier.py
Experimento: R162: R134 P(v66_zone) as position size multiplier
Origen: outputs/round_162_r134_size_mult/metadata.json · → ver detalle de la ronda
R162 R134 size: soft (linear P)BUGGY-ENGINE 4,388% -116.6 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)62.8%-1,099.2%1162%
F2 Recovery (2022-24)117.8%-116.2%234%
F3 Lateral (2024-25)136.5%+136.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r162_r134_size_multiplier.py
Experimento: R162: R134 P(v66_zone) as position size multiplier
Origen: outputs/round_162_r134_size_mult/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 3,810% -111.6 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)-9.0%-1,171.0%1162%
F2 Recovery (2022-24)122.8%-111.2%234%
F3 Lateral (2024-25)260.4%+260.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.2
trades_total
182
skip_pct
94.4206008583691
avg_mdd
22.90006047409818

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 3,681% -115.8 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)-17.8%-1,179.8%1162%
F2 Recovery (2022-24)140.0%-94.0%234%
F3 Lateral (2024-25)258.1%+258.1%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.1
trades_total
207
skip_pct
92.28187919463086
avg_mdd
25.836237270527242

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R162 R134 size: aggressive 10/30/60/100BUGGY-ENGINE 3,415% -133.6 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)20.8%-1,141.2%1162%
F2 Recovery (2022-24)100.8%-133.2%234%
F3 Lateral (2024-25)170.8%+170.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r162_r134_size_multiplier.py
Experimento: R162: R134 P(v66_zone) as position size multiplier
Origen: outputs/round_162_r134_size_mult/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 2,921% -147.1 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)-12.0%-1,174.0%1162%
F2 Recovery (2022-24)87.3%-146.7%234%
F3 Lateral (2024-25)242.5%+242.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.3
trades_total
167
skip_pct
95.26241134751773
avg_mdd
23.11876349394448

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 2,360% -158.2 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)2.7%-1,159.3%1162%
F2 Recovery (2022-24)76.2%-157.8%234%
F3 Lateral (2024-25)154.2%+154.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.7
trades_total
121
skip_pct
97.26182394206833
avg_mdd
19.861826425315833

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R158 R151-A (canonical R069 for shorts) [baseline]BUGGY-ENGINE 1,772% -290.9 3/4 398 sh 51.2%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)483.0%+379.0%104%
F1 Bull (2019-21)229.0%-933.0%1162%
F2 Recovery (2022-24)-56.5%-290.5%234%
F3 Lateral (2024-25)124.4%+124.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=398 · WR=51.2232321592815%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier k_up=15, k_dn=5 (longer up barrier, much tighter down)
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r158_dual_r157.py
Experimento: R158: V66 canonical longs + R157 short-trained shorts
Origen: outputs/round_158_dual_model/metadata.json · → ver detalle de la ronda
R158 R157 P(SL)>0.65, exit P(TP)>0.35, sl=8%BUGGY-ENGINE 1,772% -290.9 3/4 398 sh 51.2%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)483.0%+379.0%104%
F1 Bull (2019-21)229.0%-933.0%1162%
F2 Recovery (2022-24)-56.5%-290.5%234%
F3 Lateral (2024-25)124.4%+124.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=398 · WR=51.2232321592815%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier k_up=15, k_dn=5 (longer up barrier, much tighter down)
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r158_dual_r157.py
Experimento: R158: V66 canonical longs + R157 short-trained shorts
Origen: outputs/round_158_dual_model/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 1,576% -179.8 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)-12.0%-1,174.0%1162%
F2 Recovery (2022-24)54.6%-179.4%234%
F3 Lateral (2024-25)130.3%+130.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.4
trades_total
156
skip_pct
95.97419354838709
avg_mdd
25.50800531681281

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R148 (unnamed)BUGGY-ENGINE 1,331% -169.8 2/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)-14.3%-1,176.3%1162%
F2 Recovery (2022-24)64.6%-169.4%234%
F3 Lateral (2024-25)89.6%+89.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

tau
0.5
trades_total
146
skip_pct
96.44509374239104
avg_mdd
24.630217400457944

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r148_meta_label.py
Experimento: R148: meta-labeling V66 + R134 P(v66_zone) filter
Origen: outputs/round_148_metalabel/metadata.json · → ver detalle de la ronda
R176 R176: V66 backtest with R175 Transformer checkpoints (bug-fi 92% -223.9 0/4 243

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)-21.2%104%
F1 Bull (2019-21)-68.9%1162%
F2 Recovery (2022-24)-223.9%234%
F3 Lateral (2024-25)-6.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=243 · WR=—

Métricas y config crudas (metadata.json)

folds_trades
[51, 136, 49, 7]
total_wins
114
v66_bugfix_baseline
{"compound": 42636, "min_alpha": 193}
beats_v66
False
elapsed_min
42.88139955202738

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
Transformer encoder 4 layers × d_model=64 × 8 heads × FFN=128 (155K params). Inputs same as GRU, output 3-class. NEW arch.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam 1e-4, GELU, 5 seeds, same data + events + labeling as default.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Transformer outputs fed into V66 cascade. FAILED: distribution mismatch (P(TP) p50=0.18 vs GRU 0.30) breaks thresholds.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r176_transformer_eval.py
Experimento: R176: V66 backtest with R175 Transformer checkpoints (bug-fixed engine)
Origen: outputs/round_176_transformer_eval/metadata.json · → ver detalle de la ronda
R158 R157 P(SL)>0.60, exit P(TP)>0.30, sl=8%BUGGY-ENGINE -12% -307.2 2/4 1,540 sh 45.8%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)58.2%-45.8%104%
F1 Bull (2019-21)13.7%-1,148.3%1162%
F2 Recovery (2022-24)-72.8%-306.8%234%
F3 Lateral (2024-25)80.7%+80.7%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=1540 · WR=45.845186538028486%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier k_up=15, k_dn=5 (longer up barrier, much tighter down)
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r158_dual_r157.py
Experimento: R158: V66 canonical longs + R157 short-trained shorts
Origen: outputs/round_158_dual_model/metadata.json · → ver detalle de la ronda
R169 R169: V66 backtest with R168 MTF-trained checkpointsBUGGY-ENGINE -56% -222.2 0/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)-61.7%104%
F1 Bull (2019-21)-139.7%1162%
F2 Recovery (2022-24)-222.2%234%
F3 Lateral (2024-25)-34.9%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

folds_trades
[1, 85, 41, 46]
r136_baseline
{"compound": 70576, "min_alpha": 245, "folds_alpha": [378...
improves_vs_r136
False
verdict
FAIL — MTF doesn't help
elapsed_min
7.2285001397132875

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r169_mtf_eval.py
Experimento: R169: V66 backtest with R168 MTF-trained checkpoints
Origen: outputs/round_169_mtf_eval/metadata.json · → ver detalle de la ronda
R158 R157 P(SL)>0.55, exit P(TP)>0.35, sl=8%BUGGY-ENGINE -96% -303.8 1/4 900 sh 47.5%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)-57.3%-161.3%104%
F1 Bull (2019-21)-86.4%-1,248.4%1162%
F2 Recovery (2022-24)-69.4%-303.4%234%
F3 Lateral (2024-25)116.9%+116.9%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=900 · WR=47.514101503072084%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier k_up=15, k_dn=5 (longer up barrier, much tighter down)
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r158_dual_r157.py
Experimento: R158: V66 canonical longs + R157 short-trained shorts
Origen: outputs/round_158_dual_model/metadata.json · → ver detalle de la ronda
R158 R157 P(SL)>0.50, exit P(TP)>0.40, sl=8%BUGGY-ENGINE -99% -305.4 0/4 667 sh 44.5%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)-76.5%-180.5%104%
F1 Bull (2019-21)-83.0%-1,245.0%1162%
F2 Recovery (2022-24)-71.0%-305.0%234%
F3 Lateral (2024-25)-29.2%-29.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=667 · WR=44.51303463530242%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier k_up=15, k_dn=5 (longer up barrier, much tighter down)
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r158_dual_r157.py
Experimento: R158: V66 canonical longs + R157 short-trained shorts
Origen: outputs/round_158_dual_model/metadata.json · → ver detalle de la ronda
R158 R157 P(SL)>0.50, exit P(TP)>0.40, sl=10%BUGGY-ENGINE -100% -311.6 0/4 638 sh 44.6%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)-78.7%-182.7%104%
F1 Bull (2019-21)-82.3%-1,244.3%1162%
F2 Recovery (2022-24)-77.2%-311.2%234%
F3 Lateral (2024-25)-42.0%-42.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=638 · WR=44.618133638296385%

Métricas y config crudas (metadata.json)

No extra config

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2x128 5-seed RE-TRAINED with short-specific tb3 labeling (k_up=7, k_dn=10) — asymmetric for catching drops faster.
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier k_up=15, k_dn=5 (longer up barrier, much tighter down)
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r158_dual_r157.py
Experimento: R158: V66 canonical longs + R157 short-trained shorts
Origen: outputs/round_158_dual_model/metadata.json · → ver detalle de la ronda
R135 Production-grade bar-by-bar portfolio simulatorBUGGY-ENGINE -227.7 —/4
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

round
135
method
V66 GRU 5-seed inference + uniform-exit + cooldown logic,...
completed_at
2026-05-26T13:19:04.568384+00:00
elapsed_min
1.42
v66_compound
43.51348400339998
macd_compound
-89.1549372176
portfolio_compound
-60.1537811512
fold_summary
[{"fold": 0, "fold_name": "F0_Bear", "n_v66_trades": 30, ...
portfolio_results
[{"fold": 0, "fold_name": "F0_Bear", "method": "fixed 25/...

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r135.py
Experimento: Production-grade bar-by-bar portfolio simulator
Origen: outputs/round_135/metadata.json · → ver detalle de la ronda
R159 V66 canonicalOOTBUGGY-ENGINE 1/4 +11.4%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.554368963751494
alpha
11.43278473470329

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r159_oot_2026.py
Experimento: R159: 2026 OOT validation
Origen: outputs/round_159_oot_2026/metadata.json · → ver detalle de la ronda
R159 R151-AOOTBUGGY-ENGINE 1/4 2 sh +13.8%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-5.227596461050816
alpha
13.759557237403968

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r159_oot_2026.py
Experimento: R159: 2026 OOT validation
Origen: outputs/round_159_oot_2026/metadata.json · → ver detalle de la ronda
R159 R151-BOOTBUGGY-ENGINE 1/4 +11.4%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.554368963751494
alpha
11.43278473470329

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r159_oot_2026.py
Experimento: R159: 2026 OOT validation
Origen: outputs/round_159_oot_2026/metadata.json · → ver detalle de la ronda
R159 R154OOTBUGGY-ENGINE 1/4 2 sh +13.8%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-5.227596461050816
alpha
13.759557237403968
shorts_skipped
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r159_oot_2026.py
Experimento: R159: 2026 OOT validation
Origen: outputs/round_159_oot_2026/metadata.json · → ver detalle de la ronda
R165 V66 canonicalOOTBUGGY-ENGINE 1/4 +11.4%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.55436896375144
alpha
11.432784734703343

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r165_oot_pyramid.py
Experimento: R165: 2026 OOT for R163 pyramid variants + comparisons
Origen: outputs/round_165_oot_pyramid/metadata.json · → ver detalle de la ronda
R165 R163 pyramidOOTBUGGY-ENGINE 1/4 +60.3%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
41.30449568804348
alpha
60.291649386498264
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r165_oot_pyramid.py
Experimento: R165: 2026 OOT for R163 pyramid variants + comparisons
Origen: outputs/round_165_oot_pyramid/metadata.json · → ver detalle de la ronda
R165 R163 +5%/+30%/1.3x/12hOOTBUGGY-ENGINE 1/4 +41.1%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
22.099480702744838
alpha
41.08663440119962
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r165_oot_pyramid.py
Experimento: R165: 2026 OOT for R163 pyramid variants + comparisons
Origen: outputs/round_165_oot_pyramid/metadata.json · → ver detalle de la ronda
R165 R163 +15%/+50%/1.5x/48hOOTBUGGY-ENGINE 1/4 +11.4%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.55436896375144
alpha
11.432784734703343
pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r165_oot_pyramid.py
Experimento: R165: 2026 OOT for R163 pyramid variants + comparisons
Origen: outputs/round_165_oot_pyramid/metadata.json · → ver detalle de la ronda
R165 R163 +20%/+100%/2.0x/48hOOTBUGGY-ENGINE 1/4 +11.4%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.55436896375144
alpha
11.432784734703343
pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r165_oot_pyramid.py
Experimento: R165: 2026 OOT for R163 pyramid variants + comparisons
Origen: outputs/round_165_oot_pyramid/metadata.json · → ver detalle de la ronda
R165 R151-A shortsOOTBUGGY-ENGINE 1/4 2 sh +13.8%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-5.227596461050816
alpha
13.759557237403968

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r165_oot_pyramid.py
Experimento: R165: 2026 OOT for R163 pyramid variants + comparisons
Origen: outputs/round_165_oot_pyramid/metadata.json · → ver detalle de la ronda
R171 V66 canonicalOOTBUGGY-ENGINE —/4 +11.4%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.55436896375144
alpha
11.432784734703343
pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R171 R163 baseline (0.10/0.50/1.5x/24h)OOTBUGGY-ENGINE —/4 +60.3%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
41.30449568804348
alpha
60.291649386498264
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R171 R170-A (0.05/0.50/1.5x/24h) ★OOTBUGGY-ENGINE —/4 +60.9%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
41.90008113313115
alpha
60.887234831585936
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R171 R170-B (0.12/0.65/1.75x/24h)OOTBUGGY-ENGINE —/4 +71.9%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
52.95842635339719
alpha
71.94558005185198
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R171 R170-C (0.10/0.50/1.75x/24h)OOTBUGGY-ENGINE —/4 +60.3%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
41.30449568804348
alpha
60.291649386498264
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R171 R170-D (0.10/0.25/1.5x/24h)OOTBUGGY-ENGINE —/4 +59.1%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
40.11172246397922
alpha
59.098876162434
pyramid_adds
2

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R171 R170-E (0.08/0.50/1.5x/24h)OOTBUGGY-ENGINE —/4 +60.9%
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
41.90794090857351
alpha
60.89509460702829
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 cascade: entry on regime-specific thresholds (bull/lateral/bear via 20d slope) → exit en cascada (init_sl 10% OR trail ratchet 22→18→5% según unrealized OR DRSI>78 OR 3/5 GRUs danger (P(SL)>0.70 o P(TP)<exit_th) OR peak_drop del avg_tp_bar desde su pico) → cooldown 4 bars post-cualquier-exit + 48 adicionales si fue loss
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r171_oot_new_champ.py
Experimento: R171: OOT 2026 for R170 sweep winners
Origen: outputs/round_171_oot_new_champ/metadata.json · → ver detalle de la ronda
R172 R172: R170-B with full instrumentation per foldBUGGY-ENGINE +415.5 4/4 301
⚠️ BUGGY-ENGINE — Esta ronda es pre-R173 (engine con bug intra-bar lookahead). El compound está inflado vs realidad de producción. Para R151-A, la versión bug-fixed honesta es R174 (+113,981%). Por eso los buggy aparecen arriba pero los candidatos reales son los R173+.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=301 · WR=—

Métricas y config crudas (metadata.json)

config
{"trigger": 0.12, "add_size": 0.65, "max_lev": 1.75, "min...
compound_total
257753.52085323367
simple_sum_total
759.4234047223401
total_wins
166
avg_wr_unweighted
55.42761418999043
elapsed_min
5.9215695063273115

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
(Instrumented re-run of R170-B for audit. Per-trade logs revealed phantom adds → trigger for R173.)
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r172_instrumented.py
Experimento: R172: R170-B with full instrumentation per fold
Origen: outputs/round_172_instrumented/metadata.json · → ver detalle de la ronda
R177 V66 alone bugfixOOT 1/4 10 +12.4%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=10 · WR=—

Métricas y config crudas (metadata.json)

pnl
-6.620420847287624
alpha
12.366732851167159

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
OOT 2026: full hold-out (2026-01-01 to 2026-03-23). NO training on this period.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r177_oot_r151_bugfix.py
Experimento: R177: OOT 2026 R151-A under bug-fixed engine
Origen: outputs/round_177_oot_r151_bugfix/metadata.json · → ver detalle de la ronda
R177 R151-A shorts full notional (bugfix)OOT 1/4 2 sh +15.3%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-3.685996882913823
alpha
15.30115681554096

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
OOT 2026: full hold-out (2026-01-01 to 2026-03-23). NO training on this period.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r177_oot_r151_bugfix.py
Experimento: R177: OOT 2026 R151-A under bug-fixed engine
Origen: outputs/round_177_oot_r151_bugfix/metadata.json · → ver detalle de la ronda
R177 R151-A half-Kelly (bugfix)OOT 1/4 2 sh +11.5%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.50420184892284
alpha
11.482951849531943

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
OOT 2026: full hold-out (2026-01-01 to 2026-03-23). NO training on this period.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r177_oot_r151_bugfix.py
Experimento: R177: OOT 2026 R151-A under bug-fixed engine
Origen: outputs/round_177_oot_r151_bugfix/metadata.json · → ver detalle de la ronda
R177 R151-B conservative (bugfix)OOT 1/4 +12.4%

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-6.620420847287624
alpha
12.366732851167159

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R151-A (V66 longs + shorts in V66 cash gaps) under bug-fixed engine. Honest re-validation of R151 family.
Walk-forward
OOT 2026: full hold-out (2026-01-01 to 2026-03-23). NO training on this period.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r177_oot_r151_bugfix.py
Experimento: R177: OOT 2026 R151-A under bug-fixed engine
Origen: outputs/round_177_oot_r151_bugfix/metadata.json · → ver detalle de la ronda
R166 COMBINED R163 + R151-APHANTOM 454,068% +287.2 4/4 93 sh
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)1,321.5%+1,217.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)753.4%+519.4%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

pyramid_adds
2

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r166_combined.py
Experimento: R166: combined R163 pyramid + R151-A shorts (stacking test)
Origen: outputs/round_166_combined/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.50 · lev=1.75x · hold=24hPHANTOM 269,825% +372.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)764.5%-397.5%1162%
F2 Recovery (2022-24)740.9%+506.9%234%
F3 Lateral (2024-25)378.6%+378.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.5
max_lev
1.75
min_hold
24
total_adds
4

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.12 · add=0.65 · lev=1.75x · hold=24hPHANTOM 257,754% +415.5 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 83.5% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)748.4%+644.4%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)814.8%+580.8%234%
F3 Lateral (2024-25)421.3%+421.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.12
add_size
0.65
max_lev
1.75
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.25 · lev=1.50x · hold=24hPHANTOM 231,575% +371.1 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)673.2%+569.2%104%
F1 Bull (2019-21)650.7%-511.3%1162%
F2 Recovery (2022-24)736.9%+502.9%234%
F3 Lateral (2024-25)376.9%+376.9%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.25
max_lev
1.5
min_hold
24
total_adds
7

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.05 · add=0.50 · lev=1.50x · hold=24hPHANTOM 228,349% +430.4 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 81.3% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)685.2%+581.2%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)751.4%+517.4%234%
F3 Lateral (2024-25)436.2%+436.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.05
add_size
0.5
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.08 · add=0.40 · lev=1.50x · hold=24hPHANTOM 226,896% +346.6 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)635.1%+531.1%104%
F1 Bull (2019-21)761.8%-400.2%1162%
F2 Recovery (2022-24)692.1%+458.1%234%
F3 Lateral (2024-25)352.4%+352.4%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.08
add_size
0.4
max_lev
1.5
min_hold
24
total_adds
4

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R163 pyramid +20% / +100% / 2.0x / 48hPHANTOM 219,361% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)898.0%+794.0%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)501.5%+501.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

total_pyramid_adds
2

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 + PYRAMIDING longs: cuando price > entry*(1+trigger) (e.g., +10%), add size_frac of remaining cap; up to max_leverage. ⚠️ INTRA-BAR LOOKAHEAD BUG in entry sequencing — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r163_pyramiding.py
Experimento: R163: Pyramiding × always-invested V66
Origen: outputs/round_163_pyramiding/metadata.json · → ver detalle de la ronda
R166 R151-A shorts only (P(SL)>0.65)PHANTOM 212,591% +245.1 4/4 93 sh
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)880.5%+776.5%104%
F1 Bull (2019-21)852.5%-309.5%1162%
F2 Recovery (2022-24)479.5%+245.5%234%
F3 Lateral (2024-25)293.0%+293.0%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=93 · WR=—

Métricas y config crudas (metadata.json)

pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r166_combined.py
Experimento: R166: combined R163 pyramid + R151-A shorts (stacking test)
Origen: outputs/round_166_combined/metadata.json · → ver detalle de la ronda
R170 trig=0.08 · add=0.50 · lev=1.50x · hold=24hPHANTOM 204,690% +377.5 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)685.2%+581.2%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)746.7%+512.7%234%
F3 Lateral (2024-25)383.3%+383.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.08
add_size
0.5
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.08 · add=0.50 · lev=1.50x · hold=24hPHANTOM 204,690% +377.5 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)685.2%+581.2%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)746.7%+512.7%234%
F3 Lateral (2024-25)383.3%+383.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.08
add_size
0.5
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R163 pyramid +10% / +50% / 1.5x / 24hPHANTOM 198,893% +372.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)740.9%+506.9%234%
F3 Lateral (2024-25)378.6%+378.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

total_pyramid_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 + PYRAMIDING longs: cuando price > entry*(1+trigger) (e.g., +10%), add size_frac of remaining cap; up to max_leverage. ⚠️ INTRA-BAR LOOKAHEAD BUG in entry sequencing — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r163_pyramiding.py
Experimento: R163: Pyramiding × always-invested V66
Origen: outputs/round_163_pyramiding/metadata.json · → ver detalle de la ronda
R166 R163 pyramid only (+10/+50/1.5x/24h)PHANTOM 198,893% +372.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)740.9%+506.9%234%
F3 Lateral (2024-25)378.6%+378.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pyramid_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r166_combined.py
Experimento: R166: combined R163 pyramid + R151-A shorts (stacking test)
Origen: outputs/round_166_combined/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.50 · lev=1.50x · hold=24hPHANTOM 198,893% +372.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)740.9%+506.9%234%
F3 Lateral (2024-25)378.6%+378.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.5
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.50 · lev=1.50x · hold=12hPHANTOM 198,893% +372.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)740.9%+506.9%234%
F3 Lateral (2024-25)378.6%+378.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.5
max_lev
1.5
min_hold
12
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.50 · lev=1.50x · hold=48hPHANTOM 198,893% +372.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)740.9%+506.9%234%
F3 Lateral (2024-25)378.6%+378.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.5
max_lev
1.5
min_hold
48
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.12 · add=0.50 · lev=1.50x · hold=24hPHANTOM 196,935% +371.0 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 83.5% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)675.8%+571.8%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)735.9%+501.9%234%
F3 Lateral (2024-25)376.8%+376.8%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.12
add_size
0.5
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R163 pyramid +15% / +50% / 1.5x / 48hPHANTOM 191,642% +366.3 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)670.4%+566.4%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)727.3%+493.3%234%
F3 Lateral (2024-25)372.1%+372.1%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

total_pyramid_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 + PYRAMIDING longs: cuando price > entry*(1+trigger) (e.g., +10%), add size_frac of remaining cap; up to max_leverage. ⚠️ INTRA-BAR LOOKAHEAD BUG in entry sequencing — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r163_pyramiding.py
Experimento: R163: Pyramiding × always-invested V66
Origen: outputs/round_163_pyramiding/metadata.json · → ver detalle de la ronda
R170 trig=0.15 · add=0.50 · lev=1.50x · hold=24hPHANTOM 191,642% +366.3 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)670.4%+566.4%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)727.3%+493.3%234%
F3 Lateral (2024-25)372.1%+372.1%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.15
add_size
0.5
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.40 · lev=1.50x · hold=24hPHANTOM 163,654% +342.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)627.5%+523.5%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)687.3%+453.3%234%
F3 Lateral (2024-25)348.6%+348.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.4
max_lev
1.5
min_hold
24
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.15 · add=0.40 · lev=1.50x · hold=48hPHANTOM 158,495% +337.5 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)623.2%+519.2%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)676.3%+442.3%234%
F3 Lateral (2024-25)343.3%+343.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.15
add_size
0.4
max_lev
1.5
min_hold
48
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R163 pyramid +5% / +30% / 1.3x / 12hPHANTOM 150,563% +360.4 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)585.0%+481.0%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)640.3%+406.3%234%
F3 Lateral (2024-25)366.2%+366.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

total_pyramid_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 + PYRAMIDING longs: cuando price > entry*(1+trigger) (e.g., +10%), add size_frac of remaining cap; up to max_leverage. ⚠️ INTRA-BAR LOOKAHEAD BUG in entry sequencing — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r163_pyramiding.py
Experimento: R163: Pyramiding × always-invested V66
Origen: outputs/round_163_pyramiding/metadata.json · → ver detalle de la ronda
R170 trig=0.05 · add=0.30 · lev=1.30x · hold=12hPHANTOM 150,563% +360.4 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 81.3% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)585.0%+481.0%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)640.3%+406.3%234%
F3 Lateral (2024-25)366.2%+366.2%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.05
add_size
0.3
max_lev
1.3
min_hold
12
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.15 · add=0.30 · lev=1.30x · hold=48hPHANTOM 129,452% +308.7 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)576.0%+472.0%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)625.5%+391.5%234%
F3 Lateral (2024-25)314.5%+314.5%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.15
add_size
0.3
max_lev
1.3
min_hold
48
total_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R163 pyramid +10% / +25% / 1.25x / 24hPHANTOM 119,050% +297.8 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)555.2%+451.2%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)607.1%+373.1%234%
F3 Lateral (2024-25)303.6%+303.6%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

total_pyramid_adds
3

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 + PYRAMIDING longs: cuando price > entry*(1+trigger) (e.g., +10%), add size_frac of remaining cap; up to max_leverage. ⚠️ INTRA-BAR LOOKAHEAD BUG in entry sequencing — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r163_pyramiding.py
Experimento: R163: Pyramiding × always-invested V66
Origen: outputs/round_163_pyramiding/metadata.json · → ver detalle de la ronda
R163 canonical V66 (no pyramid)PHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

total_pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
V66 + PYRAMIDING longs: cuando price > entry*(1+trigger) (e.g., +10%), add size_frac of remaining cap; up to max_leverage. ⚠️ INTRA-BAR LOOKAHEAD BUG in entry sequencing — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r163_pyramiding.py
Experimento: R163: Pyramiding × always-invested V66
Origen: outputs/round_163_pyramiding/metadata.json · → ver detalle de la ronda
R166 canonical V66PHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r166_combined.py
Experimento: R166: combined R163 pyramid + R151-A shorts (stacking test)
Origen: outputs/round_166_combined/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.65 · lev=1.50x · hold=24hPHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.65
max_lev
1.5
min_hold
24
total_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.80 · lev=1.50x · hold=24hPHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.8
max_lev
1.5
min_hold
24
total_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.50 · lev=1.25x · hold=24hPHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.5
max_lev
1.25
min_hold
24
total_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.05 · add=0.40 · lev=1.30x · hold=12hPHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 81.3% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.05
add_size
0.4
max_lev
1.3
min_hold
12
total_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R170 trig=0.10 · add=0.80 · lev=1.75x · hold=24hPHANTOM 70,576% +239.2 4/4
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: bajo bug-fixed engine = +42,636% (= V66 baseline, 78.6% del alpha original era phantom). → ver R184

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)435.1%+331.1%104%
F1 Bull (2019-21)537.3%-624.7%1162%
F2 Recovery (2022-24)473.6%+239.6%234%
F3 Lateral (2024-25)261.3%+261.3%0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

trigger
0.1
add_size
0.8
max_lev
1.75
min_hold
24
total_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
Dense sweep over R163 pyramid params (trigger/add_size/max_lev/min_hold). ⚠️ Same intra-bar bug. ALL 20 variants INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r170_pyramid_sweep.py
Experimento: R170: dense pyramid sweep around R163 winner
Origen: outputs/round_170_pyramid_sweep/metadata.json · → ver detalle de la ronda
R167 V66 canonicalPHANTOMOOT 1/4 +11.4%
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
-7.55436896375144
alpha
11.432784734703343
pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r167_oot_combined.py
Experimento: R167: OOT 2026 for COMBINED + comparison
Origen: outputs/round_167_oot_combined/metadata.json · → ver detalle de la ronda
R167 R163 pyramid onlyPHANTOMOOT 1/4 +60.3%
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=— · WR=—

Métricas y config crudas (metadata.json)

pnl
41.30449568804348
alpha
60.291649386498264
pyramid_adds
1

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r167_oot_combined.py
Experimento: R167: OOT 2026 for COMBINED + comparison
Origen: outputs/round_167_oot_combined/metadata.json · → ver detalle de la ronda
R167 R151-A shorts onlyPHANTOMOOT 1/4 2 sh +13.8%
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-5.2275964610507435
alpha
13.759557237404039
pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r167_oot_combined.py
Experimento: R167: OOT 2026 for COMBINED + comparison
Origen: outputs/round_167_oot_combined/metadata.json · → ver detalle de la ronda
R167 COMBINED R163+R151-APHANTOMOOT 1/4 2 sh +13.8%
🚨 PHANTOM — Esta estrategia fue invalidada por la auditoría R173 (intra-bar lookahead + apalancamiento sin coste). El compound mostrado es 100% artefacto del engine bug.
R184 empirical re-exec: toda la familia pyramid colapsa a V66 baseline (+42,636%) bajo bug-fixed engine. Audit empíricamente validado.

Performance por fold

FoldPnLαBHTradesWR
F0 Bear (2018)104%
F1 Bull (2019-21)1162%
F2 Recovery (2022-24)234%
F3 Lateral (2024-25)0%
Trades/WR por fold solo disponibles cuando metadata.json los registra (R180+). Totales: trades=2 · WR=—

Métricas y config crudas (metadata.json)

pnl
-5.2275964610507435
alpha
13.759557237404039
pyramid_adds
0

Reproducción (cómo replicar este modelo)

Datos fuente
BTC/USD 5min OHLCV (Kaiko, 2017→2026, ~970K bars) en data/btcusd_5min.csv.gz
Timeframes
Base: resample 5min → 15min OHLCV (~325K bars). Slope/DRSI features derivados de close diario via resample('1D'). No multi-timeframe HTF mixing (cerrado en R168/R175 por failure y ahora bajo regla anti-lookahead).
Construcción de secuencias
Lookback = 300 EVENT-bars (no time-bars). Cada secuencia incluye los 300 últimos eventos antes del bar de decisión. Construida por src/data/splitter.py::create_event_sequences(). Cualquier feature que requiera datos posteriores al close[i] está PROHIBIDA.
Normalización
Per-sequence min-max. Grupos compartidos: PRICE (open/high/low/close + ema_9/21/50 + bb_upper/lower/mid + vwap_20) normalizado en bloque; VOLUME (volume_sma_20, obv, obv_sma_20) en bloque; resto (oscilladores RSI/MACD, ratios, returns, ATR_pct) cada uno individual. Definido en src/data/features.py::NORM_GROUPS_BASE + get_norm_group_indices().
Arquitectura
GRU 2 layers × 128 hidden × 5-seed ensemble (checkpoints en outputs/round_069). Input: (batch, 300, n_features) → GRU → dropout 0.2 → FC → 3 logits (softmax externally).
Indicadores / features
RSI(14), MACD(12,26,9), Bollinger(20,2σ) + %B, ATR_14_pct (vol normalization), EMAs(9,21,50), VWAP_20, daily SMA20+pct_change5 slope, DRSI(28) daily (con shift(1) anti-leak), avg_tp_bar, OBV + OBV_SMA20, plus 30+ rolling stats (returns, vol, momentum) generados en src/data/features.py::add_all_features()
Entrenamiento
Adam lr=1e-3, 50 epochs con early-stop on val_loss (patience=10), batch=64, dropout=0.2. 5-seed ensemble: seeds 17/29/41/53/67. Loss: CrossEntropyLoss para 3-class. Val split: 10% del train fold.
Filtro de eventos
Volatility event filter: bar marcado como evento si (ATR_14 > atr_mult × median_ATR_50) AND |return_5_bar| > percentile_90. atr_mult=2.0, return_percentile=90 → ~10.5% de bars seleccionados. Calibrado en R141/R142 — modificar este % rompe V66 thresholds.
Labeling
Triple-barrier method (López de Prado): k_up=10 × ATR_14_pct (upper barrier), k_dn=7 × ATR_14_pct (lower barrier), max_hold=64 bars (vertical barrier). Label ∈ {-1 SL, 0 timeout, 1 TP} → 3-class output. Definido en src/data/labeling.py::apply_labeling(method='tb_vol_10_7').
Entrada / salida
R163 pyramid + R151-A shorts combined. ⚠️ Combined two bugs — INVALIDATED.
Walk-forward
Walk-forward 4 folds chronológicos: F0 Bear (2018), F1 Bull (2019-2021), F2 Recovery (2022-2024), F3 Lateral (2024-2025). val_pct=10% del train por fold. Sin purging — la separación cronológica train|val|test es estricta.
Patrón de ejecución
🚨 Bug-fixed engine (R173+): detect@close[i] → execute@open[i+1]. Pre-R173 ejecutaba en mismo bar = intra-bar lookahead bug. Comisiones 0.04% + slippage 0.01% en cada trade leg, sin excepción.
Script fuente
scripts/run_r167_oot_combined.py
Experimento: R167: OOT 2026 for COMBINED + comparison
Origen: outputs/round_167_oot_combined/metadata.json · → ver detalle de la ronda