Repository Public Research preview
1# Model card — `garch_midas` (GARCH-MIDAS, fixed-span, own monthly realized variance, K = 24) — post-registration extension23## 1. Identity4- **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`)5- **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.6- **Seminal citation:** `engle2013stock`7- **Other references:** `ghysels2006predicting`, `ghysels2007midas` (MIDAS weighting), `engle2008spline` (Spline-GARCH, the other multiplicative low-frequency component), `engle1999long` (additive component GARCH, scored as `cgarch11`), `andersen2003modeling` (realized variance as the low-frequency regressor). This card replaces the former unsupported stub (same id).89## 2. Definition (as coded)10Day 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).11$$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,$$12$$\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,$$13i.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.1415## 3. Parameter space and admissibility16- Parameters: `mu, m, theta, w, alpha, beta` (+ `nu` for t).17- 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.18- 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$. `engle2013stock` leave the sign of θ free (needed for macro regressors); with a variance regressor θ ≥ 0 is the economically meaningful region and is imposed here.1920## 4. Nesting and relations21- θ → 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).22- `cgarch11` (Engle–Lee) is the additive two-component analogue with a daily-updated long-run component; `engle2008spline` the deterministic-spline analogue; `histvar252`/`rm2006` are parameter-free long-memory proxies.23- 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.2425## 5. Estimation26Shared 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.2728## 6. Forecasting29`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):30$$\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}.$$31Exact 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.3233## 7. Implementation and verification34- `src/wp46/models/extensions.py::GARCHMIDAS`, numba `rec_garch_midas`, pure-numpy `_tau`/`_month_rv`; `rolling.py` passes `months` = calendar months of the window dates (special-cased on `job.model_id == "garch_midas"`).35- 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 ≥ `GARCH11` custom − 2.0; 22-step forecast positive and finite. Not covered by `test_no_lookahead_extensions`.36- **No external-package cross-check** (no GARCH-MIDAS in arch 8.0.0 — arch's `MIDASHyperbolic` is a MIDAS-weighted ARCH on daily squared returns — nor in rugarch 1.5-6; the R package `mfGARCH` is 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 — hence `extension` status.3738## 8. Known limitations / failure modes39Post-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.4041## 9. Computational footprint42O(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.4344## 10. Literature expectations45`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.46