Model card — garch_midas (GARCH-MIDAS, fixed-span, own monthly realized variance, K = 24) — post-registration extension
1. Identity
- model_id:
garch_midas· family: component · tier: A · status: extension (E-01, added 2026-11-09 after the protocol freeze; scored with the frozen protocol, reported separately as exploratory) · impl: custom (src/wp46/models/extensions.py::GARCHMIDAS) - Label: GARCH-MIDAS (own monthly RV, 24 months) · distributions: normal, t (registry
dists; the class also accepts ged/skewt but those pairs are not scored) · information set: the instrument's own daily returns only (Tier A) — the former registry note "requires a low-frequency series outside the pre-registered information set" no longer applies because the long-run component is built from the window's own returns. - Seminal citation:
engle2013stock - Other references:
ghysels2006predicting,ghysels2007midas(MIDAS weighting),engle2008spline(Spline-GARCH, the other multiplicative low-frequency component),engle1999long(additive component GARCH, scored ascgarch11),andersen2003modeling(realized variance as the low-frequency regressor). This card replaces the former unsupported stub (same id).
2. Definition (as coded)
Day t belongs to calendar month $m(t)$ (from the dates in rolling.py: datetime64[M]; the unit tests use 21-day blocks when no calendar is supplied).
$$r_t = \mu + \varepsilon_t,\quad \varepsilon_t = \sqrt{\tau_t g_t},z_t,\qquad g_t = (1 - \alpha - \beta) + \alpha,\frac{\varepsilon_{t-1}^2}{\tau_{t-1}} + \beta,g_{t-1},\qquad g_0 = 1,$$
$$\tau_t = m + \theta\sum_{k=1}^{K}\varphi_k(w),RV^{(m)}{m(t)-k},\qquad RV^{(m)}j = \sum{s:,m(s)=j}(r_s - \bar r)^2,\qquad \varphi_k(w) = \frac{(1 - k/K)^{w-1}}{\sum{j=1}^{K}(1 - j/K)^{w-1}},\quad K = 24,$$
i.e. the fixed-span (rolling-window) GARCH-MIDAS of engle2013stock with the own monthly realized variance as the low-frequency variable and the Beta-polynomial weights with $w_1 = 1$ fixed (one free weight parameter $w \equiv w_2$; $\varphi_K = 0$ exactly for w > 1, so 23 lags carry weight). $\tau_t$ is constant within a month and uses only the K completed months before $m(t)$; $\bar r$ is the sample mean of the window; $\tau$ is floored at 1e-10. Short histories at the start of the window (_tau): months with index $6 \le m < K$ use the available months with renormalised weights $(1 - k/K)^{w-1}$, k = 1..m; months $m < 6$ use $m + \theta\times$ (plain mean of the available monthly RVs, and for the first month its own RV). Innovations: standardised normal or Student-t.
3. Parameter space and admissibility
- Parameters:
mu, m, theta, w, alpha, beta(+nufor t). - Reparameterisation: $m = e^{\theta_0} > 0$; $\theta = e^{\theta_1} > 0$; $w = 1 + e^{\theta_2} > 1$ (monotonically decreasing weights); persistence $s = \sigma(\theta_3)$ and share $\sigma(\theta_4)$ give $\alpha = s,\sigma(\theta_4)$, $\beta = s(1 - \sigma(\theta_4))$, so $\alpha, \beta \ge 0$, $\alpha + \beta < 1$ and $g$ has unit unconditional mean.
- Admissibility flag: $m > 0$, $\theta \ge 0$, $w \ge 1$, $\alpha, \beta \ge 0$, $\alpha + \beta < 1$ — all by construction. $\tau_t > 0$ follows from $m > 0$, $\theta \ge 0$, $RV \ge 0$.
engle2013stockleave the sign of θ free (needed for macro regressors); with a variance regressor θ ≥ 0 is the economically meaningful region and is imposed here.
4. Nesting and relations
- θ → 0: $\tau_t = m$ and $\sigma_t^2 = m,g_t$ is GARCH(1,1) with $\omega = m(1-\alpha-\beta)$ — reached only in the limit ($\theta = e^{\theta_1}$), and w is then unidentified. The nesting test allows a 2.0 log-likelihood slack (§7).
cgarch11(Engle–Lee) is the additive two-component analogue with a daily-updated long-run component;engle2008splinethe deterministic-spline analogue;histvar252/rm2006are parameter-free long-memory proxies.- Relation to Tier B: the long-run regressor is the sum of squared daily returns, not an intraday realized measure, so the model stays in Tier A.
5. Estimation
Shared custom MLE (CustomModel.fit; GARCHMIDAS.fit first builds the day→month map and the monthly RV series from the window): L-BFGS-B (maxiter 2000, ftol 1e-10, gtol 1e-6) from up to three starts (m, θ, w, α, β) ∈ {(0.5v, 0.5, 3, 0.06, 0.90), (0.8v, 0.2, 5, 0.04, 0.93), (0.3v, 0.8, 2, 0.08, 0.85)}, v = sample variance of the demeaned window; μ start = sample mean; ν start 6; stop after the second start if converged; Nelder–Mead polish (maxiter 4000) + final L-BFGS-B if not converged or stalled; A-05 floor vs GARCH(1,1) with the same law (−50 units → two perturbed restarts → degenerate flag). The backcast $s_0$ is computed but not used by the recursion ($g_0 = 1$, $\tau_0$ from the first month's own RV). fit.aux["months"] stores the calendar so that filter/forecast rebuild the same monthly RVs. Point estimates only.
6. Forecasting
GARCHMIDAS.step_forecast (method analytic), with $\tau$ frozen at the last in-sample value $\tau_t$ (the next month's $\tau$ would require the current month's completed RV):
$$\hat g_{t+1|t} = (1-\alpha-\beta) + \alpha,\varepsilon_t^2/\tau_t + \beta g_t,\qquad \hat g_{t+k|t} = (1-\alpha-\beta) + (\alpha+\beta),\hat g_{t+k-1|t},\qquad \hat\sigma^2_{t+k|t} = \tau_t,\hat g_{t+k|t}.$$
Exact under $E z^2 = 1$ for the short-run component; the frozen $\tau$ is an approximation whenever the 22-day horizon crosses a month end. Cumulative h-day variance = sum of the first h steps.
7. Implementation and verification
src/wp46/models/extensions.py::GARCHMIDAS, numbarec_garch_midas, pure-numpy_tau/_month_rv;rolling.pypassesmonths= calendar months of the window dates (special-cased onjob.model_id == "garch_midas").- Tests (
tests/unit/test_extensions.py::test_garch_midas_nests_garch_with_calendar_months): fit (normal) on the GARCH-t fixture with 21-day months converges with log-likelihood ≥GARCH11custom − 2.0; 22-step forecast positive and finite. Not covered bytest_no_lookahead_extensions. - No external-package cross-check (no GARCH-MIDAS in arch 8.0.0 — arch's
MIDASHyperbolicis a MIDAS-weighted ARCH on daily squared returns — nor in rugarch 1.5-6; the R packagemfGARCHis not part of the version-locked toolchain and was not run), no simulation-recovery test, no likelihood identity test. The only external identity in the extension set is HYGARCH(amp = 1) vs arch's FIGARCH (hygarch11.md§7). CLAUDE.md rule 6 is not met in full — henceextensionstatus.
8. Known limitations / failure modes
Post-registration, exploratory. A 1,000-day window holds ≈ 47 calendar months, so with K = 24 the first half of every window uses the shortened-history rules of §2 (renormalised weights for months 6–23; plain means before; the first month uses its own, contemporaneous RV — an in-sample initialisation artefact confined to the first month, with no effect on the forecasts, which are issued ≥ 47 months into the window). $g_t$ divides by $\tau_{t-1}$ rather than $\tau_t$, which differs from engle2013stock only on the first trading day of each month. Monthly RV uses demeaned returns (the paper uses raw squared returns). θ and w are weakly identified when the long-run component is flat (θ small); w is unidentified at θ = 0; $\tau$ frozen over the horizon; no data-driven choice of K (fixed at 24 months). Rolling windows of unequal month counts (holidays, missing days) are handled through the calendar map, not by trading-day counts.
9. Computational footprint
O(T) GARCH recursion plus an O(n_months × K) weight convolution per likelihood evaluation — comparable to cgarch11, i.e. a small multiple of garch11_custom; analytic forecasts are O(22). Far below the fractional extensions. Not timed in the pilot.
10. Literature expectations
engle2013stock find that a realized-variance MIDAS component already captures most of the long-run movement and that macro components add at long horizons; ghysels2006predicting show the value of mixed-frequency variance regressors; engle1999long/engle2008spline document gains of two-component models mainly at long horizons. Under H4 (persistence structure) the expectation is no gain at h = 1 and a possible gain at h = 22 relative to garch11, comparable to cgarch11; under H6 the frozen long-run component should hurt in stressed regimes when the level shifts within the month.