SPB Git

spb/wp29_uqo

Public

# F3-conf-04 — Multi-horizon forecasts of Canadian quarterly CPI inflation

# Question

Over 40 rolling quarterly origins, 2015-10-01 to 2025-07-01 (n_origins, first_origin, last_origin), does a time-series model forecast Canadian quarterly CPI inflation (400 × Δln of the quarterly-average NSA CPI) better than the seasonal-naive forecast at horizons 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, 1995Q1–2026Q3 (n_input_rows). data/cpi_monthly.csv: 381 rows (n_input_rows), used only for the provenance audit. Both SHA-256 hashes match data/README.md. Averaging the monthly index by quarter reproduces cpi_avg (max abs diff 3e-7), and 400·Δln reproduces infl_annualised (max abs diff 3e-6). Neither file has duplicates or gaps (details in out/state/data_audit.md).
  • Exclusions (out/exclusions.csv): one row removed, 1995Q1, because its inflation value is undefined. That leaves 126 analysable quarters (data_issues).
  • The 2022Q2 value (12.15 %) is a genuine part of the inflation surge. I kept it (data_issues).
  • The last estimation sample (origin 2025Q3) has 121 regression observations (n_analysed).

# Method

  • Baseline (seasonal naive): the forecast for target t+h is the value at t+h−4.
  • Model (model_name = ar_seas_aic): model_description. The regression has four quarter-of-year intercepts plus p lags of inflation. At each origin, AIC picks p from 0 to 8, comparing all candidates on a common sample. The chosen model is then re-estimated by OLS on every available quarter up to and including the origin. Forecasts for h = 2 and 4 are iterated from the one-step equation. At each origin the code cuts the series at the origin before doing any estimation or selection, so no later quarter is used (this is asserted in out/analysis.py). AIC chose p = 1 or 2 across origins (selected_lags_by_origin).
  • Evaluation: errors are e = actual − forecast. RMSE and MAE are taken over the 40 origins at each horizon.
  • h = 4 test (Diebold–Mariano): d_t = e²_snaive,t − e²_model,t. Its mean is loss_diff_mean_h4, and its standard error comes from a Bartlett-kernel (Newey–West) long-run variance (hac_kernel_h4) with truncation lag 3 = h−1 (hac_lags_h4). The test statistic is dm_stat_h4 and its p-value dm_pvalue_h4 is two-sided against N(0,1). I fixed the lag and kernel before seeing any results. Nothing in the analysis is random (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)

RMSE and MAE are in percentage points of annualised inflation. Over this window the model has lower RMSE and MAE than the seasonal-naive forecast at all three horizons. The RMSE reductions are 23 %, 13 % and 19 %.

At h = 4, the mean loss differential is d̄ = 2.818 squared pp (loss_diff_mean_h4), with HAC SE 2.086 (loss_diff_se_h4). That gives DM = 1.351 (dm_stat_h4) and a two-sided p = 0.177 (dm_pvalue_h4). The model's squared error was smaller at 29 of the 40 origins (n_loss_diff_positive_h4). At conventional levels, the h = 4 improvement cannot be distinguished statistically from zero.

# Uncertainty

  • The conclusion depends on the HAC choices (sensitivity_h4). With Bartlett lag 4, p = 0.128. With a rectangular kernel at lag 3, p = 0.097. With the Harvey–Leybourne–Newbold small-sample correction and t(39) reference, p = 0.225. With Bartlett lag 6, p = 0.041. The SE shrinks as the lag grows, which means d_t has negative autocorrelations at higher lags. The lag-6 result was not pre-specified and is the only one below 0.05; I treat it as a sensitivity check, not as evidence. The pre-specified result (lag 3, p = 0.18) stands.
  • 40 overlapping observations is a small sample for long-run-variance estimation, so the normal approximation is rough. Squared-error losses are also strongly affected by the 2021–2023 inflation surge, so a handful of quarters drive much of d̄.
  • No uncertainty is reported for the RMSE and MAE at h = 1 and 2. The task only asks for a formal test at h = 4.

# Limitations and open issues

  • I chose one model ahead of time and did not compare alternatives (SARIMA, direct forecasts) on the test window, so there is no search-induced bias. However, the results describe only this model.
  • The errors are computed on the current data vintage, and a quarter is treated as known at the end of that quarter. No real-time validity is claimed. Actual CPI publication comes about three weeks later, and basket updates may have small effects.
  • The DM test compares forecasts, not models. Both forecasts come from expanding-window estimates, and the model is not nested in the seasonal-naive forecast in any parameter sense, so applying standard DM asymptotics is reasonable but approximate.
  • Feasibility: complete (feasibility).
Files · main
Menu

Theme