Volatility Processes

A volatility process is added to a mean model to capture time-varying volatility.

ConstantVariance()

Constant volatility process.

GARCH([p, o, q, power])

GARCH and related model estimation.

FIGARCH([p, q, power, truncation])

FIGARCH model.

EGARCH([p, o, q])

EGARCH model estimation.

HARCH([lags])

Heterogeneous ARCH process.

MIDASHyperbolic([m, asym])

MIDAS Hyperbolic ARCH process.

ARCH([p])

ARCH process.

APARCH([p, o, q, delta, common_asym])

Asymmetric Power ARCH (APARCH) volatility process.

FIAPARCH([p, o, q, delta, truncation])

Fractionally Integrated Asymmetric Power ARCH (FIAPARCH) volatility process.

NGARCH([p, o, q])

Nonlinear asymmetric GARCH (NGARCH) volatility process.

Fractionally Integrated Asymmetric Power ARCH

FIAPARCH is a fractionally integrated asymmetric power ARCH process. It extends FIGARCH, which has long memory in the volatility, with the asymmetry and the power of APARCH. The conditional volatility evolves according to

\[\sigma_t^{\delta} = \omega + \left[1-\beta L - (1-\phi L)(1-L)^d\right] (|\epsilon_t| - \gamma \epsilon_t)^{\delta} + \beta \sigma_{t-1}^{\delta}\]

where \(L\) is the lag operator and \(d\) is the fractional differencing parameter. The shocks enter through \(|\epsilon_t| - \gamma \epsilon_t\), so that \(\gamma>0\) produces a larger response to negative shocks than to positive shocks of the same size, and the power \(\delta\) determines the scale on which the volatility is modeled. As in the FIGARCH, the process is estimated using its ARCH(\(\infty\)) representation

\[\sigma_t^{\delta} = (1-\beta)^{-1}\omega + \sum_{i=1}^{\infty} \lambda_i (|\epsilon_{t-i}| - \gamma \epsilon_{t-i})^{\delta}\]

with weights \(\lambda_i\) that are the same as in the FIGARCH, truncated after truncation terms (1000 by default).

The orders p, o and q can be 0 or 1. They select, respectively, the parameters \(\phi\), \(\gamma\) and \(\beta\), and the parameters are ordered omega, phi, d, beta, gamma and delta, omitting the ones that are not in the model. The power \(\delta\) is estimated, with values between 0.05 and 4, unless delta is provided, which fixes it to a value in the same range. Fixing \(\delta\) makes estimation considerably faster. The process is named "FI Power ARCH" when o=0, since it then has no asymmetry.

In [1]: import arch.data.nasdaq

In [2]: from arch.univariate import ConstantMean, FIAPARCH

In [3]: nasdaq = arch.data.nasdaq.load()

In [4]: returns = 100 * nasdaq["Adj Close"].pct_change().dropna()

In [5]: am = ConstantMean(returns, volatility=FIAPARCH(delta=1.0, truncation=250))

In [6]: res = am.fit(disp="off")

In [7]: res.params
Out[7]: 
mu       0.035159
omega    0.136685
phi      0.195449
d        0.485489
beta     0.605320
gamma    0.729977
Name: params, dtype: float64

The process can also be selected using vol="fiaparch" in arch_model(), which estimates \(\delta\) and uses the default truncation. Analytic forecasts are only available for a horizon of 1. Longer horizons require method="simulation" or method="bootstrap".

In [8]: import numpy as np

In [9]: forecasts = res.forecast(
   ...:     horizon=3,
   ...:     method="simulation",
   ...:     simulations=500,
   ...:     random_state=np.random.RandomState(0),
   ...: )
   ...: 

In [10]: forecasts.variance
Out[10]: 
                 h.1       h.2       h.3
Date                                    
2018-12-31  3.646961  3.309469  3.090744

Nonlinear Asymmetric GARCH

NGARCH is the nonlinear asymmetric GARCH of Engle and Ng [EngleNg1993], which the rugarch package for R calls NAGARCH. The shock is shifted by a multiple of the lagged volatility before it is squared,

