Equity ledgers: every healed day held the previous day's close (found and repaired 2026-10-02)
Owner-approved repair of the live equity ledgers, the go-live and forward gates' input series.
The bug (fixed in #213)
Alpaca stamps a 1D portfolio-history bar at 00:00 UTC after its trading day — 20:00 New York
time on that day. AlpacaBroker.get_equity_history took the stamp's UTC date, so every close was
labelled one day late:
| Alpaca stamp (epoch) | UTC date (used) | New York date (true) | close |
|---|---|---|---|
| 1789776000 | Sat 2026-09-19 | Fri 2026-09-18 | 13,708.48 |
| 1790035200 | Tue 2026-09-22 | Mon 2026-09-21 | 13,721.76 |
| 1790640000 | Tue 2026-09-29 | Mon 2026-09-28 | 13,693.61 |
So portfolio backfill-equity, which heals days a run never recorded, wrote each one with the
previous trading day's close (Friday's close was filed under Saturday and then dropped as a
non-trading day). No Monday could ever be healed, and reconcile could not flag a missing Monday
either (its comment called the Saturday rows "weekend snapshots carrying Friday forward"). Found
while chasing the daily audit's "two equity holes" (09-21, 09-28; 2026-10-02 report, Finding 3).
The repair (this change)
scripts/repair_equity_dates_2026_10_02.py, using the fixed history and the ledger's own writer
(StateManager.append_equity). An entry is corrected only when all hold, so no real run's
value is touched:
- the sleeve logged no
run_summarythat day (nothing ran; the backfill wrote it) — judged only from the sleeve's first logged run on; - it equals the previous trading day's broker close to the cent;
- it differs from that day's own broker close.
Missing trading days on or after the first logged run get that day's close.
| sleeve | corrected | added (missing) | not touched |
|---|---|---|---|
| momentum | 06-17, 07-16, 07-17, 08-06, 08-27, 09-22, 09-23, 09-24, 09-25, 09-29, 09-30 | 09-21, 09-28 | 05-06..05-08 (before run logging: not assessable); 08-28 (a real run, the STAMP-2 midnight-crossing incident, a different defect) |
| meanrev | 07-16, 07-17, 07-30, 08-06, 09-22, 09-23, 09-24, 09-25, 09-29, 09-30 | 09-21, 09-28 | — |
| vrp | 07-24, 08-06 | 09-21, 09-28 | 7 healed days while the book was all cash (prior close = true close: already right) |
Every value is the broker's own close for that New York date; the full before/after list is the dry-run output in the PR.
Effect on the gates
| before | after | |
|---|---|---|
| momentum go-live clock (live trading days since 06-11) | 76 | 78 |
| vrp forward-gate clock (since 07-27) | 46 | 48 |
| momentum live cumulative return | −3.34% | −3.34% (shifts cancel over a stretch) |
| momentum live Sharpe (point) | −1.235 | −1.264 |
| momentum trailing 63d Sharpe | −0.918 | −0.642 |
The repair changes which day a move is booked on, not how much was made: the cumulative return is unchanged, the daily series is now correctly dated, and both clocks gain the two Mondays.