- run_eod_exit now queries DB for any pending candidates not in-memory
(guards against server restart mid-day leaving zombie pending records)
- Remove compound_returns=True force-override; live engine doesn't use it
and V23 config has compound_returns=false
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- screener.py: add min_atr_pct/max_atr_pct filters to live_pre_screen
- engine.py: prepend regime ticker (QQQ) to bar fetch so regime filter works
- engine.py: add rolling loss + account circuit breaker at run_orb_detection
- engine.py: patch today_open from first 1-min bar so regime gap is real
- engine.py: explicit regime + breadth filter before compute_orb_candidates
- engine.py: max_simultaneous_entries guard in run_breakout_check
- engine.py: _compute_sizing_capital with daily_budget_reset (fixed $10k base),
drawdown governor, and streak sizing (win bonus / loss penalty)
- engine.py: trailing_tighten_at_r in run_stop_check (tight multiplier at 2R)
Bug fixes in _compute_sizing_capital:
- streak direction: remove reversed() so outcomes[0] = newest trade
- daily reset: use initial_equity as base (not growing equity), matching V23
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add run_pre_screen() at 9:20 ET: fetch daily bars + enrichment + quality filter
before market open, narrowing universe for faster orb_detect intraday fetch
- run_orb_detection() uses cached pre-screen data when available; falls back to
full pipeline if pre_screen missed (late start, failure)
- Add _last_trading_day() helper to skip weekends/holidays for bars_end,
preventing Alpaca 502 on Mondays (today-1 = Sunday was causing failures)
- Fix Oracle client chunk_size 300→75: Alpaca rejects 100+ ticker URL requests
- Add pre_screen event to build_schedule() at 9:20 ET and dispatch in _run_trading()
- run_session_now() runs pre_screen before orb_detect for efficiency
- Add ORB daemon, engine, models, state, screener, and intraday strategy configs
- Add intraday library (libs/intraday/) and web routes for ORB/intraday trading
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- libs/oracle_client/alpaca.py: Added get_multi_daily_bars() and
get_multi_intraday_bars() helpers that call Oracle's /api/v1/price/data
and /api/v1/alpaca/intraday endpoints respectively. Oracle handles
symbol normalization (e.g. BF-B → BF.B) internally, so symbols like
BF-B no longer crash the screening chunk.
- apps/paper_trader/alpaca_broker.py: get_bars() and get_intraday_bars()
now use the new Oracle client helpers instead of the Alpaca SDK
StockBarsRequest, eliminating direct Alpaca bar API calls from broker.
- apps/orb_trader/engine.py: Removed per-symbol BF-B workaround (now
unnecessary since Oracle normalizes the symbol server-side); kept outer
try/except for chunk-level resilience.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Daily bars chunk loop: on failure, retry symbol-by-symbol to isolate
and skip the bad ticker rather than crashing the entire detection.
Intraday bars chunk loop: catch and log failures, continue with rest.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Breakout check interval: change from every-1-min to every sim_bar_minutes,
matching the backtest bar aggregation frequency; align timeout base to
market open (consistent with orb_simulator.py)
- Rejected/cancelled orders: add order_rejected flag so cancelled orders no
longer fall through to position creation (phantom positions)
- Stop/EOD exit fill price: poll broker fill price after close_position()
instead of recording at current_stop, capturing gap-through losses
- Stop/EOD close_position: pass qty=int(pos.shares) so multi-session
same-ticker scenarios only close the current session's share count
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>