ARCH

import warnings
warnings.simplefilter("ignore", FutureWarning)

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme()
sns.set_context("notebook")

import pandas as pd
import sqlite3

Conditional heteroskedasticity

Time series models are (largely) models of the temporal dependence observed in time series data

  • the future depends of the past

  • the past is informative about the future

p(zt+h|zt,zt1,)p(zt+h)

Central objective of time series modeling is characterizing temporal dependence, i.e. characterizing

p(zt+h|zt,zt1,)

or characterizing some of its moments, such as

E(zt+h|zt,zt1,)=Et(zt+h)var(zt+h|zt,zt1,)=vart(zt+h)

So far, we have seen models for the conditional mean.

  • for example, in zt=αzt1+εt the conditional mean is

E(zt+1|zt,zt1,)=E(zt+1|zt)=αzt

changes with zt

However, the assumptions about εt imply that var(zt+h|zt,zt1,) is a constant (independent of zt,zt1,)

  • for example, in zt=αzt1+εt

var(zt+1|zt,zt1,)=var(εt+1|zt)=var(εt+1)=σ2

independent of zt

Gaussian time series model

p(z1,z2,,zTz1,zT+1,,zT+hz2)=p(z1,z2)N(μ,Σ).

Forecasts

p(z2|z1)=N(μ2+Σ21Σ111(z1μ1),Σ22Σ21Σ111Σ12)
  • E(z2|z1)=μ2+Σ21Σ111(z1μ1) function of z1

  • cov(z2|z1)=Σ22Σ21Σ111Σ12 constant

More generally, if

εt=ztE(zt|zt1,zt2,)

then

E(εt|zt1,zt2,)=0

and

E(εt2|zt1,zt2,)=var(εt|zt1,zt2,)=var(zt|zt1,zt2,)

For var(zt|zt1,zt2,) to vary with (zt1,zt2,), we need var(εt|zt1,zt2,) to be a function of (zt1,zt2,)

var(εt|zt1,zt2,)=E(εt2|zt1,zt2,)=h(zt1,zt2,)=σt2

where h(.) is non-negative

and therefore

var(zt|zt1,zt2,)=σt2

conditional heteroskedasticity models are models for σt2

  • σt2=σ2 - homoskedasticity

  • σt2σ2 - heteroskedasticity

Autoregressive conditional heteroskedasticity (ARCH) models

ARCH(1)

σt2=ω0+ω1εt12
  • ω0>0, ω10 (for σt2 to be positive)

  • large shocks (εt1) are expected to be followed by other large shocks ( large var(εt|zt1,zt2,) )

Since εt is innovation process (unpredictable)

Et1(εt)=0

we have

Et1(εt2)=vart1(εt)=σt2=ω0+ω1εt12

and defining νt=εt2Et1(εt2)

εt2=ω0+ω1εt12+νt

From

E(εt|εt1,εt2,)=E(εt|zt1,zt2,)=0

and

var(εt|εt1,εt2,)=var(εt|zt1,zt2,)=ω0+ω1εt12

follows

E(εt2|εt1,εt2,)=var(εt|εt1,εt2,)=σt2=ω0+ω1εt12

and

εt2=ω0+ω1εt12+νt,whereνt=εt2E(εt2|εt1,εt2,)
νt=εt2E(εt2|εt1,εt2,)=σt2(ϵt21)
εt2=ω0+ω1εt12+νt
  • AR(1) model for εt2

  • εt2 are positively autocorrelated (εt are uncorrelated)

  • stationarity: ω1<1

  • unconditional mean of εt2 :

Eεt2=ω01ω1
  • unconditional variance of εt:

Eεt=0var(εt)=Eεt2=ω01ω1=σ2
  • εt and zt are stationary (unconditional moments are time-invariant)

  • large (relative to σ2) shocks expected after large (relative to σ2) shocks

εt2σ2=ω0+ω1(εt12σ2)+νt

ARCH(q)

σt2=ω0+iqωiεti2

as before

εt2=ω0+iqωiεti2+νt
  • AR(q) model for εt2

Estimation

Pure volatility models

zt=μ+εt

Let

etiid(0,1)

Then, we can write

εt=σtet
εt=σtϵtandztσt=ϵt
  • if etiidN(0,1) the conditional density of zt is

zt|zt1,,z1N(μ,σt2)

because at time t1, σt is known, i.e. a constant

  • and the conditional log-likelihood of zt

