You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #269/#272. Raised as an open question in #272's review: min_periods was deliberately left at 1 because raising it to a full session would leave the first session of every intraday backtest with no liquidity cap and no market impact at all (both _daily_adv consumers guard with if pd.notna(adv_20) and adv_20 > 0, so NaN skips the cap block rather than applying a cautious one).
Problem
During warm-up (fewer than _adv_bars_per_day * 20 bars of history), _daily_adv() extrapolates from whatever partial window it has, weighted by min_periods=1 — in the worst case, a single bar's volume × bars-per-day. That's a fair, unbiased but high-variance guess, and it's strictly better than the pre-#265 behaviour, but it's not the best available estimate.
Proposed fix
Use an expanding mean during warm-up instead of a fixed-window rolling mean with min_periods=1:
For at_date where fewer than _adv_window_bars are available, average all bars seen so far (rescaled to daily by _adv_bars_per_day) instead of relying on min_periods=1's partial-window behaviour.
Once _adv_window_bars of history exists, behaviour is identical to today — this only changes the warm-up period.
Does not change trade admission logic — no trade that currently fires should stop firing, and no trade that's currently blocked should start firing. Only the cap/impact magnitude during warm-up changes.
No-regression requirement
D/W/M timeframes: bpd == 1, so the "warm-up" period is the first ~20 calendar days of any run — same as today's behaviour for daily backtests, since 20 daily bars is a short warm-up already covered by existing tests. Confirm no numeric drift there.
Any backtest whose full history already exceeds 20 days behaves byte-identically (the expanding-mean path is only reachable during the literal first _adv_window_bars bars of a series).
Golden master (tests/test_engine_characterization.py) green.
Follow-up to #269/#272. Raised as an open question in #272's review:
min_periodswas deliberately left at1because raising it to a full session would leave the first session of every intraday backtest with no liquidity cap and no market impact at all (both_daily_advconsumers guard withif pd.notna(adv_20) and adv_20 > 0, soNaNskips the cap block rather than applying a cautious one).Problem
During warm-up (fewer than
_adv_bars_per_day * 20bars of history),_daily_adv()extrapolates from whatever partial window it has, weighted bymin_periods=1— in the worst case, a single bar's volume × bars-per-day. That's a fair, unbiased but high-variance guess, and it's strictly better than the pre-#265 behaviour, but it's not the best available estimate.Proposed fix
Use an expanding mean during warm-up instead of a fixed-window rolling mean with
min_periods=1:at_datewhere fewer than_adv_window_barsare available, average all bars seen so far (rescaled to daily by_adv_bars_per_day) instead of relying onmin_periods=1's partial-window behaviour._adv_window_barsof history exists, behaviour is identical to today — this only changes the warm-up period.No-regression requirement
D/W/Mtimeframes:bpd == 1, so the "warm-up" period is the first ~20 calendar days of any run — same as today's behaviour for daily backtests, since 20 daily bars is a short warm-up already covered by existing tests. Confirm no numeric drift there._adv_window_barsbars of a series).tests/test_engine_characterization.py) green.Acceptance criteria