SPB Git

Repository Public Research preview

garch11.md 7.0 KB 43 lines markdown

1# Model card — `garch11` (GARCH(1,1), the benchmark)23## 1. Identity4- **model_id:** `garch11` · **family:** classical · **tier:** A · **status:** implemented · **benchmark: true** · **impl:** arch 8.0.0 (`GARCH(p=1, o=0, q=1)`)5- **Label:** GARCH(1,1) · **distributions:** normal, t, ged, skewt6- **Seminal citation:** `bollerslev1986generalized`7- **Other references:** `engle1982autoregressive` (ARCH); `nelson1990stationarity` (strict stationarity); `bollerslev1992quasi`, `lee1994asymptotic`, `lumsdaine1996consistency` (QMLE theory); `hansen2005forecast` ("does anything beat a GARCH(1,1)?"); `engle2001garch`, `bollerslev2010glossary` (nomenclature); distributions `bollerslev1987conditionally`, `nelson1991conditional`, `hansen1994autoregressive`.89## 2. Definition10$$r_t = \mu + \varepsilon_t,\quad \varepsilon_t = \sigma_t z_t,\qquad \sigma_t^2 = \omega + \alpha\,\varepsilon_{t-1}^2 + \beta\,\sigma_{t-1}^2 ,$$11with $\sigma_0^2$ initialised as $\omega + (\alpha+\beta)\cdot\text{backcast}$ (arch `garch_recursion`: both pre-sample terms use the backcast). Innovations $z_t$ i.i.d. with unit variance: normal; Student-t(ν), ν > 2; GED(ν); Hansen skew-t(η, λ). Order convention: arch's `p` = ARCH order, `q` = GARCH order (Bollerslev's (p,q) is the reverse; irrelevant for (1,1)).1213## 3. Parameter space and admissibility14- Parameters: `mu, omega, alpha[1], beta[1]` (+ `nu` or `eta, lambda`).15- arch bounds: $\omega \in [10^{-8}v, 10v]$ ($v = \overline{\varepsilon^2}$), $\alpha, \beta \in [0, 1]$; linear constraints $\omega > 0$, $\alpha \ge 0$, $\beta \ge 0$, $\alpha + \beta < 1$ (SLSQP inequality constraints; no reparameterisation). Distribution bounds: ν ∈ [2.05, 500] (t), ν ∈ [1.01, 500] (GED), η ∈ [2.05, 300], λ ∈ [−1, 1].16- Admissibility flag: $\alpha + \beta < 1$ (covariance stationarity, unconditional variance $\omega/(1-\alpha-\beta)$). The strict-stationarity condition $E\log(\alpha z^2 + \beta) < 0$ (`nelson1990stationarity`) is weaker and not used as the flag.17- (The custom cross-check class `garch11_custom` in `src/wp46/models/custom.py` uses the reparameterisation $\omega = e^{\theta_0}$, $s = \alpha+\beta = \sigma(\theta_1)$, $\alpha = s\,\sigma(\theta_2)$; it is not the registry implementation.)1819## 4. Nesting and relations20Nests `constvar` (α = β = 0) and ARCH(1) (β = 0). Nested in `garch21`, `garch12`, `gjr11` (γ = 0), `nagarch11` (θ = 0), `qgarch11` (γ = 0), `aparch11` (δ = 2, γ = 0), `avgarch11`/`tarch11` only through the power change (δ = 1 vs 2, not nested), `cgarch11` (φ = 0, ρ = 0 collapse), `figarch11` (d = 0), `garchx_rv11` (γ = 0), `msgarch2` (identical regimes), and is the ν → ∞ limit of `gas_t11` up to reparameterisation. `igarch11` is the boundary α + β = 1; `ewma094` additionally sets ω = 0.2122## 5. Estimation23arch `ConstantMean` + `GARCH(1,0,1)` + distribution; `fit(disp="off", options={"maxiter": 1000})` → SLSQP on the exact log-likelihood $\sum_t[\log f_z(\varepsilon_t/\sigma_t) - \tfrac12\log\sigma_t^2]$ with bounds/constraints of §3 (`src/wp46/models/arch_models.py::ArchModel.fit`). Starting values: arch grid α ∈ {0.01, 0.05, 0.1, 0.2} × persistence ∈ {0.5, 0.7, 0.9, 0.98}, $\omega = (1-\text{pers})\,\overline{\varepsilon^2}$, best Gaussian log-likelihood; distribution start ν from arch. Initial variance: arch backcast (exponentially weighted mean of the first min(75, T) squared residuals, weights ∝ 0.94ⁱ). Retries: ≤ 2 restarts (previous estimate × (0.9 + 0.2(i+1)/3), maxiter 2000) if `convergence_flag ≠ 0`; the better of the fits is kept. arch warns (DataScaleWarning) but does not rescale when var(ε) ∉ [0.1, 10 000) (percent units keep equities/FX inside the range; very low-volatility instruments may warn). Standard errors: arch's robust covariance is computed by arch but **only point estimates are used** in the rolling benchmark (`rolling.py`: refit every 5 days, daily filtering with `am.fix(params)`).2425## 6. Forecasting26arch `GARCH._analytic_forecast`:27$$\hat\sigma^2_{t+1|t} = \omega + \alpha\varepsilon_t^2 + \beta\sigma_t^2,\qquad \hat\sigma^2_{t+k|t} = \omega + (\alpha + \beta)\,\hat\sigma^2_{t+k-1|t},\ k = 2..22,$$28exact under $E[z^2] = 1$ for every supported innovation law. Cumulative $h$-day variance $=\sum_{k\le h}\hat\sigma^2_{t+k|t}$. Method: `analytic`. The custom class reproduces arch's 22-step forecasts to relative 1e-10 (`test_custom_garch_equals_arch_loglik_and_forecast`).2930## 7. Implementation31- `src/wp46/models/arch_models.py` (`SPECS["garch11"]`), arch 8.0.0 (`sheppard2025arch`).32- Cross-check (`results/metrics/rugarch_crosscheck.json`, rugarch 1.5-6, fixture `tests/replication/fixture_returns.csv`: T = 3,000 GJR-t data): `garch11_t` log-likelihood −3379.4618 (ours) vs −3379.5028 (rugarch), **difference +0.0410**; parameters agree (α 0.07667 vs 0.07664, β 0.89790 vs 0.89793, ν 6.916 vs 6.923). `garch11_skewt`: −3379.2756 vs −3379.3148, **+0.0392** — note rugarch `sstd` is Fernández–Steel skewing while arch is Hansen's skew-t (`fernandez1998bayesian` vs `hansen1994autoregressive`): the two likelihoods are not the same density, only the orders of magnitude are compared.33- Tests: `tests/replication/test_rugarch.py::test_rugarch_crosscheck` (asserts |Δℓ| < 0.5 and |Δα|, |Δβ| < 5e-3); `tests/unit/test_custom_models.py::test_custom_garch_equals_arch_loglik_and_forecast` (recursion identical to arch's `compute_variance` to 1e-9, forecasts to 1e-10); `tests/integration/test_rolling_driver.py::test_driver_refit_cadence_and_outputs` (driver with `garch11`, normal); `tests/unit/test_distributions.py` (densities equal arch's to 1e-12).3435## 8. Known limitations / failure modes36Near-integrated estimates ($\alpha + \beta \to 1$) on long windows or after breaks (`lamoureux1990persistence`, `hillebrand2005neglecting`) produce boundary optima and the flag `admissible = False` when SLSQP ends with $\alpha + \beta \ge 1$ (constraint is strict only up to solver tolerance); in the pilot, `garch11__t` on SPY had 26/202 refits flagged inadmissible in an earlier version of `pilot_report.json` (the current file holds CL and EURUSD: 207/207 `ok`). ω is poorly identified when persistence is high (small ω, large unconditional variance). Symmetric response to news (no leverage) — the main mis-specification for equities.3738## 9. Computational footprint39Analytic recursion and forecasts; 4–6 parameters. Pilot fit time per refit (`results/metrics/pilot/pilot_report.json`, laptop, 1,000-obs window, median s): normal 0.0042 (CL) / 0.0049 (EURUSD); t 0.0065 / 0.0074. The cheapest estimated dynamic model of the registry.4041## 10. Literature expectations42`hansen2005forecast`: nothing beats GARCH(1,1) on DM/$ (FX), while leverage models do on IBM (equities). `awartani2005predicting`, `brownlees2011practical`: asymmetric models beat GARCH(1,1) on equity indices, more so in crises. `marcucci2005forecasting`: regime models win at short horizons only. The literature matrix (§G) frames GARCH(1,1) as the benchmark that the MCS/SPA machinery tests against; the pre-registered hypotheses H1–H6 (`docs/preregistered_protocol.md`) are all stated relative to this model.43
Files main
Menu

Theme