On 2026-10-02 the live bot bought 7 TNON at 4.62 and the Tradier sell-stop filled at
4.30 forty-nine seconds later, before a position record existed, so no position_closed
event was written and the 80-trade scorecard silently dropped a -1R loser. The daily
equity-vs-P&L gap ($2.31 that day, cents everywhere else) is what exposed it.
load_trades now merges the journal with a cross-check of the broker's filled orders
(account_orders_updated snapshots, one row per broker order id). For any session day and
symbol with a filled buy and sell but no journaled close, reconstruct_missing synthesises
the trade from the fills: fill VWAPs for entry/exit, the sell-stop's stop price for R.
Such trades are labelled "[broker fill; journal missed]" and the daily report alerts on a
same-day miss. The paper side of the exit A/B skips the check: that store's order
snapshots run to 2.2 GB over the window and its Alpaca journal is reconciled by
alpaca_paper/sync.
Corrected test state: 16/80, mean R -0.08, realized +$0.91 (was 15/80, -0.02, +$3.15).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LXxioW7HA18AY1gqnzA2HN
The live (Tradier) stack has no backup service. Only the paper stack backs up its
own DB, so the 80-trade test's whole record lived only on the TrueNAS pool.
- deploy/backup_live_db.py, run by Task Scheduler "Momentum\LiveDbBackup" at 20:40 ET
nightly: pg_dump -Fc (PostgreSQL 18.6 client) of the live DB to
C:\Users\Admin\momentum-backups. It is verified with pg_restore --list (the events
and config_overrides data must be present), keeps the newest 7, and writes
status.json. A broken dump is deleted rather than kept.
- research/daily_report.py alerts when the last backup failed or is more than 36 h
old. When there are alerts it sends them to Telegram, using the stack's own sender
and the credentials in .env. --no-telegram suppresses that for dry runs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3PXXn2tHBzdv6rYtGPz86
research/daily_report.py, run by Task Scheduler "Momentum\DailyReport" at 16:25 ET
on weekdays, writes data/reports/daily_<date>.md with ALERTS on top:
- the live opening-range bot's frozen 80-trade test: verdict, mean R with CI,
P&L, equity headroom over the floor, today's trades, open deviations, settings
drift;
- the judge v2 paper trial: judge.review for every counted day, cumulative
paper-vs-sim execution parity, today's flagged trades, trader errors and
restarts;
- the old-vs-new exit A/B (alerts at 50 pairs);
- stack health: down at the open, silent gaps of 10+ min, the press-release
recorder.
Read-only everywhere (PG_SKIP_SCHEMA=1, SELECTs only). Replayed on 2026-09-30 it
flags that day's real problems: the judge error loop, the paper stack down until
13:51, and a 25-min gap.
judge/PAPER_TRIAL.md, written before any counted trade: trades count from
2026-10-02. At 60 trades the paper trial must show execution parity with the
simulator (paper minus sim >= -0.15R) before a 150-trade performance read. Real
money is only considered after that, and only with the owner's go-ahead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3PXXn2tHBzdv6rYtGPz86