t(θ)=12ln2π12lnσtztμ2σt2
  • the likelihood of {z1,z2,,zT}

(θ|z)=t=1Tt(θ)

Time-varying mean

zt=μt+εt
  • μt=Et1zt

  • for example

μt=α0+α1zt1
  • conditional log-likelihood of zt

t(θ)=12ln2π12lnσtztμt2σt2
  • the likelihood of {z1,z2,,zT}

(θ|z)=t=1Tt(θ)

ARCH models in Python

from arch import arch_model
conn = sqlite3.connect(database='FCI_EIKON_long.db')

query ='SELECT * FROM "Eikon-daily" WHERE variable=="STOXXE"'
df = pd.read_sql_query(query, conn)

df = df.set_index('time', drop=True)
df.index = pd.to_datetime(df.index)
df = df.sort_index().dropna()
euro_stoxx = df.drop('variable', axis=1)
euro_stoxx.columns = ['EURO STOXX INDEX']

euro_stoxx_returns = 100 * euro_stoxx.pct_change().dropna()['2004':]
euro_stoxx_returns.columns = ['EURO STOXX Returns']
fig = euro_stoxx_returns.plot(figsize=(14,3), legend=False, title='EURO STOXX Returns', ylabel='%', xlabel='year')
../../_images/01-ARCH_7_0.png

Estimate ARCH(1)

arch1 = arch_model(y=euro_stoxx_returns, mean='constant', vol='ARCH')
arch1
Constant Mean(constant: yes, no. of exog: 0, volatility: ARCH(p: 1), distribution: Normal distribution, ID: 0x2a8f1847f70)
res = arch1.fit(update_freq=0)
print(res.summary())
Optimization terminated successfully    (Exit mode 0)
            Current function value: 7748.798771475143
            Iterations: 6
            Function evaluations: 33
            Gradient evaluations: 6
                      Constant Mean - ARCH Model Results                      
==============================================================================
Dep. Variable:     EURO STOXX Returns   R-squared:                       0.000
Mean Model:             Constant Mean   Adj. R-squared:                  0.000
Vol Model:                       ARCH   Log-Likelihood:               -7748.80
Distribution:                  Normal   AIC:                           15503.6
Method:            Maximum Likelihood   BIC:                           15523.0
                                        No. Observations:                 4749
Date:                Mon, Apr 04 2022   Df Residuals:                     4748
Time:                        17:29:15   Df Model:                            1
                                 Mean Model                                 
============================================================================
                 coef    std err          t      P>|t|      95.0% Conf. Int.
----------------------------------------------------------------------------
mu             0.0424  1.852e-02      2.288  2.212e-02 [6.082e-03,7.869e-02]
                            Volatility Model                            
========================================================================
                 coef    std err          t      P>|t|  95.0% Conf. Int.
------------------------------------------------------------------------
omega          1.2266  7.797e-02     15.731  9.201e-56 [  1.074,  1.379]
alpha[1]       0.2872  4.632e-02      6.201  5.596e-10 [  0.196,  0.378]
========================================================================

Covariance estimator: robust
fig = res.plot()
fig.set_figheight(val=8)
fig.set_figwidth(val=14)
../../_images/01-ARCH_11_0.png

Forecasting

forecasts = res.forecast(reindex=False, horizon=12)

forecasts.variance
h.01 h.02 h.03 h.04 h.05 h.06 h.07 h.08 h.09 h.10 h.11 h.12
time
2022-03-30 1.672126 1.706939 1.716939 1.719811 1.720636 1.720873 1.720941 1.720961 1.720967 1.720968 1.720969 1.720969
forecasts.mean
h.01 h.02 h.03 h.04 h.05 h.06 h.07 h.08 h.09 h.10 h.11 h.12
time
2022-03-30 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386 0.042386
from arch.univariate import ARCH

arch7 = arch1
arch7.volatility = ARCH(p=7)
arch7
Constant Mean(constant: yes, no. of exog: 0, volatility: ARCH(p: 7), distribution: Normal distribution, ID: 0x2a8f1847f70)
res = arch7.fit(update_freq=0)
fig = res.plot()
fig.set_figheight(val=8)
fig.set_figwidth(val=14)
Optimization terminated successfully    (Exit mode 0)
            Current function value: 7018.71525122455
            Iterations: 19
            Function evaluations: 216
            Gradient evaluations: 19
../../_images/01-ARCH_16_1.png

