Introduction to ARCH Models¶
ARCH models are a popular class of volatility models that use observed values of returns or residuals as volatility shocks. A basic GARCH model is specified as
A complete ARCH model is divided into three components:
a mean model, e.g., a constant mean or an
ARX;a volatility process, e.g., a
GARCHor anEGARCHprocess; anda distribution for the standardized residuals.
In most applications, the simplest method to construct this model is to use the constructor
function arch_model()
import arch.data.sp500
from arch import arch_model
sp500 = arch.data.sp500.load()
sp500 = sp500.loc['2000-01-01':'2014-01-01']
returns = 100 * sp500['Adj Close'].pct_change().dropna()
am = arch_model(returns)
Alternatively, the same model can be manually assembled from the building blocks of an ARCH model
from arch.univariate import ConstantMean, GARCH, Normal
am = ConstantMean(returns)
am.volatility = GARCH(1, 0, 1)
am.distribution = Normal()
In either case, model parameters are estimated using
res = am.fit()
with the following output
Iteration: 1, Func. Count: 6, Neg. LLF: 68805886954919.59
Iteration: 2, Func. Count: 15, Neg. LLF: 1575359856.4496076
Iteration: 3, Func. Count: 22, Neg. LLF: 5194.449409971215
Iteration: 4, Func. Count: 28, Neg. LLF: 5190.7422748202325
Iteration: 5, Func. Count: 34, Neg. LLF: 5191.570045895966
Iteration: 6, Func. Count: 40, Neg. LLF: 5150.829260399659
Iteration: 7, Func. Count: 46, Neg. LLF: 6474.487216207122
Iteration: 8, Func. Count: 53, Neg. LLF: 5143.161859778254
Iteration: 9, Func. Count: 59, Neg. LLF: 5141.392123039943
Iteration: 10, Func. Count: 64, Neg. LLF: 5141.390238848524
Iteration: 11, Func. Count: 69, Neg. LLF: 5141.390233587619
Iteration: 12, Func. Count: 73, Neg. LLF: 5141.390233588856
Optimization terminated successfully (Exit mode 0)
Current function value: 5141.390233587619
Iterations: 12
Function evaluations: 73
Gradient evaluations: 12
print(res.summary())
yields
Constant Mean - GARCH Model Results
==============================================================================
Dep. Variable: Adj Close R-squared: 0.000
Mean Model: Constant Mean Adj. R-squared: 0.000
Vol Model: GARCH Log-Likelihood: -5141.39
Distribution: Normal AIC: 10290.8
Method: Maximum Likelihood BIC: 10315.4
No. Observations: 3520
Date: Fri, Oct 16 2026 Df Residuals: 3519
Time: 11:57:57 Df Model: 1
Mean Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
mu 0.0531 1.487e-02 3.569 3.581e-04 [2.392e-02,8.220e-02]
Volatility Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
omega 0.0156 4.932e-03 3.155 1.606e-03 [5.892e-03,2.523e-02]
alpha[1] 0.0879 1.140e-02 7.710 1.260e-14 [6.554e-02, 0.110]
beta[1] 0.9014 1.183e-02 76.163 0.000 [ 0.878, 0.925]
============================================================================
Covariance estimator: robust
Model Constructor¶
While models can be carefully specified using the individual components, most common specifications can be specified using a simple model constructor.
-
arch.univariate.arch_model(y: ndarray | DataFrame | Series | None, x: ndarray | DataFrame | Series | ndarray[tuple[int, int], dtype[float64]] | None =
None, mean: 'constant' | 'zero' | 'ls' | 'ar' | 'arx' | 'har' | 'harx' ='constant', lags: int | list[int] | ndarray[tuple[int, ...], dtype[int32]] | ndarray[tuple[int, ...], dtype[int64]] | None =0, vol: 'garch' | 'arch' | 'egarch' | 'figarch' | 'fiaparch' | 'aparch' | 'harch' | 'ngarch' ='garch', p: int | list[int] =1, o: int =0, q: int =1, power: float =2.0, dist: 'normal' | 'gaussian' | 't' | 'studentst' | 'skewstudent' | 'skewt' | 'ged' | 'generalized error' ='normal', hold_back: int | None =None, rescale: bool | None =None) HARX[source]¶ Initialize common ARCH model specifications.
- Parameters:¶
- y: ndarray | DataFrame | Series | None¶
The dependent variable.
- x: ndarray | DataFrame | Series | ndarray[tuple[int, int], dtype[float64]] | None =
None¶ Exogenous regressors. Ignored if model does not permit exogenous regressors.
- mean: 'constant' | 'zero' | 'ls' | 'ar' | 'arx' | 'har' | 'harx' =
'constant'¶ Name of the mean model. Currently supported options are: ‘constant’ (default), ‘zero’, ‘ls’, ‘ar’, ‘arx’, ‘har’ and ‘harx’. Not case sensitive.
- lags: int | list[int] | ndarray[tuple[int, ...], dtype[int32]] | ndarray[tuple[int, ...], dtype[int64]] | None =
0¶ Either a scalar integer value indicating lag length or a list of integers specifying lag locations.
- vol: 'garch' | 'arch' | 'egarch' | 'figarch' | 'fiaparch' | 'aparch' | 'harch' | 'ngarch' =
'garch'¶ Name of the volatility model. Currently supported options are: ‘garch’ (default), ‘arch’, ‘egarch’, ‘figarch’, ‘fiaparch’, ‘aparch’, ‘harch’ and ‘ngarch’. Not case sensitive.
- p: int | list[int] =
1¶ Lag order of the symmetric innovation. A list of lags can only be used with the ‘harch’ volatility model. Must be at least 0, and integers only (2.0 and True are not accepted).
- o: int =
0¶ Lag order of the asymmetric innovation. Must be at least 0.
- q: int =
1¶ Lag order of lagged volatility or equivalent. Must be at least 0.
- power: float =
2.0¶ Power to use with GARCH and related models. Must be finite and positive.
- dist: 'normal' | 'gaussian' | 't' | 'studentst' | 'skewstudent' | 'skewt' | 'ged' | 'generalized error' =
'normal'¶ Name of the error distribution. Not case sensitive. Currently supported options are:
Normal: ‘normal’, ‘gaussian’ (default)
Student’s t: ‘t’, ‘studentst’
Skewed Student’s t: ‘skewstudent’, ‘skewt’
Generalized Error Distribution: ‘ged’, ‘generalized error’
- hold_back: int | None =
None¶ Number of observations at the start of the sample to exclude when estimating model parameters. Used when comparing models with different lag lengths to estimate on the common sample.
- rescale: bool | None =
None¶ Flag indicating whether to automatically rescale data if the scale of the data is likely to produce convergence issues when estimating model parameters. If False, the model is estimated on the data without transformation. If True, then y is rescaled and the new scale is reported in the estimation results.
- Returns:¶
model – Configured ARCH model.
- Return type:¶
- Raises:¶
TypeError – If
mean,volordistis not a string,lags,p,o,qorhold_backis not an integer (a float, including 5.0, and a bool are not accepted),rescaleis not a bool or None,poweris not a real number, orxcannot be converted to numbers.ValueError – If
mean,volordistis not one of the options,lags,p,o,qorhold_backis negative,ois 0 whenvol='ngarch',poweris not finite and positive, orxcontains NaN or inf or does not have a row for each observation ofy.
Notes
Input that are not relevant for a particular specification, such as lags when mean=’zero’, are silently ignored, and so are not checked.
The default
o=0has no asymmetric term in any volatility model. Withvol='ngarch',ois the number of shifted innovations, and must not exceedp. Useo=1for the NGARCH(1,1) of Engle and Ng. An NGARCH model without a shift is a GARCH model, and sovol='ngarch'with the defaulto=0raises aValueError.Examples
>>> from arch.data.sp500 import load >>> sp500 = load() >>> returns = 100 * sp500['Adj Close'].pct_change().dropna()A basic GARCH(1,1) with a constant mean can be constructed using only the return data
>>> from arch.univariate import arch_model >>> am = arch_model(returns)Alternative mean and volatility processes can be directly specified
>>> am = arch_model(returns, mean='ar', lags=2, vol='harch', p=[1, 5, 22])This example demonstrates the construction of a zero mean process with a TARCH volatility process and Student t error distribution
>>> am = arch_model(returns, mean='zero', p=1, o=1, q=1, ... power=1.0, dist='studentst')