Model card — realgarch11 (Realized GARCH(1,1), log-linear, Hansen–Huang–Shek)
1. Identity
- model_id:
realgarch11· family: realized (Tier B) · tier: B · status: implemented · impl: custom (src/wp46/models/custom.py::RealGARCH11) - Label: Realized GARCH(1,1), log-linear · distributions: normal, t (for $z_t$; the measurement error $u_t$ is always Gaussian)
- Seminal citation:
hansen2012realized - Other references:
hansen2016exponential(Realized EGARCH, unsupported),hansen2014realized(Realized Beta GARCH),shephard2010realising(HEAVY),engle2002new(GARCH-X); literature-matrix caveat #7 (the measurement equation is part of the likelihood → in-sample log-likelihoods are not comparable with GARCH).
2. Definition
With $x_t$ the realized measure (rv5ss_on, percent², observed at the end of day t; only $x_{t-1}$ enters $\sigma_t^2$):
$$r_t = \mu + \sigma_t z_t,\qquad \log\sigma_t^2 = \omega + \beta,\log\sigma_{t-1}^2 + \gamma,\log x_{t-1},$$
$$\log x_t = \xi + \varphi,\log\sigma_t^2 + \tau_1 z_t + \tau_2,(z_t^2 - 1) + u_t,\qquad u_t \sim \text{N}(0, \sigma_u^2) .$$
rec_realgarch: $\log\sigma_0^2 = \log s_0$ (backcast), $x$ floored at 1e-8 before the log; the fit fails (FloatingPointError → objective 1e10) if $|\log\sigma_t^2| > 50$. Joint log-likelihood $\ell = \sum_t\big[\log f_z(z_t) - \tfrac12\log\sigma_t^2\big] + \sum_t\big[-\tfrac12\log(2\pi\sigma_u^2) - u_t^2/(2\sigma_u^2)\big]$. Innovations $z_t$: normal or standardised t(ν).
3. Parameter space and admissibility
- Parameters:
mu, omega, beta, gamma, xi, phi, tau1, tau2, log_sigma_u(+nu). All unconstrained in the optimizer (identity transform; $\sigma_u = e^{\texttt{log_sigma_u}}$). - Admissibility flag: $|\beta + \varphi\gamma| < 1$ (stationarity of the reduced-form AR(1) for $\log\sigma_t^2$ obtained by substituting the measurement equation). No positivity constraints are needed (log specification).
4. Nesting and relations
Realized GARCH reduces to a GARCH-type model when the measurement equation is dropped; in log-linear form with $\gamma = 0$ it is a log-GARCH without ARCH term. HEAVY uses $x_{t-1}$ in levels without a measurement equation; GARCH-X adds $x_{t-1}$ to a GARCH(1,1). Realized EGARCH (unsupported) generalises the leverage function and allows several measures.
5. Estimation
Custom MLE (CustomModel.fit with extra_loglik adding the measurement-equation terms): L-BFGS-B on the 8 + 1 (+1) raw parameters (maxiter 3000, ftol 1e-10, gtol 1e-6) from three starts (ω, β, γ, ξ, φ, τ₁, τ₂, log σ_u) ∈ {(0.04 ℓ̄, 0.55, 0.41, −0.1, 1.0, −0.07, 0.07, log 0.4), (0.1 ℓ̄, 0.7, 0.28, 0, 0.95, −0.05, 0.05, log 0.5), (0.02 ℓ̄, 0.4, 0.55, −0.2, 1.05, −0.1, 0.1, log 0.35)} with $\bar\ell$ = mean of $\log x$, Nelder–Mead polish on failure; μ start = sample mean, ν start 6; backcast $s_0$ arch-style on the demeaned returns. Point estimates only; the reported loglik is the joint return + measurement log-likelihood.
6. Forecasting
RealGARCH11.step_forecast: h = 1 analytic, $\log\hat\sigma^2_{t+1|t} = \omega + \beta\log\sigma_t^2 + \gamma\log x_t$. h > 1 by simulation (analytic_multistep = False): 2,000 paths; for k = 2..22 draw $z \sim f_z$ (fitted law, distributions.rvs) and $u \sim$ N(0, σ_u²) with np.random.default_rng(46 + origin) (seeded), set $\log x_{t+k-1} = \xi + \varphi\log\sigma^2_{t+k-1} + \tau_1 z + \tau_2(z^2-1) + u$, then $\log\sigma^2_{t+k} = \omega + \beta\log\sigma^2_{t+k-1} + \gamma\log x_{t+k-1}$, clipped to ±30; $\hat\sigma^2_{t+k|t}$ = path mean of $\exp(\log\sigma^2_{t+k})$. Cumulative = sum over k ≤ h. Method: simulation. (The class docstring mentions a VAR-type recursion; the code simulates.)
7. Implementation
src/wp46/models/custom.py::RealGARCH11(numbarec_realgarch).- Cross-check: attempted against rugarch
realGARCH(normal,realizedVol = sqrt(x)) on the shared fixture, but rugarch did not converge (results/metrics/rugarch_crosscheck.json["rugarch"]["realgarch11_n"] = {"converged": false}), socomparison.realgarch11_n.diff = null; ours: joint log-likelihood −4989.2126, converged. No library cross-check is therefore available. - Tests:
tests/simulation/test_recovery.py::test_realgarch_recovery(T = 4,000, normal, truth (0.06, 0.55, 0.40, −0.2, 1.0, −0.07, 0.07, 0.4): β, γ, φ within 0.1, σ_u within 0.05);tests/unit/test_custom_models.py::test_realized_models_fit_on_synthetic_measure(converged, positive finite forecasts); pilotrealgarch11__normal: 207/207 refitsok, 1,032/1,032 forecastsokon CL.
8. Known limitations / failure modes
No parameter constraints → the optimizer can leave the stationary region (flag admissible = False); the simulation step compounds $\exp(\cdot)$ of Gaussian-like paths (mean of log-normal paths grows with the simulated variance, sensitive to τ₂ and σ_u); $x_{t-1}$ imputed by $r_{t-1}^2$ on invalid sessions and floored at 1e-8 (log of a tiny number); the joint likelihood is dominated by the measurement equation (not comparable with GARCH); the t option applies to $z_t$ only.
9. Computational footprint
Estimation: 9–10 free parameters, one numba pass per evaluation; pilot median fit time per refit (normal) 0.0269 s (CL) / 0.0279 s (EURUSD) — the second most expensive pilot model after aparch11. Forecasting by simulation (21 × 2,000 draws of z and u per origin).
10. Literature expectations
hansen2012realized report substantial likelihood and forecast gains over GARCH when a realized measure is available; lyocsa2021stock and kourtis2016international confirm the information advantage of intraday data at h = 1 that decays with the horizon. Pre-registered H3: Tier B beats Tier A at h = 1 (pooled ratio < 0.9), advantage shrinking at h = 22; the matrix lists Realized GARCH together with HEAVY and HAR as the Tier B contenders.