|
|
_meta:
|
|
|
id: 35
|
|
|
name: "ORB Pullback V1"
|
|
|
status: documented_failure
|
|
|
description: >
|
|
|
[DOCUMENTED FAILURE — NOT PROMOTED]
|
|
|
|
|
|
Phase 1 attempt: V23's gainers_leader candidate pool + pullback continuation entry.
|
|
|
|
|
|
Diagnostic result (200d):
|
|
|
- Base pullback (no quality gates): 133 trades, WR 25.6%, return -10.14%
|
|
|
- All quality filters (impulse_min, depth_max, vol_contraction, vwap_floor): negative selection
|
|
|
Adding each filter either left WR unchanged or DECREASED it (min 13.3%)
|
|
|
- V23 immediate-entry same pool: WR 61.5% (+36pp gap)
|
|
|
|
|
|
Root cause: V23's candidate pool selects stocks that immediately continue after breakout.
|
|
|
Waiting for a pullback negatively selects against V23's edge — catches the stocks
|
|
|
that stall (typically failing breakouts). All 5 quality filters showed negative selection;
|
|
|
this is NOT a tunable parameter problem but a structural incompatibility.
|
|
|
|
|
|
Conclusion: orb_pullback_v1 on V23 candidates = negative-EV. Pivoting to vwap_reclaim_v1.
|
|
|
|
|
|
Original Phase 1 multi-engine hypothesis:
|
|
|
|
|
|
Engine: orb_pullback_v1 (independent engine_family, not a V23 variant).
|
|
|
Same candidate universe and scoring as V23 (gainers_leader candidate pool).
|
|
|
Different entry: instead of immediate ORB breakout, waits for:
|
|
|
1. Post-breakout impulse peak within 9:40-9:55 ET window
|
|
|
2. Pullback of 25-50% of impulse move (with volume contraction)
|
|
|
3. VWAP floor check (pullback can't breach VWAP by >0.3%)
|
|
|
4. Continuation bar: green + above pullback extreme
|
|
|
|
|
|
Stop: pullback_low (structural) rather than pure ATR.
|
|
|
|
|
|
Gates (standalone 200d):
|
|
|
trades >= 50, WR >= 50%, total_return >= 0%, max_dd >= -20%
|
|
|
Portfolio gates (combined with V23, 600d):
|
|
|
trade_overlap <= 20%, daily_pnl_corr <= 0.30,
|
|
|
combined_600d_dd improvement >= 5pp vs V23 standalone (-51.25%)
|
|
|
|
|
|
Evaluation: not standalone — portfolio contribution to V23 is the target metric.
|
|
|
Run via apps/intraday_bt/portfolio_report.py for combined analysis.
|
|
|
|
|
|
Initial capital intentionally lower ($4000) for composite sleeve weighting (40%
|
|
|
of a hypothetical $10k combined portfolio). For standalone comparison use $10000.
|
|
|
|
|
|
strategy_mode: orb
|
|
|
|
|
|
orb_strategy:
|
|
|
engine_family: orb_pullback_v1
|
|
|
live_readiness: research_only
|
|
|
|
|
|
orb_minutes: 5
|
|
|
sim_bar_minutes: 5
|
|
|
|
|
|
entry_direction: long_only
|
|
|
order_timeout_minutes: 45
|
|
|
|
|
|
allow_doji_breakout: true
|
|
|
allow_red_to_green_breakout: true
|
|
|
|
|
|
# === Candidate filters identical to V23 (gainers_leader pool) ===
|
|
|
min_price: 10.0
|
|
|
min_avg_dollar_volume: 25000000
|
|
|
min_atr_14: 0.50
|
|
|
min_atr_pct: 0.04
|
|
|
min_rvol: 1.5
|
|
|
min_abs_gap_pct: 0.02
|
|
|
min_premarket_dollar_vol: 1500000
|
|
|
max_candidates: 20
|
|
|
max_candidates_per_sector: 3
|
|
|
min_candidates_to_trade: 1
|
|
|
ticker_cooldown_days: 0
|
|
|
max_gap_pct: 0.04
|
|
|
|
|
|
min_candidate_breadth: 0.60
|
|
|
market_regime_spy_threshold: 0.0015
|
|
|
market_regime_ticker: QQQ
|
|
|
rolling_loss_days: 7
|
|
|
rolling_loss_threshold: -0.07
|
|
|
max_simultaneous_entries: 3
|
|
|
min_breakout_rel_vol: 1.2
|
|
|
|
|
|
# === Scoring weights identical to V23 ===
|
|
|
weight_rvol: 0.35
|
|
|
weight_gap: 0.20
|
|
|
weight_dollar_vol: 0.05
|
|
|
weight_premarket_dollar_vol: 0.25
|
|
|
weight_body_ratio: 0.0
|
|
|
weight_momentum: 0.15
|
|
|
|
|
|
# === Stop / exit parameters (base ATR same as V23) ===
|
|
|
atr_stop_multiplier: 0.75
|
|
|
breakeven_at_r: 1.0
|
|
|
trailing_at_r: 1.0
|
|
|
trailing_stop_atr_multiplier: 0.8
|
|
|
trailing_tighten_at_r: 2.0
|
|
|
trailing_stop_atr_multiplier_tight: 0.3
|
|
|
|
|
|
partial_exit_at_r: 99.0
|
|
|
partial_exit_pct: 0.50
|
|
|
|
|
|
risk_per_trade_pct: 0.05
|
|
|
max_position_pct: 0.70
|
|
|
daily_max_loss_pct: 0.05
|
|
|
max_stops_per_day: 5
|
|
|
exit_minutes_before_close: 5
|
|
|
|
|
|
slippage_bps: 5.0
|
|
|
initial_capital: 10000
|
|
|
|
|
|
compound_returns: false
|
|
|
daily_budget_reset: true
|
|
|
settlement_days: 1
|
|
|
|
|
|
drawdown_governor_threshold: 0.025
|
|
|
drawdown_governor_min_scale: 0.30
|
|
|
|
|
|
streak_sizing_win_bonus: 0.70
|
|
|
streak_sizing_max: 2.5
|
|
|
|
|
|
# === Pullback entry — core engine feature ===
|
|
|
pullback_entry: true
|
|
|
pullback_max_bars: 8
|
|
|
pullback_min_retracement_pct: 0.25
|
|
|
pullback_stop_at_low: true
|
|
|
|
|
|
# === Extended pullback controls (orb_pullback_v1) ===
|
|
|
# Impulse peak must form by 9:55 ET (25 min from open)
|
|
|
pullback_impulse_window_end_min: 25
|
|
|
|
|
|
# Impulse must move at least 0.4× ATR above breakout level
|
|
|
pullback_impulse_min_move_atr: 0.4
|
|
|
|
|
|
# Pullback depth: 25% to 60% of impulse move
|
|
|
pullback_depth_max_pct: 0.60
|
|
|
|
|
|
# Pullback phase must have lower avg volume than impulse phase (70% threshold)
|
|
|
pullback_volume_contraction_ratio: 0.70
|
|
|
|
|
|
# Abort if pullback penetrates VWAP by more than 0.3%
|
|
|
pullback_vwap_floor: true
|
|
|
pullback_vwap_floor_tolerance_pct: 0.003
|
|
|
|
|
|
# Stop: structural pullback low (not VWAP — cleaner for initial testing)
|
|
|
pullback_stop_mode: pullback_low
|
|
|
pullback_stop_vwap_buffer_pct: 0.002
|
|
|
|
|
|
# Reclaim bar must have 1.2× average post-ORB bar volume
|
|
|
pullback_reclaim_confirm_rel_vol: 1.2
|
|
|
|
|
|
universe:
|
|
|
source: midlarge
|
|
|
|
|
|
backtest:
|
|
|
start_date: null
|
|
|
end_date: null
|
|
|
lookback_trading_days: 200
|
|
|
|
|
|
cache:
|
|
|
enabled: true
|
|
|
dir: data/cache/intraday
|
|
|
|
|
|
output:
|
|
|
dir: runs/intraday_orb
|
|
|
verbose: false
|