P2 = run detect_vwap_reclaim over history and score it with the SAME no-look-ahead
machinery that scores the live ORB setups, so its base rates are directly comparable
and there's no train/serve skew in the SCORING either (not just the features).
- Extracted research/labeler.py's forward-label logic into a shared _forward_labels()
(max-upside/-drawdown 5/15/60m, reached_1R/2R-before-1R pessimistic, held-VWAP over
the evolving cumulative VWAP, trend-day, failed-breakout, time-to-max). compute_setup
now calls it -- the 3 existing labeler tests still pass, so the extraction is
behavior-preserving.
- compute_vwap_reclaim_setups(): slides the detector over each session's RTH bars and
emits a NON-TRADEABLE setup_event on each RISING EDGE (not-valid->valid, with a bar
cooldown so one curl episode = one setup), carrying the detector's OWN entry/stop/R.
STRICT time split: the detector at bar i sees only bars[:i+1]; labels use only bars
after i. setup_version='vr1', setup_name='vwap_reclaim' -- isolated from the ORB 'v1'.
- build_vwap_reclaim / report_vwap_reclaim + CLI `build-vr` / `report-vr`. report-vr
prints forward outcomes AND a head-to-head vs the ORB baseline on the same symbol-days.
- 2 new tests: a continuation session fires + labels a +1R winner; a one-way fade stays
silent (anti falling-knife). 12/12 green.
PRELIMINARY read (n=35, 4 days -- far too small to trust; full build running): curl-
fires reached +1R 66% / +2R 49%, held-VWAP-15m 86%, avg +8% max-upside in 60m; the ORB
baseline on the same symbol-days reached +1R 67%. Real finding pending the full build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>