You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
3.9 KiB
YAML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# ORB (Opening Range Breakout) Strategy — Default Configuration
# Strategy: Buy breakout of first 5-min candle high (bullish candles only).
# Uses ATR-based stops, risk-based position sizing, 15:55 ET time exit.
# Based on ORB academic research adapted for available data infrastructure.
strategy_mode: orb
orb_strategy:
# ORB window
orb_minutes: 5 # 9:309:35 ET opening range
sim_bar_minutes: 30 # 30-min bars for breakout/stop management (ORB candle stays 5-min)
# Entry
entry_direction: long_only # bullish candle only (V1; 'candle' for both directions)
order_timeout_minutes: 45 # cancel if no fill by 10:15 ET
# Universe quality filters (applied during pre-screening)
min_price: 10.0 # $10+ stocks only
min_avg_dollar_volume: 25000000 # $25M 30-day avg daily dollar volume
min_atr_14: 0.50 # ATR(14) > $0.50 (sufficient range to trade)
# RVOL-based candidate selection
min_rvol: 1.0 # minimum approx RVOL at open (see note in features.py)
max_candidates: 20 # top N candidates per day
min_candidates_to_trade: 3 # skip day if fewer qualify
# Composite ranking weights (must sum to 1.0)
weight_rvol: 0.60 # relative volume (main signal)
weight_gap: 0.25 # gap% (proxy for premarket activity)
weight_dollar_vol: 0.15 # first-bar dollar volume
# ATR-based stop management
atr_stop_multiplier: 0.50 # initial stop = ATR(14) × 50% from entry
breakeven_at_r: 1.0 # move stop to entry at +1R
trailing_at_r: 2.0 # activate trailing stop (3-bar swing low) at +2R
# Risk-based position sizing
risk_per_trade_pct: 0.0025 # 0.25% of equity per trade
max_position_pct: 0.20 # cap at 20% of equity per position
daily_max_loss_pct: 0.0125 # stop trading at -1.25% daily loss
max_stops_per_day: 3 # stop trading after 3 full-R stops
# Exit
exit_minutes_before_close: 5 # time exit at 15:55 ET
# Execution
slippage_bps: 5.0 # 0.05% one-way slippage (both entry and exit)
initial_capital: 10000 # $10,000 starting capital
ticker_cooldown_days: 0 # no cooldown (ORB trades daily runners)
# Cash account GFV (Good Faith Violation) constraint
# Unsettled proceeds can buy but not same-day sell → ORB always exits same day
# → only settled cash is usable. 0=disabled, 1=T+1 (US since May 2024), 2=T+2
settlement_days: 1
# Max opening gap filter: exclude stocks that gapped up more than this at open.
# Stocks with large gaps are over-extended and show low breakout continuation rate.
# Sweep result: 3% >> 5% >> 10% in Sharpe (5.59 vs 4.50 vs 3.74).
max_gap_pct: 0.03
# Market regime: skip days when index gaps down > threshold at open
# Sweep result: SPY -0.5% filter hurts absolute return with minimal Sharpe gain.
# Individual ORB candidates can surge even on weak-SPY days (e.g. sector rotation).
market_regime_spy_threshold: null # disabled — breadth filter below is superior
# Candidate breadth filter: skip day if <N% of candidates opened above prev close.
# Sweep: Breadth≥30% → Sharpe 19.86 but return +520% vs +676% with no filter.
# Existing per-trade risk controls (ATR stop, daily loss limit) are sufficient.
min_candidate_breadth: null
universe:
source: midlarge # 971-ticker mid+large cap universe
min_price: 10.0 # redundant with orb_strategy.min_price but explicit
backtest:
start_date: null # null = auto (today - lookback_trading_days)
end_date: null
lookback_trading_days: 200 # ~10 months
pre_screen_threshold: 0.01 # not used by ORB mode (kept for config compatibility)
cache:
enabled: true
dir: data/cache/intraday
output:
dir: runs/intraday_orb
verbose: false