main
${ noResults }
2 Commits (main)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
d000731cc7 |
PEAD session: add 4 candidate engines + Oracle vocab normalizer + auto-refresh disable
New engines (configurable but not promoted by default): - libs/backtest/earnings_runup.py: pre-earnings drift entry (T-7 to T-3, attention+volume z-scores) - libs/backtest/peer_sympathy.py: peer reaction trade after leader earnings, with reaction_close variant - libs/backtest/vol_breakout_52w.py: 52-week high volume breakout - libs/backtest/cross_sectional_momentum.py: 12-1 momentum with VIX/SPY-50dma regime filter Pipeline additions: - libs/parser/event_type_normalizer.py: normalize Oracle fallback raw vocab to strategy vocabulary (earnings_result→earnings_release, regulation_fd→guidance_update, etc.). Wired into apps/pipeline/event_parser/main.py oracle-fallback path. - libs/labeler/label_generator.py: preserve future entry_dates as label_status='pending' instead of dropping as 'unavailable'. - libs/export/snapshot_export.py: include 'pending' labels in snapshot export. - libs/parser/rule_parser.py: harden 8-K item-code classifier against dirty input strings. Infrastructure: - libs/backtest/snapshot_store.py: _PRICE_FEATURE_WARMUP_DAYS 120→400 (needed for xsmom 12-1 lookback of 273 trading days). - apps/backtester/run.py + apps/paper_trader/backtest_sim.py: disable auto-refresh of snapshots (user request — auto-refresh was silently rebuilding snapshots with current code, making historical backtests irreproducible across DB mutations). Engine config support: - libs/backtest/domain.py: add fields for ER/PS/VolBO/xsmom engine configs. - libs/backtest/execution.py: wire pct-trailing for EarningsRunup. - libs/backtest/scoring.py: synthetic candidate scoring for new engines. Configs (POC + sweeps, none promoted as active strategy): - Phase A-E PEAD baseline comparisons (no PEAD / +ER / +xsmom / +sleeves variants) - Phase F1-F8 silo allocation sweep (v7.356 + ER/xsmom silos 15-60%) - xsmom_poc_v1, xsmom_v2_regime_mdd - v7.356_plus_er_silo_05/10/15/20/25/30 ranges - earnings_runup_* / peer_sympathy_* / vol_breakout_52w_* POCs Tests: 16-tests-each for each new engine + event_type_normalizer tests. Note: backtest reproducibility infrastructure remains broken — see _backup_2026-05-10/HANDOFF.md for details on the +12,592% reference run that cannot be reproduced after rebuilds. Followup work needed before trusting any specific backtest number. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
3 months ago |
|
|
956cc78f1b |
Add 3 candidate engine classes beyond PEAD: EarningsRunup, PeerSympathy, VolBreakout52w
Adds three new synthetic-Candidate emitter engines parallel to the existing leader_follower scheduler hook, plus look-ahead defenses (LookaheadViolationError + per-engine assertions). Each engine is covered by a standalone PoC config (no PEAD/parking/idle alpha) for isolation backtests against the midlarge or broad snapshot. Engines: EarningsRunup (libs/backtest/earnings_runup.py) - Trigger: days_to_earnings ∈ [3,7] AND attention_zscore_20d ≥ 1.5 AND dollar_volume_20d_zscore ≥ 1.0 (all evaluated at T-1 close) - Entry: T+1 next_open. Exit: -4% / +8% / max_holding_days = days_to_earnings - buffer (forced flat by close before announcement) - PIT calendar: PointInTimeEarningsCalendar adapter for backtest; oracle_surprise_prefetch fallback when parquet calendar absent - PoC verdict (configs/experiments/earnings_runup_poc_v1.json): 119 trades over 1051 days, +37.27% total return, 44.46% MDD, SQS 45.2 (profitability=55.5, risk=23.5, robustness=50.1). VIABLE BUT NEEDS WORK — signal exists; standalone risk profile too aggressive for v7.356 baseline (8.8% MDD on v7.364). Path forward: per_trade_risk reduction, VIX gate, position cap, or integrate as PEAD sleeve adjunct (not as standalone replacement). PeerSympathy (libs/backtest/peer_sympathy.py) - Trigger: leader passes PEAD filter (earnings_release / guidance_update / material_contract) AND leader reaction_close ≥ +5% AND peer 60d correlation ≥ 0.55 over [T-65, T-5]. Top-2 peers by correlation from leader_follower_extra_peer_symbols_by_sector + sector ETF holdings. - Entry: T+1 next_open on peer. Exit: -3.5% / +6% / max_holding=3 / peer-earnings blackout - PoC verdict (configs/experiments/peer_sympathy_poc_v1.json): 256 trades over 1051 days, -52.92% total return, 54.47% MDD, SQS 19.6 (profitability=0.0, risk=5.4, robustness=100.0). DEAD. The leader's catalyst is already absorbed by T+1 next_open — peers gap up overnight before entry. robustness=100 confirms the negative result is not noise. Salvage paths (not implemented): reaction_close entry, raised-guidance-only restriction. - Note: initial run_id was 0 trades due to a select_candidates filter mismatch (engine.event_types=['peer_sympathy'] dropping real event_type='earnings_release' rows). The runner adapter was patched to bypass strategy_engine filtering for leader selection; the manual peer_sympathy_leader_event_types filter does the gating. VolBreakout52w (libs/backtest/vol_breakout_52w.py) - Trigger: close_T-1 > max(high[T-252:T-2]) AND volume_T-1 ≥ 2 × median_volume_20d_T-2 AND ATR_14_T-1/close ∈ [0.015, 0.06]. Entry T next_open, exit -3% / +5% / max_holding=2 / MOC. - Honest, look-ahead-safe descendant of the retired topgainer v1-v54 family. Five layers of strict-before assertions guard the bar provider, candidate construction, trigger evaluation, and feature timestamps. A leaky-provider proof-by-contradiction test demonstrates the categorical catch. - PoC verdict (configs/experiments/vol_breakout_52w_poc_v1.json, broad-liquid universe): 1,332 trades, -87.28% total return, 88.74% MDD, SQS 24.4 (profitability=0.0, robustness=100.0). DEAD AND HONEST. This is the most important finding of the three PoCs: the topgainer v1-v54 lineage's headline returns (+267% Sharpe 13.73 in best variants) were 100% lookahead bug. With the bug removed, the 52w-high + volume + ATR signal has no real alpha — the lookahead-corrected -4.3% from prior memory is confirmed and amplified to -87% on a fuller universe and longer horizon. Future "revive topgainer" proposals can cite this run (bt_return_max_long_v1_broad-liquid_20260509042903892342_3bb473d9) as definitive falsification. - Pre-open gap guard inactive (no premarket data in broad snapshot). skip_if_no_gap_data=true; the +4% gap-fade guard would not move the result given the magnitude. Shared infrastructure additions: - libs/backtest/domain.py: LookaheadViolationError class + StrategyEngineConfig fields (11 EarningsRunup + 11 PeerSympathy + 13 VolBreakout52w = 35 new fields) - apps/backtester/run.py: _BacktestAttentionZscoreAdapter, _RunnerPeerResolver, _schedule_earnings_runup_candidates, _schedule_peer_sympathy_candidates, _schedule_vol_breakout_52w_candidates wired into the daily scheduler block. PeerSympathy adapter bypasses strategy_engine filtering on leader selection (manual filter handles gating). Tests: 21 (EarningsRunup) + 27 (PeerSympathy) + 38 (VolBreakout52w) = 86 new unit tests, all passing. Broader unit suite: 1392 passed, 2 pre-existing failures unrelated. Net engine state: EarningsRunup is the only viable new engine class. PeerSympathy and VolBreakout52w are kept in-tree as falsification evidence, not as production engines. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
3 months ago |