fix: backtest starvation — schedule the labeler nightly, make inserts idempotent

Dashboard backtest sources sessions from setup_events v1, which only the
labeler writes — and the labeler was never in the nightly scheduler, so
setups (and therefore backtests) froze at the last manual run (07-17).
Root blocker was _insert crashing on duplicate setup_ids on any re-run;
now ON CONFLICT DO NOTHING, so incremental nightly builds are safe.
Scheduler gains 'labeler build' + 'build-tod1' after eod_replay in both
compose files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
momentum devandClaude Fable 5 committed 2026-07-22 06:51:56 -05:00
1 parent 5f33799a9a
commit ed176b3712
3 files changed
+22 -2

No files matched your search

+17
View File
@@ -237,3 +237,20 @@ def test_tod1_silent_without_volume_explosion():
df = _tod1_bars(base_vol=300) # 300/min vs med 100k -> tod << 50
assert compute_tod1_setups("QUIET", D, df, prior_close=2.00,
med_vol=100_000, cats={}) == []
def test_insert_is_idempotent_on_setup_id():
"""Nightly incremental builds re-scan history — a duplicate setup_id must be
skipped (ON CONFLICT DO NOTHING), not crash the whole build."""
from storage.event_store import EventStore
from research.labeler import _insert
s = EventStore(":memory:")
con = s.con
row = dict(setup_id="X:2026-06-01:v9", symbol="X", setup_time=datetime(2026, 6, 1, 9, 40),
session_date=date(2026, 6, 1), setup_name="t", setup_version="v9",
entry_reference_price=1.0, invalidation_price=0.9)
_insert(con, "setup_events", row)
_insert(con, "setup_events", row) # duplicate: must not raise
n = con.execute("SELECT count(*) FROM setup_events WHERE setup_version='v9'").fetchone()[0]
assert n == 1
s.close()