Specifying model for the conditional mean

dcpi = pd.read_csv('HICP_unadj_ANR_clean.csv', index_col=0, parse_dates=True)
infl_pt = dcpi[['PT']].copy()
infl_pt.plot(figsize=(12,4), title='Inflation, PT')
<AxesSubplot:title={'center':'Inflation, PT'}, xlabel='date'>
../../_images/01-ARCH_19_1.png
from arch.univariate import ARX

arch_ar_model = ARX(infl_pt,
                    constant=True,
                    lags=[1, 12],
                    volatility=ARCH(p=1))

#arch_ar_model.volatility = ARCH(p=1) # to add volatility if not specified above

arch_ar_model
AR(constant: yes, lags: 1, 12, no. of exog: 0, volatility: ARCH(p: 1), distribution: Normal distribution, ID: 0x1f7a54a55d0)
zt=α+α1zt1+α12zt12+εtεtARCH(1)
res_arch_ar_model = arch_ar_model.fit(update_freq=0, disp="off")
print(res_arch_ar_model.summary())
                           AR - ARCH Model Results                            
==============================================================================
Dep. Variable:                     PT   R-squared:                       0.920
Mean Model:                        AR   Adj. R-squared:                  0.919
Vol Model:                       ARCH   Log-Likelihood:               -147.565
Distribution:                  Normal   AIC:                           305.130
Method:            Maximum Likelihood   BIC:                           323.462
                                        No. Observations:                  289
Date:                Sun, Apr 03 2022   Df Residuals:                      286
Time:                        23:43:26   Df Model:                            3
                                 Mean Model                                
===========================================================================
                 coef    std err          t      P>|t|     95.0% Conf. Int.
---------------------------------------------------------------------------
Const          0.0990  4.107e-02      2.411  1.590e-02  [1.854e-02,  0.180]
PT[1]          1.0056  1.951e-02     51.545      0.000    [  0.967,  1.044]
PT[12]        -0.0646  1.999e-02     -3.232  1.227e-03 [ -0.104,-2.544e-02]
                              Volatility Model                             
===========================================================================
                 coef    std err          t      P>|t|     95.0% Conf. Int.
---------------------------------------------------------------------------
omega          0.1288  1.829e-02      7.039  1.930e-12  [9.291e-02,  0.165]
alpha[1]       0.2623      0.142      1.853  6.389e-02 [-1.515e-02,  0.540]
===========================================================================

Covariance estimator: robust
ar_model = ARX(infl_pt,
                    constant=True,
                    lags=[1, 12])

res_ar_model = ar_model.fit(update_freq=0, disp="off")
print(res_ar_model.summary())
                     AR - Constant Variance Model Results                     
==============================================================================
Dep. Variable:                     PT   R-squared:                       0.920
Mean Model:                        AR   Adj. R-squared:                  0.920
Vol Model:          Constant Variance   Log-Likelihood:               -153.943
Distribution:                  Normal   AIC:                           315.887
Method:            Maximum Likelihood   BIC:                           330.553
                                        No. Observations:                  289
Date:                Sun, Apr 03 2022   Df Residuals:                      286
Time:                        23:43:44   Df Model:                            3
                                  Mean Model                                  
==============================================================================
                 coef    std err          t      P>|t|        95.0% Conf. Int.
------------------------------------------------------------------------------
Const          0.1315  4.353e-02      3.020  2.531e-03     [4.613e-02,  0.217]
PT[1]          0.9882  1.919e-02     51.487      0.000       [  0.951,  1.026]
PT[12]        -0.0574  1.891e-02     -3.037  2.386e-03 [-9.451e-02,-2.038e-02]
                            Volatility Model                            
========================================================================
                 coef    std err          t      P>|t|  95.0% Conf. Int.
------------------------------------------------------------------------
sigma2         0.1699  1.918e-02      8.859  8.041e-19 [  0.132,  0.207]
========================================================================

Covariance estimator: White's Heteroskedasticity Consistent Estimator
forecasts = res_arch_ar_model.forecast(reindex=False, horizon=6)
forecasts.mean
h.1 h.2 h.3 h.4 h.5 h.6
date
2022-01-01 3.498751 3.610983 3.736772 3.82449 3.983794 4.034121
forecasts.variance
h.1 h.2 h.3 h.4 h.5 h.6
date
2022-01-01 0.193844 0.375625 0.555719 0.736862 0.91979 1.104713