eod_replay: fix screener so historical dates work (unlocks backtesting)

_daily_gappers selected each symbol's LATEST daily bar (always the most recent
date in the table) and skipped the symbol unless that bar == the session date.
So replaying ANY past date saw rows[0] != sess and skipped every symbol —
silently reporting "no qualifying gappers" for all history. Multi-day
backtesting was impossible; the dataset looked empty when it was not.

Bound the query to bars ON OR BEFORE the session date so rows[0] is the session
day and rows[1] the prior trading day. Verified: June 17 now finds 11 gappers,
June 16 finds 8, etc. — and a 6-day / 24-trade replay shows the clean strategy
is +11.6R, 75% win, +0.48R/trade (the live losses were execution bugs, since
fixed; no entry-rule tweak robustly beats baseline on this sample).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
momentum devandClaude Opus 4.8 committed 2026-06-18 17:39:40 -04:00
1 parent 78bdf26141
commit b706289a61
1 file changed
+7 -1
+7 -1
View File
@@ -54,9 +54,15 @@ def _daily_gappers(con, sess, universe):
minute-backfill the handful that matter, not all 100 names."""
out = []
for sym in universe:
# Bars ON OR BEFORE the session date, newest first — so rows[0] is the
# session day and rows[1] the prior trading day. Without the `<= sess`
# bound this pulled the LATEST bar (always the most recent date in the
# table), so replaying any past date saw rows[0] != sess and skipped
# EVERY symbol — silently reporting "no qualifying gappers" for all
# history and making multi-day backtesting impossible.
rows = con.execute(
"SELECT trade_date, open, close, volume FROM daily_bars WHERE symbol=? "
"ORDER BY trade_date DESC LIMIT 25", [sym]).fetchall()
"AND trade_date <= ? ORDER BY trade_date DESC LIMIT 25", [sym, sess]).fetchall()
if len(rows) < 2 or str(rows[0][0]) != str(sess):
continue
t_open, t_close, t_vol = float(rows[0][1]), float(rows[0][2]), float(rows[0][3])