| Clean re-run (deleted results.json, forecasts.csv; re-ran analysis.py) gives byte-identical files |
PASS |
| forecasts.csv has 240 rows, 40 per (model, horizon) |
PASS |
| target_date = origin_date + h quarters for every row |
PASS |
actual equals infl_annualised at target_date |
PASS |
| snaive forecast equals infl_annualised at target − 4 quarters, and that date ≤ origin |
PASS |
| Estimation sample at each origin ends exactly at the origin (assert in code: hist.index.max() == t) |
PASS |
| RMSE ≥ MAE for all model/horizon pairs |
PASS |
| rel_improvement = 1 − rmse_model/rmse_snaive ( |
diff |
| loss_diff_mean_h4 = rmse_snaive_h4² − rmse_model_h4² (2.81795 both) |
PASS |
| dm_stat_h4 = mean/se; se > 0; hac_lags_h4 = 3 ≥ h−1 |
PASS |
| HAC SE cross-checked against statsmodels OLS-on-constant HAC (Bartlett, maxlags=3, no small-sample correction): 2.086237 vs 2.086237 |
PASS |
| first_origin < last_origin; n_origins = 40 |
PASS |
| Exclusion ledger: 127 − 1 = 126 analysable quarters; last estimation sample 1995Q2–2025Q3 = 122 quarters, minus p=1 lag = 121 = n_analysed |
PASS |
| Magnitudes: model RMSE (2.19–2.46) below snaive RMSE (≈2.85–2.88) and of the same order as the series sd (2.39) |
plausible |
| Sensitivity note: HAC SE decreases with longer Bartlett lags (L=4: 1.85, L=6: 1.38) — negative higher-order autocorrelations in d_t; primary lag L=3 was fixed before seeing results |
reported, not a failure |