# F3-conf-04 — Multi-horizon forecasts of Canadian quarterly CPI inflation ## Question Over 40 expanding-window origins, 2015Q4 to 2025Q3 (`n_origins`, `first_origin`, `last_origin`), does a seasonal autoregression forecast Canadian quarterly CPI inflation (400·Δln of the quarterly-average NSA index, % annual rate) better than the seasonal-naive forecast at h = 1, 2 and 4? And at h = 4, is the mean squared-error loss differential different from zero once we allow for the serial correlation that overlapping 4-step errors create? ## Data and exclusions - `data/cpi_quarterly.csv`: 127 rows; `data/cpi_monthly.csv`: 381 rows (`n_input_rows`). Both SHA-256 hashes match the README. The quarterly series can be recomputed from the monthly file to within 5e-7. Details are in `out/state/data_audit.md`. - One exclusion (`out/exclusions.csv`): 1995Q1 has no inflation value because the first difference is undefined. 127 − 1 = 126 usable quarters. The last estimation sample (origin 2025Q3) uses 121 observations (`n_analysed`). - Data issues (`data_issues`): the series has large real shocks (2008Q4, 2020Q2 COVID, the 2022 surge). I kept them as they are, because any outlier treatment would need judgement made after the origin. ## Method - **Baseline (snaive):** the forecast for quarter t+h is the inflation value of quarter t+h−4. - **Model (`model_name` = `sar_dummy_aic`), see `model_description`:** OLS regression of inflation on four quarter dummies and p own lags. At each origin, AIC picks p ∈ {0,…,4} on a common sample. The model is then re-estimated on the expanding window from 1995Q2 to the origin, and multi-step forecasts are iterated. Only quarters ≤ origin are used for estimation and lag selection. The AIC chose p = 1 at 15 origins and p = 2 at 25 (`ar_lag_order_selected`). - **Evaluation:** RMSE and MAE over the 40 origins for each horizon, and relative improvement = 1 − RMSE_model/RMSE_snaive. - **h = 4 test:** d_t = e²_snaive − e²_model, and DM = d̄ / SE_HAC. The SE uses a Bartlett (Newey–West) kernel with truncation lag 4 (`hac_kernel_h4`, `hac_lags_h4`). I fixed this choice before seeing any results: it is ≥ h−1 = 3, it gives non-zero weight to all autocovariances up to lag 3, and the Bartlett kernel guarantees a positive variance. The p-value is two-sided from the standard normal. No random numbers are used (`random_seed` = null). ## Results | h | RMSE snaive | RMSE model | MAE snaive | MAE model | 1 − RMSE ratio | |---|---|---|---|---|---| | 1 | 2.849 (`rmse_snaive_h1`) | 2.193 (`rmse_model_h1`) | 2.137 (`mae_snaive_h1`) | 1.519 (`mae_model_h1`) | 0.230 (`rel_improvement_rmse_h1`) | | 2 | 2.847 (`rmse_snaive_h2`) | 2.463 (`rmse_model_h2`) | 2.126 (`mae_snaive_h2`) | 1.553 (`mae_model_h2`) | 0.135 (`rel_improvement_rmse_h2`) | | 4 | 2.882 (`rmse_snaive_h4`) | 2.343 (`rmse_model_h4`) | 2.181 (`mae_snaive_h4`) | 1.597 (`mae_model_h4`) | 0.187 (`rel_improvement_rmse_h4`) | Units are percentage points of annualised inflation. At every horizon the seasonal AR has a lower RMSE and a lower MAE than the seasonal-naive forecast. At h = 4: d̄ = 2.818 squared pp (`loss_diff_mean_h4`, positive means the model is better), HAC SE = 1.851 (`loss_diff_se_h4`), DM = 1.52 (`dm_stat_h4`), two-sided p = 0.128 (`dm_pvalue_h4`). **At conventional levels, the h = 4 loss differential cannot be distinguished from zero.** ## Uncertainty The test result depends on the HAC choice. The supplementary results are under `sensitivity_h4`: - Bartlett, lag 3: p = 0.177 - rectangular, lag 3 (original DM truncation): p = 0.097 - Harvey–Leybourne–Newbold small-sample correction of the main statistic, with t(39) reference: p = 0.173 - Bartlett, lag 6: p = 0.041 Only the longest lag, which was not pre-specified, gives p < 0.05. The reason is that d_t has negative sample autocorrelations at lags 3–4 (−0.29, −0.41; see `out/state/checks.md`), so wider windows shrink the long-run variance. I report the pre-specified lag-4 Bartlett result as the primary answer. With T = 40 and a few very large errors (2021–2022), the normal approximation is rough. No formal tests were run at h = 1 or h = 2; those are point comparisons only. ## Limitations and open issues - Errors are computed on the current data vintage. Each quarter is treated as known at the end of that quarter, although publication actually comes about three weeks later. No real-time validity is claimed. - The evaluation window contains the COVID shock and the 2021–2022 inflation surge. A few quarters dominate the squared-error losses, so the results may not carry over to calmer periods. - Only one candidate model was evaluated, so there is no model-search multiplicity in the comparison. The model is simple (linear, constant parameters, deterministic seasonality). - The DM test treats forecasts from estimated models as given (no parameter-estimation adjustment), which is the standard practical usage. - All required outputs were produced (`feasibility` = "complete").