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

\begin{eqnarray} r_t & = & \mu + \epsilon_t \\ \epsilon_t & = & \sigma_t e_t \\ \sigma^2_t & = & \omega + \alpha \epsilon_{t-1}^2 + \beta \sigma^2_{t-1} \end{eqnarray}

A complete ARCH model is divided into three components:

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:

arch.univariate.base.ARCHModel

Raises:
  • TypeError – If mean, vol or dist is not a string, lags, p, o, q or hold_back is not an integer (a float, including 5.0, and a bool are not accepted), rescale is not a bool or None, power is not a real number, or x cannot be converted to numbers.

  • ValueError – If mean, vol or dist is not one of the options, lags, p, o, q or hold_back is negative, o is 0 when vol='ngarch', power is not finite and positive, or x contains NaN or inf or does not have a row for each observation of y.

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=0 has no asymmetric term in any volatility model. With vol='ngarch', o is the number of shifted innovations, and must not exceed p. Use o=1 for the NGARCH(1,1) of Engle and Ng. An NGARCH model without a shift is a GARCH model, and so vol='ngarch' with the default o=0 raises a ValueError.

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')