SPB Git

spb/wp29_uqo

Public

# 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-01 to 2026-04-01; n_origins, first_origin, last_origin), how well can the year-over-year growth of Canadian monthly real GDP for month t+1 and t+3 be forecast using only data published by then? And does a model that also uses the more timely LFS employment growth beat the naive forecast (the latest published GDP growth, gdp_yoy(t−2))?

# Data and exclusions

  • Input: data/canada_gdp_employment.csv: 345 rows (n_input_rows), 1998-01 to 2026-09. The SHA-256 matches the README. There are no duplicate months and no gaps. GDP is missing only for 2026-08 and 2026-09, which were not yet published. Full audit: out/state/data_audit.md; detected issues: data_issues.
  • Publication lags are enforced inside every origin loop. GDP is used only for months ≤ t−2 and employment only for months ≤ t−1. At the last origin, this means GDP up to 2026-02-01 (last_target_date_available) and employment up to 2026-03-01 (last_predictor_date_available).
  • Exclusions for the last estimation sample (origin 2026-04, h=1; out/exclusions.csv):
    • 7 months removed by the publication-lag rule.
    • 3 removed because their lags are not in the file.
    • 25 removed by a COVID-window rule. Before looking at any out-of-sample errors, I decided to drop training pairs whose target or regressor month falls in 2020-03..2021-12.
    • That leaves 345 − 35 = 310 observations (n_analysed); for h=3 it is 306 (n_analysed_last_origin_h3).
  • The naive forecast drops no observations.

# Method

  • Naive: forecast = gdp_yoy(t−2) for both horizons.
  • Model ardl_emp_direct (model_name, model_description): a direct h-step OLS regression, fitted separately for each horizon and origin:
    • Equation: y(m) = a + b·y(m−h−2) + c·emp_yoy(m−h−1) + e.
    • Estimation: expanding window from 1998, using only target months ≤ t−2, with the COVID-window exclusion above.
    • Forecast: plug in y(t−2) and emp_yoy(t−1). This uses the one-month timeliness advantage of the LFS.
  • Model choices were fixed in advance; I did not tune the model on the evaluation errors.
  • Errors are forecast − actual, measured against current-vintage gdp_yoy.
  • No randomness is involved (random_seed = null).
  • Replication: ~/wp29/venv/bin/python out/analysis.py. It regenerates out/results.json, out/forecasts.csv and out/exclusions.csv.

# Results

horizon RMSE naive MAE naive RMSE model MAE model 1 − RMSE ratio
h=1 0.814 (rmse_naive_h1) 0.642 (mae_naive_h1) 0.743 (rmse_model_h1) 0.604 (mae_model_h1) 0.087 (rel_improvement_rmse_h1)
h=3 1.140 (rmse_naive_h3) 0.872 (mae_naive_h3) 0.902 (rmse_model_h3) 0.753 (mae_model_h3) 0.208 (rel_improvement_rmse_h3)

All values are in percentage points, except the last column, which is a fraction.

  • The employment-augmented model has lower RMSE and MAE than the naive forecast at both horizons: about 9% lower RMSE at h=1 and about 21% lower at h=3.
  • The naive forecast gets worse as the horizon grows, as expected.

# Uncertainty

I compared the two models' squared-error losses with a Diebold–Mariano test (Harvey small-sample correction, HAC variance with h−1 lags, n=48):

  • h=1: DM = −2.03, p = 0.048 (dm_stat_h1, dm_pvalue_h1). This is borderline significant at 5%.
  • h=3: DM = −1.35, p = 0.18 (dm_stat_h3, dm_pvalue_h3). This is not significant. The overlapping 3-step errors and only 48 origins give limited power.

Sensitivity check: keeping the COVID window in the training sample changes the improvement to 0.012 at h=1 (sens_rel_improvement_rmse_nocovidexcl_h1) and 0.304 at h=3 (sens_rel_improvement_rmse_nocovidexcl_h3). The size of the gain therefore depends noticeably on how the pandemic observations are treated. Only its sign holds in both specifications.

# Limitations and open issues

  • The data are the current (revised) vintage. The exercise simulates publication timing only. The errors are not real-time errors, and no real-time validity is claimed.
  • There are 48 origins in a single post-pandemic period (2022–2026), so the evaluation sample is small and the gains are not statistically robust, particularly at h=3.
  • The COVID exclusion window is a judgement call made in advance. The sensitivity results show it matters for how large the gain is.
  • The README says gdp_yoy is empty for the first 12 months, but the file has values from 1998-01. I used the values as given (data_issues).
  • Only one model was evaluated, as the task requires. No model search was done.
Files · main
Menu

Theme