backtest: seed slow-TF history to the live 1000-bar floor (_history_pad_days)
The per-TF warm-up pad before --start targeted 210 bars, so a 3-year H4 book started with 372 H4 bars and ~210 D1 bars of seeding while the live scanner now fetches at least MIN_LIVE_BARS (1000) on every timeframe. _history_pad_days keeps the 62-day intraday pad (already >= 1488 bars, so M5/M15/H1 cache windows are untouched) and pads H4 by 234 and D1 by 1400 calendar days; the raw-path fetch for trade resolution reuses the primary timeframe's own start (one cache file per TF, as before). Verified on the 3-year books at $0.65: M5 and M15 byte-identical (c2722f98…, b2cfa9e2…); H1 and H4 trade-for-trade identical (253 / +70.02R, 114 / +21.68R) — the only differences are one H4 confirmation reading 15 days into the H1 window and 1e-6…1e-9 numerics in D1 Wilder recursions during Oct–Dec 2023, i.e. the window-start seeding zone. Evidence: backtest/research/cycle_2026-09-10.md. Tests: Module 21 "history pad seeds slow TFs like live". Suite 501 passed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NQDjW8rXYrJR4JDWMWKUij
This commit is contained in:
+15
@@ -5849,6 +5849,21 @@ def _():
|
||||
"no 0.0-defaulted prices may appear"
|
||||
|
||||
|
||||
@test("backtester: history pad seeds slow TFs like live (H4/D1 deeper, intraday unchanged)")
|
||||
def _():
|
||||
import backtest.gpu_backtest as _gb
|
||||
pad = {tf: _gb._history_pad_days(tf, 250) for tf in
|
||||
(Timeframe.M5, Timeframe.M15, Timeframe.H1, Timeframe.H4, Timeframe.D1)}
|
||||
# intraday pads keep the 62-day base -> cache windows and books unchanged
|
||||
assert pad[Timeframe.M5] == 62 and pad[Timeframe.M15] == 62 and pad[Timeframe.H1] == 62, pad
|
||||
# slow TFs fetch enough history for MIN_LIVE_BARS (1000) bars: H4 6/day, D1 1/day
|
||||
assert pad[Timeframe.H4] == 234 and pad[Timeframe.D1] == 1400, pad
|
||||
# base pad still follows --warmup-bars when that is the larger requirement
|
||||
assert _gb._history_pad_days(Timeframe.M5, 1000) == 250
|
||||
# the floor is the provider's constant, not a second copy of the number
|
||||
assert _gb.BaseDataProvider.MIN_LIVE_BARS == 1000
|
||||
|
||||
|
||||
@test("backtester: NaN bar inside a trailing window cannot poison R/metrics")
|
||||
def _():
|
||||
import gpu_backtest as _gb
|
||||
|
||||
Reference in New Issue
Block a user