ARMAGARCH#

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

ARMA mean with a symmetric GARCH variance, estimated jointly.

The mean

\[y_t = c + \sum_{i=1}^{p} \phi_i\, y_{t-i} + \varepsilon_t + \sum_{j=1}^{q} \theta_j\, \varepsilon_{t-j}, \qquad \varepsilon_t = \sigma_t z_t,\]

over the GARCH variance, with one likelihood for both. When ma_lags > 0 the mean residual feeds on its own past and the mean is searched through the partial autocorrelations, so the fit is stationary and invertible by construction; when ma_lags == 0 the specification collapses to ARGARCH and the lag weights are unconstrained. Both defaults are one, so ARMAGARCH(y, ar_lags=2) keeps a moving-average 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.

  • _const – Whether the mean carries an intercept.

Parameters:
  • endog (ArrayLike) – The series.

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

  • ma_lags (int) – Conditional-mean moving-average order.

  • p (int) – Order of the shock-magnitude block.

  • q (int) – Order of the variance persistence block.

  • 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

Example

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> n = 2000
>>> s2 = np.ones(n)
>>> e = np.zeros(n)
>>> y = np.zeros(n)
>>> for t in range(1, n):
...     s2[t] = 0.05 + 0.10 * e[t - 1] ** 2 + 0.85 * s2[t - 1]
...     e[t] = np.sqrt(s2[t]) * rng.standard_normal()
...     y[t] = 0.5 * y[t - 1] + e[t] + 0.4 * e[t - 1]
>>> res = ARMAGARCH(y, ar_lags=1, ma_lags=1).fit()
>>> bool(res.is_stationary and res.is_invertible)
True
>>> bool(abs(res.ar_params[0] - 0.5) < 0.1), bool(abs(res.ma_params[0] - 0.4) < 0.1)
(True, True)
>>> res._comparison_label()
'ARMA(1, 1)-GARCH(1, 1)'

Attributes#

ar_lags

The conditional-mean autoregressive order.

endog

The validated endogenous series.

has_constant_mean

Whether a mean intercept is estimated.

ma_lags

The conditional-mean moving-average order.

mean_order

The conditional-mean order (ar_lags, ma_lags).

order

The variance order (p, o, q).

vol

The volatility family.

Methods#

fit()

Estimate mean and variance jointly by Gaussian maximum likelihood.