\[\sigma_t^{2} = \omega + \sum_{i=1}^{p}\alpha_i\left(\epsilon_{t-i} - \theta_i I_{[o\geq i]} \sigma_{t-i}\right)^{2} + \sum_{j=1}^{q}\beta_j \sigma_{t-j}^{2}.\]

In terms of the standardized shock \(e_t=\epsilon_t/\sigma_t\) the news impact is \(\sigma_{t-1}^2(e_{t-1}-\theta)^2\), a parabola with a minimum at \(e_{t-1}=\theta\). With \(\theta>0\), the leverage effect, a negative shock increases the variance by more than a positive shock of the same size. Engle and Ng write the shift as \((\epsilon_{t-1}+\gamma\sigma_{t-1})^2\) and expect \(\gamma<0\), so that \(\theta=-\gamma\). The sign convention of NGARCH is that of rugarch. The parameters are named omega, alpha[i], theta[i] and beta[j], and the orders must satisfy \(o\leq p\), as for APARCH. Unlike the GJR-GARCH, the expected value of the shock term does not depend on the distribution of \(e_t\) beyond its mean and variance, since \(E[(e_t-\theta)^2]=1+\theta^2\) for any standardized distribution.

Note

Another model, the nonlinear ARCH of Higgins and Bera [HigginsBera1992], is also called NGARCH. It is not available in arch.

The process is covariance stationary when the persistence \(\phi=\sum_i\alpha_i(1+\theta_i^2)+\sum_j\beta_j\) is smaller than 1. Estimation imposes the linear constraints \(\sum_i\alpha_i+\sum_j\beta_j<1\) and non-negativity, as for APARCH, and not \(\phi<1\), which is not linear in the parameters. fit issues a ValueWarning when the persistence of the estimated model is 1 or more.

In [11]: import arch.data.sp500

In [12]: from arch.univariate import ConstantMean, NGARCH

In [13]: sp500 = arch.data.sp500.load()

In [14]: returns = 100 * sp500["Adj Close"].pct_change().dropna()

In [15]: am = ConstantMean(returns, volatility=NGARCH(p=1, o=1, q=1))

In [16]: res = am.fit(disp="off")

In [17]: res.params
Out[17]: 
mu          0.002957
omega       0.020990
alpha[1]    0.076032
theta[1]    1.339966
beta[1]     0.781219
Name: params, dtype: float64

In [18]: params = res.params

In [19]: params["alpha[1]"] * (1 + params["theta[1]"] ** 2) + params["beta[1]"]
Out[19]: np.float64(0.9937674338841983)

The process can also be selected using vol="ngarch" in arch_model(), where o=1 adds the shift and is required. Without a shift (o=0, the default of arch_model) the model is a GARCH, so arch_model raises a ValueError. Use vol="garch" for that model. Analytic forecasts are exact at all horizons. For p=q=1 they satisfy \(f_h=\omega+\phi f_{h-1}\).

In [20]: res.forecast(horizon=5).variance.iloc[-1]
Out[20]: 
h.1    3.675346
h.2    3.673430
h.3    3.671525
h.4    3.669632
h.5    3.667752
Name: 2018-12-31 00:00:00, dtype: float64

Parameterless Variance Processes

Some volatility processes use fixed parameters and so have no parameters that are estimable.

EWMAVariance([lam])

Exponentially Weighted Moving-Average (RiskMetrics) Variance process.

RiskMetrics2006([tau0, tau1, kmax, rho])

RiskMetrics 2006 Variance process.

FixedVariance

The FixedVariance class is a special-purpose volatility process that allows the so-called zig-zag algorithm to be used. See the example for usage.

FixedVariance(variance[, unit_scale])

Fixed volatility process.

Writing New Volatility Processes

All volatility processes must inherit from VolatilityProcess and provide all public methods.

VolatilityProcess()

Abstract base class for ARCH models.

They may optionally expose a VolatilityUpdater class that can be used in ARCHInMean estimation.

VolatilityUpdater

Base class that all volatility updaters must inherit from.