F3-conf-01 — Forecasting Canadian monthly GDP y/y growth under publication lags
Question
At the end of each month t (48 origins, 2022-05 to 2026-04), how accurately can year-over-year growth of Canadian monthly real GDP for month t+1 and t+3 be forecast from what is published at that time? And does a model that also uses the more timely LFS employment growth beat the naive forecast (the latest published GDP y/y value, month t−2)?
Data and exclusions
data/canada_gdp_employment.csv: 345 monthly rows, 1998-01 to 2026-09, current vintage (StatCan v65201210 GDP, v2062811 LFS employment). There are no duplicate months and no gaps. GDP is missing only for 2026-08/09 (not yet published). When the y/y columns are recomputed from the levels, they match to within 5e-5 pp (rounding to 4 decimals).- Information rule applied at every origin t: GDP months ≤ t−2 and employment months ≤ t−1 only. The code asserts this. Training targets must also be ≤ t−2. At the last origin (2026-04) the latest GDP month available is 2026-02 and the latest employment month is 2026-03.
- Exclusion (decided in advance, not tuned on evaluation errors): training rows whose target or predictor month falls in 2020-03..2021-06 are dropped from model estimation. In that window the COVID collapse and rebound push y/y values from −16.2% to +18.5%, and these few points would dominate OLS. The naive forecast is unaffected, and no evaluation target falls in that window.
- I used the y/y columns as given.
Method
- Naive: forecast = gdp_yoy(t−2) for both h=1 and h=3.
- Model
ardl_direct_emp: a direct h-step OLS regression, gdp_yoy(s+h) = a + b·gdp_yoy(s−2) + c·emp_yoy(s−1), fitted over pseudo-origins s. At each origin t it is re-estimated on an expanding window (1998 onward) using only pairs whose target month is ≤ t−2 (minus the COVID rows). The forecast plugs in gdp_yoy(t−2) and emp_yoy(t−1). There is no model selection: the specification was fixed before the evaluation was run. In the last estimation sample (origin 2026-04) there are 316 rows for h=1 and 312 for h=3. - Evaluation: RMSE and MAE over the 48 origins, per horizon, computed against current-vintage gdp_yoy. The full ledger is in
out/forecasts.csv(192 rows).
Results
| horizon | RMSE naive | RMSE model | MAE naive | MAE model | 1 − RMSE_m/RMSE_n |
|---|---|---|---|---|---|
| h=1 | 0.814 | 0.741 | 0.642 | 0.603 | 0.089 |
| h=3 | 1.140 | 0.947 | 0.872 | 0.796 | 0.170 |
(Units are percentage points of y/y growth.) The employment-augmented model has lower RMSE and MAE than the naive forecast at both horizons: about 9% lower RMSE at h=1 and 17% at h=3. Both methods over-predict on average over 2022–2026. The mean error is +0.30 (naive) and +0.34 (model) pp at h=1, and +0.46 and +0.53 pp at h=3, consistent with growth slowing over the evaluation window.
Uncertainty
- I ran a Diebold–Mariano test on the squared-error loss differential (model − naive). It uses a Newey–West long-run variance with h+1 lags, because the effective distance from the last observed GDP month is h+2 and errors from consecutive origins overlap. It also applies the Harvey–Leybourne–Newbold small-sample correction and Student-t(47) reference.
- h=1: DM = −1.33, p = 0.19.
- h=3: DM = −1.26, p = 0.22.
- The improvements are therefore not statistically distinguishable from zero at conventional levels with 48 overlapping, autocorrelated origins. The point estimates favour the model, but the evidence is weak.
Limitations and open issues
- The data are the current (revised) vintage. The exercise simulates publication timing only, not the first releases that a forecaster would actually have seen, so no real-time validity is claimed. Revisions to both GDP and LFS could change the results.
- The 48 origins cover a single macro episode (post-COVID disinflation and slowdown), so the results may not generalise.
- I did not run an ablation (the same model without employment). The gain could therefore partly come from the regression structure (mean reversion of y/y growth toward its historical average) rather than from employment itself. Whether employment specifically adds value is not evaluated.
- The COVID exclusion window is a judgement call. I did not try other windows, to avoid tuning on the test sample.
- The HAC/DM inference is approximate with T=48.