GARCH#

class cultivars.univariate.conditional_variance.GARCH(endog, *, p=1, q=1, ar_lags=0, mean='constant')[source]

Bases: _ShortMemoryVarianceModel[GARCHResult]

Symmetric GARCH(p, q) with an optional AR mean.

The variance recursion

\[\sigma_t^2 = \omega + \sum_{i=1}^{p} \alpha_i \varepsilon_{t-i}^2 + \sum_{j=1}^{q} \beta_j \sigma_{t-j}^2\]

under a constant, zero, or autoregressive mean, the two estimated jointly by Gaussian maximum likelihood. Positivity is enforced by searching \(\omega\) in logs and the coefficients through a transform that keeps them non-negative; stationarity is not imposed, so a persistence at or above one is reported as such rather than clipped. Both \(p = 0\) and \(q = 0\) are allowed – the first is a pure variance autoregression, the second an ARCH(p) – and the asymmetry order is fixed at zero; GJR is the family with a sign term.

Variables:
  • _vol – The family name, "GARCH".

  • _p – ARCH order.

  • _o – Asymmetry order, always zero here.

  • _q – GARCH order.

  • _endog – The validated series.

  • _ar_lags – Conditional-mean AR order.

  • _ma_lags – Conditional-mean MA order, always zero here.

  • _const – Whether the mean carries an intercept.

Parameters:
  • endog (ArrayLike) – The series, typically returns or residuals.

  • p (int) – ARCH order, the number of lagged squared residuals.

  • q (int) – GARCH order, the number of lagged variances.

  • ar_lags (int) – Conditional-mean AR order.

  • mean (str) – "constant" or "zero".

Raises:
  • SpecificationError – If an order is not a non-negative integer, or mean is not one of the two choices.

  • DimensionError – If endog is not one-dimensional or is shorter than the orders require.

  • NumericalError – If endog contains non-finite values.

See also

References

Bollerslev, T. (1986). Generalized autoregressive conditional heteroskedasticity. Journal of Econometrics, 31(3), 307-327.

Engle, R. F. (1982). Autoregressive conditional heteroscedasticity with estimates of the variance of United Kingdom inflation. Econometrica, 50(4), 987-1007.

Example

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> e = np.zeros(2000)
>>> s2 = np.full(2000, 2.5)
>>> z = rng.standard_normal(2000)
>>> for t in range(1, 2000):
...     s2[t] = 0.05 + 0.08 * e[t - 1] ** 2 + 0.90 * s2[t - 1]
...     e[t] = np.sqrt(s2[t]) * z[t]
>>> res = GARCH(e).fit()
>>> res.is_covariance_stationary
True
>>> bool(abs(res.persistence - 0.98) < 0.03)
True

An ARCH(2) and a zero-mean fit are the same front with the orders changed:

>>> GARCH(e, p=2, q=0).fit().order, list(GARCH(e, mean="zero").fit().params)
((2, 0, 0), ['omega', 'alpha[1]', 'beta[1]'])