F3-conf-04 — Multi-horizon forecasts of Canadian quarterly CPI inflation
Question
Over 40 expanding-window origins (2015-10-01 to 2025-07-01; first_origin, last_origin, n_origins), does a time-series model beat the seasonal-naive forecast of Canadian quarterly CPI inflation (400·Δln of the quarterly-average, not seasonally adjusted CPI) at horizons 1, 2 and 4? And at h = 4, is the mean squared-error loss differential different from zero once we use a HAC (Diebold–Mariano-type) standard error that allows for the serial correlation created by overlapping 4-step errors?
Data and exclusions
data/cpi_quarterly.csvhas 127 rows anddata/cpi_monthly.csvhas 381 (n_input_rows). Both SHA-256 hashes matchdata/README.md. The quarterly averages, recomputed from the monthly file, match to 3e-7. Inflation recomputed fromcpi_avgmatches to 3e-6, which is just rounding (data_issues).- Exclusions (
out/exclusions.csv): 1995Q1 is dropped because inflation cannot be computed without a previous quarter (127 → 126). No outliers were treated: the 2020 COVID drop and the 2021–22 surge are kept. - The last estimation sample (origin 2025-07-01) covers 122 quarterly inflation observations, 1995Q2–2025Q3 (
n_analysed). The direct regressions at that origin use 121, 120 and 118 rows for h = 1, 2, 4 (n_regression_rows_last_origin). - The full audit is in
out/state/data_audit.md.
Method
- Seasonal-naive baseline: forecast for quarter t+h = y_{t+h−4}.
- Model
dirSAR_bic(model_name,model_description): a direct h-step OLS regression of y_{s+h} on four target-quarter dummies plus p lags y_s, …, y_{s−p+1}. The lag count p ∈ {0,…,4} is chosen by BIC on a common sample, separately at each origin and horizon. The model is then re-estimated on all usable rows, using only quarters ≤ origin. Model selection is part of the expanding window. - Which lags BIC chose (
selected_p_counts):- h = 1: p = 0 at 25 origins, p = 1 at 15.
- h = 2: p = 0 at 17 origins, p = 1 at 23.
- h = 4: p = 0 at all 40 origins. At this horizon the model is therefore just the expanding-window mean of each quarter.
- Errors: e = actual − forecast, computed on the data as given. No real-time validity is claimed.
- h = 4 test:
- The loss differential is d_t = e²_snaive − e²_model.
- The standard error of d̄ uses a Newey–West long-run variance with a Bartlett kernel and truncation lag 4 (
hac_kernel_h4,hac_lags_h4). The lag was fixed before seeing results and is ≥ h−1 = 3. - The p-value is two-sided from the standard normal.
- Sensitivity checks (
sensitivity_dm_h4): Bartlett with lags 3 and 8, rectangular with lag 3, and Student-t(39) p-values. The analysis uses no randomness (random_seed= null).
Results
All errors are in percentage points of annualised inflation. Forecasts are in out/forecasts.csv (240 rows).
| h | RMSE snaive | MAE snaive | RMSE model | MAE model | 1 − RMSE ratio |
|---|---|---|---|---|---|
| 1 | 2.849 (rmse_snaive_h1) |
2.137 (mae_snaive_h1) |
2.199 (rmse_model_h1) |
1.561 (mae_model_h1) |
0.228 (rel_improvement_rmse_h1) |
| 2 | 2.847 (rmse_snaive_h2) |
2.126 (mae_snaive_h2) |
2.364 (rmse_model_h2) |
1.536 (mae_model_h2) |
0.170 (rel_improvement_rmse_h2) |
| 4 | 2.882 (rmse_snaive_h4) |
2.181 (mae_snaive_h4) |
2.353 (rmse_model_h4) |
1.602 (mae_model_h4) |
0.184 (rel_improvement_rmse_h4) |
At all three horizons the model's point RMSE and MAE are lower than those of the seasonal-naive forecast.
At h = 4:
- Mean loss differential d̄ = 2.770 squared pp (
loss_diff_mean_h4), with HAC SE 1.907 (loss_diff_se_h4). - DM statistic 1.45 (
dm_stat_h4), two-sided p = 0.146 (dm_pvalue_h4).
At conventional levels, the h = 4 improvement cannot be distinguished from zero.
Uncertainty
-
The h = 4 conclusion depends on the HAC choice (
sensitivity_dm_h4):HAC choice p-value Bartlett, lag 3 0.197 Rectangular, lag 3 0.114 Bartlett, lag 4 (primary) 0.146 (t(39): 0.154) Bartlett, lag 8 0.024 The lag-8 result means the estimated long-run variance shrinks when longer lags are included, i.e. there are negative autocorrelations at longer lags. I keep the pre-specified lag 4 as the main result and do not choose a lag after seeing the results.
-
h = 1 and h = 2 are also not significant. These supplementary DM tests (Bartlett, lag = h;
dm_tests_h1_h2_bartlett_L_h) give p = 0.105 at h = 1 and 0.269 at h = 2. So the point improvements at those horizons are not statistically established either. -
The sample is small. It has 40 overlapping errors and a few extreme quarters (2020–2022), which dominate squared losses. The normal approximation for the DM statistic is therefore rough.
Limitations and open issues
- There is a single evaluation window of 40 origins, dominated by the COVID and 2021–22 inflation episodes. The ranking could differ in calmer periods.
- The comparison is pseudo-out-of-sample on the current vintage, not real-time.
- The model is chosen by me. Alternatives (seasonal ARIMA, iterated AR) were not evaluated, and no search over models was done on the evaluation sample.
- At h = 4 the selected model is just expanding-window quarterly means. Its edge over seasonal-naive comes from averaging out noise in the single year-ago value.
- DM-test significance at h = 4 is sensitive to the HAC truncation lag, as reported above.
- Everything required was produced (
feasibility= "complete").