Model card — gjr11 (GJR-GARCH(1,1))
1. Identity
- model_id:
gjr11· family: asymmetric · tier: A · status: implemented · impl: arch 8.0.0 (GARCH(p=1, o=1, q=1)); a custom twingjr11_custom(src/wp46/models/custom.py::GJR11) exists for cross-checks and simulation tests only. - Label: GJR-GARCH(1,1) · distributions: normal, t, ged, skewt
- Seminal citation:
glosten1993relation - Other references:
engle1993measuring(news-impact curve, sign-bias tests),zakoian1994threshold(TGARCH — not the same model, seetarch11),ling2002stationarity(moments of asymmetric GARCH),hansen2005forecast,brownlees2011practical,bollerslev2010glossary(naming: EViews "TARCH" = GJR).
2. Definition (arch parameterisation)
$$r_t = \mu + \varepsilon_t,\ \varepsilon_t = \sigma_t z_t,\qquad \sigma_t^2 = \omega + \alpha,\varepsilon_{t-1}^2 + \gamma,\varepsilon_{t-1}^2,\mathbb 1{\varepsilon_{t-1} < 0} + \beta,\sigma_{t-1}^2 .$$
arch garch_recursion with power 2: pre-sample terms use the backcast for $\varepsilon^2$ and $\sigma^2$ and $0.5\times$ backcast for the asymmetric term. Innovations: normal, t, GED, Hansen skew-t.
3. Parameter space and admissibility
- Parameters:
mu, omega, alpha[1], gamma[1], beta[1](+ distribution). - arch bounds: $\omega \in [10^{-8}v, 10v]$, $\alpha \in [0,1]$, $\gamma \in [-1, 2]$, $\beta \in [0,1]$; linear constraints $\omega > 0$, $\alpha \ge 0$, $\alpha + \gamma \ge 0$, $\beta \ge 0$, $\alpha + \tfrac12\gamma + \beta < 1$ (arch uses the symmetric weight ½ in the optimizer constraint for every distribution).
- Admissibility flag (
ArchModel.fit): $\alpha + \beta + 0.5\gamma < 1$ — the covariance-stationarity condition under a symmetric innovation law. For the skew-t the exact condition is $\alpha + \beta + \kappa\gamma < 1$ with $\kappa = E[z^2\mathbb 1{z<0}] \neq 0.5$ (distributions.neg_half_moment); it is used by the custom twin (GJR11.admissible) but not by the registry implementation (recorded in_discrepancies.md). - Custom twin reparameterisation: $\omega = e^{\theta}$, persistence $s = \sigma(\theta)$, softmax shares of $s$ among $(\alpha, \kappa\gamma, \beta)$.
4. Nesting and relations
Nests garch11 (γ = 0). Special case of aparch11 with δ = 2 and $\gamma_{APARCH}$ mapped to the GJR indicator form only approximately (APARCH uses $(|\varepsilon| - \gamma\varepsilon)^\delta$, which for δ = 2 is $(1\mp\gamma)^2\varepsilon^2$: GJR corresponds to $\alpha_{GJR} = \alpha(1-\gamma)^2$, $\alpha_{GJR}+\gamma_{GJR} = \alpha(1+\gamma)^2$). Not the same as tarch11 (threshold on σ, power 1). Same news-impact asymmetry as nagarch11/qgarch11 but with a kink rather than a shift.
5. Estimation
arch ConstantMean + GARCH(1,1,1) + distribution; SLSQP (fit(disp="off", options={"maxiter": 1000})) with the bounds/constraints of §3; starting values from arch's grid (α ∈ {0.01, 0.05, 0.1, 0.2}, γ same grid, persistence ∈ {0.5, 0.7, 0.9, 0.98}; best Gaussian log-likelihood); backcast = exponentially weighted mean of the first min(75, T) squared residuals (0.94ⁱ); ≤ 2 restarts (previous estimate × (0.9 + 0.2(i+1)/3), maxiter 2000) when convergence_flag ≠ 0. Only point estimates are used in the rolling benchmark; daily filtering with am.fix(params).
6. Forecasting
arch GARCH._analytic_forecast (power 2): $\hat\sigma^2_{t+1|t} = \omega + \alpha\varepsilon_t^2 + \gamma\varepsilon_t^2\mathbb 1{\varepsilon_t<0} + \beta\sigma_t^2$ and, for $k \ge 2$,
$$\hat\sigma^2_{t+k|t} = \omega + (\alpha + 0.5,\gamma + \beta),\hat\sigma^2_{t+k-1|t},$$
because arch sets the future asymmetric term to $0.5\times$ the variance forecast (_asym_resids[h+m] = sqrt(0.5 * forecast)). This is exact for symmetric $z$ (normal, t, GED) and approximate for the skew-t (exact weight $\kappa = E[z^2\mathbb 1{z<0}]$, > 0.5 for λ < 0). The custom twin implements $\hat\sigma^2_{t+k|t} = \omega + (\alpha + \kappa\gamma + \beta)\hat\sigma^2_{t+k-1|t}$ with κ from neg_half_moment (D-09 describes this κ-version; the scored gjr11 is the arch version). Cumulative = sum over k ≤ h. Method: analytic.
7. Implementation
src/wp46/models/arch_models.py(SPECS["gjr11"]), arch 8.0.0 (sheppard2025arch); custom twincustom.py::GJR11(model_id = "gjr11_custom", not in the registry).- Cross-check (
results/metrics/rugarch_crosscheck.json, rugarchgjrGARCH, t): −3372.9536 (ours, arch) vs −3372.9905 (rugarch), difference +0.0369; parameters agree to 4 decimals (α 0.04267/0.04264, γ 0.06203/0.06202, β 0.90036/0.90040, ν 7.002/7.010). - Tests:
tests/replication/test_rugarch.py(arch GJR vs rugarch, assert ours ≥ rugarch − 1); custom twin:tests/unit/test_custom_models.py::test_nesting_and_admissibility[GJR11],test_no_lookahead_in_forecasts,test_edge_cases_constant_and_extreme(spike of 60 % at t = 700),tests/simulation/test_recovery.py::test_gjr_recovery_median_over_replications(12 seeded replications, T = 4,000, t(6) innovations; median within 0.02–0.03 of (0.04, 0.03, 0.10, 0.88)); driver:tests/integration/test_rolling_driver.py::test_driver_tier_b_and_failure_flags(gjr11, t). The fixture of the rugarch cross-check is itself GJR-t data.
8. Known limitations / failure modes
α often converges to the zero bound on equities (all news impact loaded on γ) — a boundary optimum flagged by SLSQP; near-integrated $\alpha + \gamma/2 + \beta$; the symmetric-κ forecast/admissibility rule under skew-t (above); the optimizer bound $\gamma \le 2$. Positivity requires $\alpha + \gamma \ge 0$ (imposed).
9. Computational footprint
Analytic; 5–7 parameters. Pilot median fit time per refit (t innovations): 0.0081 s (CL), 0.0101 s (EURUSD).
10. Literature expectations
hansen2005forecast: on IBM, models with a leverage effect (GJR among them) significantly outperform GARCH(1,1); on DM/$ they do not. brownlees2011practical, awartani2005predicting: asymmetric GARCH best overall for equity indices, especially in stressed periods. Pre-registered H1 (asymmetry) and H6 (regimes) concern this model directly; the matrix notes the GJR/TGARCH naming confusion that the registry resolves by keeping both definitions.