# F3-conf-04 — Multi-horizon forecasts of Canadian quarterly CPI inflation ## Question Across 40 rolling quarterly origins, 2015-10-01 to 2025-07-01 (`n_origins`, `first_origin`, `last_origin`), does a time-series model beat the seasonal-naive forecast of annualised, not seasonally adjusted, quarterly CPI inflation at h = 1, 2 and 4? And at h = 4, is the mean squared-error loss differential distinguishable from zero once we use a standard error that allows for the serial correlation caused by overlapping forecasts? ## Data and exclusions Input: `data/cpi_quarterly.csv`, 127 rows (`n_input_rows`). `data/cpi_monthly.csv` (381 rows) was used only to cross-check the file. Both SHA-256 hashes match `data/README.md`. The quarterly file agrees with the monthly file: quarterly averages match to within 3.3e-7, and recomputing inflation reproduces `infl_annualised` to within 3.3e-6. There are no duplicates and no gaps (details in `out/state/data_audit.md`). The one data issue (`data_issues`) is that inflation is undefined for 1995Q1. Exclusions are listed in `out/exclusions.csv`: 127 → 126 (drop 1995Q1) → 122 (quarters after the last origin are not used for estimation) → 118 (first 4 quarters used to build lags). So the last estimation sample has 118 observations (`n_analysed`). Quarters after an origin are used only as realised targets for that origin. ## Method - **Baseline (`snaive`):** the forecast for quarter t+h is the inflation value of quarter t+h−4. - **Model (`sar_aic`, `model_description`):** OLS regression of inflation on four quarterly seasonal intercepts plus p own lags. At every origin, p ∈ {0,…,4} is chosen by AIC on a common sample. The estimation window expands from 1995Q2 to the origin and uses only quarters ≤ origin. Multi-step forecasts are made by iterating the model forward. Across origins AIC chose p = 1 fifteen times and p = 2 twenty-five times (`supp_selected_p_counts`). - **Evaluation:** errors are actual − forecast. RMSE and MAE are computed over the 40 origins for each horizon. - **Diebold–Mariano-type test at h = 4:** d_t = e²_snaive − e²_model. Its long-run variance uses a Newey–West (Bartlett) estimator with truncation lag 3 = h − 1 (`hac_lags_h4`, `hac_kernel_h4`). The test uses a two-sided normal p-value. - The script is deterministic and draws no random numbers (`random_seed` = null). ## Results | h | RMSE snaive | RMSE model | MAE snaive | MAE model | 1 − RMSE ratio | |---|---|---|---|---|---| | 1 | 2.849 (`rmse_snaive_h1`) | 2.192 (`rmse_model_h1`) | 2.137 (`mae_snaive_h1`) | 1.519 (`mae_model_h1`) | 0.231 (`rel_improvement_rmse_h1`) | | 2 | 2.847 (`rmse_snaive_h2`) | 2.460 (`rmse_model_h2`) | 2.126 (`mae_snaive_h2`) | 1.550 (`mae_model_h2`) | 0.136 (`rel_improvement_rmse_h2`) | | 4 | 2.882 (`rmse_snaive_h4`) | 2.340 (`rmse_model_h4`) | 2.181 (`mae_snaive_h4`) | 1.594 (`mae_model_h4`) | 0.188 (`rel_improvement_rmse_h4`) | The seasonal AR has lower RMSE and lower MAE than seasonal-naive at all three horizons in this sample. At h = 4, the mean loss differential is 2.83 squared pp (`loss_diff_mean_h4`), with a HAC SE of 2.08 (`loss_diff_se_h4`). This gives DM = 1.36 (`dm_stat_h4`) and a two-sided p = 0.174 (`dm_pvalue_h4`). ## Uncertainty At the pre-specified lag of 3 with a Bartlett kernel, the h = 4 improvement is **not** statistically distinguishable from zero at conventional levels (`dm_pvalue_h4`). The Harvey–Leybourne–Newbold small-sample-corrected p-value is 0.22 (`supp_hln_pvalue_h4`). The SE depends heavily on the HAC choice (`supp_dm_se_sensitivity_h4`): it is 1.85 at Bartlett lag 4, 1.37 at Bartlett lag 6, and 1.70 with a rectangular kernel at lag 3. All of these are smaller than the lag-3 Bartlett SE because the loss differential has negative autocorrelation at higher orders. Lag 3 was fixed before looking at results and is the value reported. The sensitivity means the conclusion is fragile, not robust, and choosing a lag after seeing the results would be specification searching. No significance tests were run at h = 1 or h = 2, so the improvements there are point estimates only. ## Limitations and open issues - Only 40 origins, and the period includes the 2020 pandemic shock and the 2021–22 inflation surge. A few large errors can dominate squared-error loss. - With T = 40, the asymptotic normal approximation of the DM test is rough. - The errors use the current data vintage. CPI is essentially unrevised, but no claim of real-time validity is made. A quarter is treated as known at the end of that quarter, whereas publication actually comes about three weeks later. - Only one model was tried, so there is no multiple-model search to adjust for. - `supp_*` keys are supplementary and not required by the task.