SPB Git

spb/wp29_uqo

Public

# Real-time forecasting of US retail-sales YoY growth (T1-forecast)

# Question

Could the year-over-year (YoY) growth of US retail and food services sales (RSAFS), g_m = 100·ln(L_m/L_{m−12}), have been forecast in real time 1 and 3 months beyond the last published month, using only data published at each of 10 month-end origins (2025-10-31 … 2026-07-31)? Does a simple model of my own design beat the no-change (naive) forecast when errors are measured against the first-release value of each target month? And how large are the revisions between first release and today's data for the h = 1 targets?

# Data and exclusions

  • Real-time design. The forecast made at origin V uses only RSAFS_vintage_V.csv (ALFRED vintage dated V). The target at horizon h is last(V)+h, where last(V) is the last month in that vintage; the actual is yoy_first_release from first_release.csv. RSAFS_current.csv is used only for the revision estimand (d). PAYEMS and UMCSENT files were read and audited but do not enter the chosen model.
  • Vintage → targets (last month, h = 1 target, h = 3 target):
origin V last(V) h=1 target h=3 target
2025-10-31 2025-08 2025-09 2025-11
2025-11-30 2025-09 2025-10 2025-12
2025-12-31 2025-10 2025-11 2026-01
2026-01-31 2025-11 2025-12 2026-02
2026-02-28 2025-12 2026-01 2026-03
2026-03-31 2026-01 2026-02 2026-04
2026-04-30 2026-03 2026-04 2026-06
2026-05-31 2026-04 2026-05 2026-07
2026-06-30 2026-05 2026-06 2026-08
2026-07-31 2026-06 2026-07 2026-09
  • Publication delays observed. The vintages 2025-10-31 through 2026-03-31 all end two months before the origin month (instead of the normal one month), reflecting the delayed Census release calendar in late 2025/early 2026. The 2026-04-30 vintage catches up by adding two months (2026-02 and 2026-03) at once; therefore 2026-03 is never an h = 1 target and 2026-05 is never an h = 3 target, and targets are not equally spaced in time. PAYEMS vintages show similar irregularities (not used).
  • Revisions. The current RSAFS file is 3.8–5.6 % lower in level than the first releases for 2024-06…2026-07 (a benchmark/annual revision first visible in the 2026-09-30 vintage); first-release YoY values are computed inside one vintage, so they are internally consistent, but YoY growth has been revised by up to 2.0 pp.
  • Missing values. No missing values or gaps in any RSAFS/PAYEMS vintage or the current RSAFS file; UMCSENT is empty for 210 pre-1978 months (irrelevant here). No observations were excluded. All data issues are listed in results.json → data_issues.

# Method

  • Baselines (from the vintage dated V): naive g_{last}; seasonal naive g_{T−12}; AR(1) by OLS of g_m on a constant and g_{m−1} for 1993-02 ≤ m ≤ last(V), re-estimated at every origin, iterated h steps.
  • My model — "base-effect drift" (specified before looking at any evaluation result, no estimated parameters). YoY growth at T = last+h is ln L_T − ln L_{T−12}, and ln L_{T−12} is already published at the origin. I forecast ln L_T = ln L_last + h·μ with μ = (ln L_last − ln L_{last−12})/12, the trailing-12-month average monthly log growth. The forecast is 100·(ln L_last + h·μ − ln L_{T−12}) = naive + h·g_last/12 − 100·(ln L_{T−12} − ln L_{last−12}): the naive forecast corrected for the known base effects of the months that drop out of the 12-month window. It uses only the RSAFS vintage V.
  • Evaluation. RMSE and MAE over the 10 origins per horizon against first-release YoY. Diebold–Mariano (model vs naive, squared loss): d_t = e²_naive − e²_model, Bartlett/Newey–West long-run variance with truncation lag h−1, no small-sample correction, two-sided normal p-value. Supplementary: Harvey–Leybourne–Newbold-corrected DM with t(9) reference, and a moving-block bootstrap (block length 3, 10 000 draws, seed 20261030) of RMSE_naive − RMSE_model.
  • Revision estimand (d). Mean over the 10 h = 1 targets of |g^current_T − yoy_first_release_T|.

# Results

Table 1 (out/table1.csv), percent points of YoY growth, n = 10 per cell:

model RMSE h=1 MAE h=1 RMSE h=3 MAE h=3
naive 0.997 0.849 1.420 1.200
seasonal naive 1.675 1.307 1.316 1.066
AR(1) 0.941 0.798 1.187 0.953
base-effect drift (model) 0.550 0.486 1.142 0.934
  • Relative RMSE improvement over naive: 44.8 % at h = 1, 19.6 % at h = 3.
  • DM (model vs naive): h = 1 stat 2.43, p = 0.015 → model_better_significant; h = 3 stat 1.55, p = 0.122 → model_better_not_significant.
  • The model has the lowest RMSE and MAE among all four forecasts at both horizons; AR(1) is only marginally better than naive at h = 1, and the seasonal naive is the worst at h = 1.
  • Mean absolute revision of first-release YoY for the h = 1 targets: 0.548 pp (range 0.17–0.98 pp), i.e. about the same size as the h = 1 model RMSE: today's data differ from the first release by as much as the best real-time forecast does.
  • Figure 1 (out/figure1.png) shows actuals and naive, AR(1) and model forecasts. The model's largest h = 1 miss is 2026-07 (first-release YoY dropped to 4.9 % from 6.5 %; error −1.11 pp), while the naive forecast's largest miss is 2026-05 (+1.89 pp, the surge to 6.65 %); at h = 3 the model, like the naive forecast, under-predicted the 2026-06 surge (actual 6.50 %, model 4.91 %, naive 3.89 %) and under-predicted the 2026-03 and 2026-04 targets by more than naive (errors +1.59 and +2.37 pp vs +1.49 and +1.65 pp).

# Uncertainty

With only 10 origins, inference is fragile. At h = 1 the DM test rejects equal accuracy at 5 % (p = 0.015); the HLN small-sample correction with a t(9) reference gives p = 0.047, just under 5 %; the model beats naive in 8 of 10 origins and the block-bootstrap 95 % interval of RMSE_naive − RMSE_model is [0.29, 0.67] pp (excluding zero). So the h = 1 gain is reasonably convincing, but it rests on 10 points from a period dominated by publication disruptions and should be read as indicative. At h = 3 the point gain (0.28 pp RMSE) is not significant (DM p = 0.12; HLN p = 0.28; bootstrap interval [−0.14, 0.63]; model wins 6 of 10). In addition, h = 3 errors overlap across origins, and a lag-2 Bartlett long-run variance estimated from 10 observations is itself very noisy; the asymptotic normal reference is unreliable at this sample size. The bootstrap with overlapping blocks of 3 out of 10 observations is also only a rough guide.

# Limitations and open issues

  • 10 origins in one unusual period (delayed releases, catch-up vintage, a large benchmark revision just after the sample); results may not generalise.
  • The model was fixed a priori and not tuned, but it is the only model of my own I evaluated; PAYEMS and UMCSENT were not tested as predictors, so the question of whether they add information remains open.
  • "First release" is defined at month-end granularity by the task designer; for 2026-02/2026-03 the first observable value came in the same catch-up vintage.
  • The revision estimand compares with a current vintage that includes a level-shifting benchmark revision; future revisions may change it further.
  • The DM test is reported exactly as specified (no HLN factor); supplementary corrected statistics are in results.json → supplementary.
Files · main
Menu

Theme