专题四 波动性模型

前言

前面三节课介绍了时间序列的基本知识、4种常见的时间序列模型及季节模型,这些模型一般都假设干扰项的方差为常数,然而很多情况下时间序列的波动有集聚性等特征,使得方差并不为常数。因此,如何刻画方差是十分有必要研究的。 本文介绍的ARCH、GARCH模型可以刻画出随时间变化的条件异方差。

4.1 自回归条件异方差模型(ARCH)

4.1.1 波动率的特征

对于金融时间序列,波动率往往具有以下特征:

(1)存在波动率聚集现象。 即波动率在一段时间上高,一段时间上低。

(2)波动率以连续时间变化,很少发生跳跃

(3)波动率不会发散到无穷,波动率往往是平稳

(4)波动率对价格大幅上升和大幅下降的反应是不同的,这个现象为杠杆效应

条件波动性(Conditional Volatility) 是指在时间序列数据中,一个时刻的波动性(方差)依赖于该时刻之前的数据。换句话说,条件波动性表示了时间序列数据的波动性在不同时刻是不同的,且这种变化是基于之前的观测值而来的。

ARCH(Autoregressive Conditional Heteroskedasticity)和 GARCH(Generalized Autoregressive Conditional Heteroskedasticity)模型就是用来建模时间序列数据中的条件波动性的方法。这些模型认为时间序列数据的方差是随着时间变化的,并且可以通过过去的观测值来预测。

4.1.2 ARCH的基本原理

在传统计量经济学模型中,干扰项的方差被假设为常数。但是许多经济时间序列呈现出波动的集聚性,在这种情况下假设方差为常数是不恰当的。

ARCH模型将当前一切可利用信息作为条件,并采用某种自回归形式来刻划方差的变异,对于一个时间序列而言,在不同时刻可利用的信息不同,而相应的条件方差也不同,利用ARCH模型,可以刻划出随时间而变异的条件方差。

1. ARCH模型思想

1.资产收益率序列的扰动{ a t a_t at}是序列不相关的,但是不独立。

2.{ a t a_t at}的不独立性可以用其延迟值的简单二次函数来描述。

ARCH 模型是用于描述时间序列数据中异方差性(方差不恒定)的一种模型。“ARCH” 代表 “Autoregressive Conditional Heteroskedasticity”,它的基本思想是将过去的误差项的平方作为当前时间点的方差模型的输入。

ARCH 模型的一般形式为:

y t = μ t + ϵ t ϵ t = σ t z t σ t 2 = α 0 + α 1 ϵ t − 1 2 + α 2 ϵ t − 2 2 + … + α p ϵ t − p 2 \begin{align*} y_t &= \mu_t + \epsilon_t \\ \epsilon_t &= \sigma_t z_t \\ \sigma_t^2 &= \alpha_0 + \alpha_1 \epsilon_{t-1}^2 + \alpha_2 \epsilon_{t-2}^2 + \ldots + \alpha_p \epsilon_{t-p}^2 \end{align*} ytϵtσt2=μt+ϵt=σtzt=α0+α1ϵt12+α2ϵt22++αpϵtp2

其中:

  • y t y_t yt 是时间序列的观测值。
  • μ t \mu_t μt 是平均值(可能是一个常数,也可能是一个模型)。
  • ϵ t \epsilon_t ϵt 是时间点 t t t 的误差项,这里假设服从均值为零的独立同分布的随机变量。
  • σ t 2 \sigma_t^2 σt2 是时间点 t t t 的方差,它是过去若干个误差项的平方的加权和,权重由 α \alpha α 参数确定。
  • z t z_t zt 是标准正态随机变量。
  • α 0 , α 1 , … , α p \alpha_0, \alpha_1, \ldots, \alpha_p α0,α1,,αp 是 ARCH 模型的参数,控制着过去误差项平方对当前方差的影响。

ARCH 模型的关键特点在于,它可以捕捉到时间序列中方差的非恒定性,即方差会随着时间而变化。模型的参数可以通过最大似然估计等方法进行估计。

ARCH 模型的一种扩展是 GARCH(Generalized Autoregressive Conditional Heteroskedasticity)模型,它在 ARCH 模型的基础上引入了过去方差的高阶项,使得模型能够更准确地描述异方差性。

# !pip install arch
# 相关库
from scipy import  stats
import statsmodels.api as sm  # 统计相关的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import arch  # 条件异方差模型相关的库
import seaborn as sns     #seaborn画出的图更好看,且代码更简单
sns.set(color_codes=True) #seaborn设置背景

#导入数据
data=pd.read_excel('股价数据.xlsx')
data.set_index('date', inplace=True) #设定日期为索引
r2=np.log(data['close'])-np.log(data['close'].shift(1)) #计算对数收益率
r2=r2.dropna()
r2.head()
date
2020-01-03   -0.051530
2020-01-06   -0.000586
2020-01-07    0.016870
2020-01-08   -0.006484
2020-01-09    0.014713
Name: close, dtype: float64
r=r2
r2=pd.DataFrame(r)
r2.columns=(['return'])
r2
return
date
2020-01-03-0.051530
2020-01-06-0.000586
2020-01-070.016870
2020-01-08-0.006484
2020-01-090.014713
......
2022-12-26-0.016937
2022-12-270.007556
2022-12-280.000000
2022-12-29-0.008235
2022-12-300.004714

727 rows × 1 columns

r2.plot(figsize=(12,4))

在这里插入图片描述

4.1.2 ARCH模型建立

ok,上面尽可能简单的介绍了ARCH的原理,下面主要介绍如何python实现。ARCH模型建立大致分为以下几步:

步骤(1):通过检验数据的序列相关性建立一个均值方程,如有必要,对收益率序列建立一个计量经济模型(如ARMA)来消除任何线形依赖。

步骤(2):对均值方程的残差进行ARCH效应检验

步骤(3):如果具有ARCH效应,则建立波动率模型

步骤(4):检验拟合的模型,如有必要则进行改进

arch库其实提供了现成的方法(后面会介绍),但是为了理解ARCH,我们按流程来建模

1. 均值方程(AR)的建立

这里的均值方程可以简单认为建立ARMA(或ARIMA)模型,ARCH其实是在此基础上的一些“修正”。 我们以上证指数日涨跌幅序列为例:

由于后面的arch库均值方程只支持常数、零均值、AR模型,我们这里建立AR模型,方便对照~

(1)首先检验平稳性,是否需要差分。 原假设 H 0 H_0 H0:序列为非平稳的,备择假设 H 1 H_1 H1:序列是平稳的

t = sm.tsa.stattools.adfuller(r2)  # ADF检验
print("p-value:   ",t[1])
p-value:    0.0

P值小于0.05 拒绝原假设,所以序列是平稳的

(2)定阶

from statsmodels.graphics.tsaplots import plot_pacf as PACF   #偏自相关图

fig = PACF(r2,lags = 30) #使用对数收益率序列
plt.show()

在这里插入图片描述

(3)建模AR§

from scipy import  stats
import statsmodels.api as sm  # 统计相关的库
from statsmodels.tsa.ar_model import AutoReg

temp = np.array(r2) # 载入收益率序列
model =AutoReg(temp,lags=[1,6,25,26])  
res = model.fit()  
out = 'AIC: {0:0.3f}, HQIC: {1:0.3f}, BIC: {2:0.3f}'
print(out.format(res.aic, res.hqic, res.bic))
print(res.summary())
plt.rcParams['font.sans-serif'] = ['simhei'] #字体为黑体
plt.rcParams['axes.unicode_minus'] = False #正常显示负号 
plt.figure(figsize=(10,4))
plt.plot(temp,'b',label='对数收益率')
plt.plot(res.fittedvalues, 'r',label='AR model')
plt.legend()
AIC: -3400.990, HQIC: -3390.432, BIC: -3373.675
                            AutoReg Model Results                             
==============================================================================
Dep. Variable:                      y   No. Observations:                  727
Model:             Restr. AutoReg(26)   Log Likelihood                1706.495
Method:               Conditional MLE   S.D. of innovations              0.021
Date:                Sat, 12 Aug 2023   AIC                          -3400.990
Time:                        10:57:10   BIC                          -3373.675
Sample:                            26   HQIC                         -3390.432
                                  727                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const          0.0008      0.001      1.054      0.292      -0.001       0.002
y.L1           0.0029      0.037      0.078      0.938      -0.070       0.076
y.L6          -0.0426      0.037     -1.142      0.253      -0.116       0.031
y.L25          0.0546      0.037      1.465      0.143      -0.018       0.128
y.L26         -0.1368      0.037     -3.680      0.000      -0.210      -0.064
                                    Roots                                     
==============================================================================
                   Real          Imaginary           Modulus         Frequency
------------------------------------------------------------------------------
AR.1            -1.0603           -0.1318j            1.0685           -0.4803
AR.2            -1.0603           +0.1318j            1.0685            0.4803
AR.3            -0.9941           -0.3837j            1.0656           -0.4414
AR.4            -0.9941           +0.3837j            1.0656            0.4414
AR.5            -0.8740           -0.6099j            1.0657           -0.4030
AR.6            -0.8740           +0.6099j            1.0657            0.4030
AR.7            -0.7048           -0.8059j            1.0706           -0.3644
AR.8            -0.7048           +0.8059j            1.0706            0.3644
AR.9            -0.4882           -0.9566j            1.0740           -0.3251
AR.10           -0.4882           +0.9566j            1.0740            0.3251
AR.11           -0.2412           -1.0461j            1.0735           -0.2861
AR.12           -0.2412           +1.0461j            1.0735            0.2861
AR.13            0.0147           -1.0741j            1.0742           -0.2478
AR.14            0.0147           +1.0741j            1.0742            0.2478
AR.15            0.2711           -1.0459j            1.0805           -0.2096
AR.16            0.2711           +1.0459j            1.0805            0.2096
AR.17            0.5188           -0.9556j            1.0873           -0.1708
AR.18            0.5188           +0.9556j            1.0873            0.1708
AR.19            0.7355           -0.8040j            1.0896           -0.1321
AR.20            0.7355           +0.8040j            1.0896            0.1321
AR.21            0.9045           -0.6082j            1.0900           -0.0942
AR.22            0.9045           +0.6082j            1.0900            0.0942
AR.23            1.0925           -0.1318j            1.1004           -0.0191
AR.24            1.0925           +0.1318j            1.1004            0.0191
AR.25            1.0253           -0.3830j            1.0945           -0.0569
AR.26            1.0253           +0.3830j            1.0945            0.0569
------------------------------------------------------------------------------

在这里插入图片描述

2. ARCH效应

从上面模型的结构看,大的过去的平方“扰动”会导致信息 a t a_t at大的条件异方差。从而 a t a_t at有取绝对值较大的值的倾向。这意味着:在ARCH的框架下,大的"扰动"会倾向于紧接着出现另一个大的"扰动"。这与波动率聚集的现象相似。

所谓ARCH模型效应,也就是条件异方差序列的序列相关性

我们使用混成检验(Ljung-Box),检验序列 { a t 2 a_t^2 at2} 的相关性,来判断是否具有ARCH效应

计算均值方程残差: a t = r t − μ t \large a_t = r_t - \mu_t at=rtμt

(1)画出残差及残差的平方

at = r2.values[26:] -  res.fittedvalues
at2 = np.square(at)
plt.figure(figsize=(10,6))
plt.subplot(211)
plt.plot(at,label = 'at')
plt.legend()
plt.subplot(212)
plt.plot(at2,label='at^2')
plt.legend(loc=0)

在这里插入图片描述

(2)对{ a t 2 a_t^2 at2}序列进行混成检验: 原假设 H 0 H_0 H0:序列没有相关性,备择假设 H 1 H_1 H1:序列具有相关性

m = 25 # 我们检验25个自相关系数
acf,q,p = sm.tsa.acf(at2,nlags=m,qstat=True)  ## 计算自相关系数 及p-value
out = np.c_[range(1,26), acf[1:], q, p]
output=pd.DataFrame(out, columns=['lag', "AC", "Q", "P-value"])
output = output.set_index('lag')
output
ACQP-value
lag
1.00.0358440.9044843.415822e-01
2.00.0885916.4376924.000120e-02
3.00.14744421.7863757.225955e-05
4.00.05364523.8210628.674936e-05
5.00.04667125.3633421.185340e-04
6.00.15916343.3261431.005310e-07
7.00.10951051.8419226.272714e-09
8.00.05552554.0343106.798537e-09
9.00.01872454.2839901.667087e-08
10.00.18026677.4592261.577224e-12
11.00.04100078.6598242.678490e-12
12.00.00639778.6890907.335388e-12
13.00.04487780.1316361.042143e-11
14.0-0.00126680.1327852.673556e-11
15.00.01655380.3296176.079293e-11
16.00.03662481.2945869.715658e-11
17.00.03149482.0091911.682693e-10
18.0-0.04478683.4564252.114351e-10
19.0-0.03430984.3069893.328231e-10
20.0-0.00250784.3115397.193319e-10
21.00.04383485.7040428.798365e-10
22.0-0.02396186.1207231.553194e-09
23.00.00280686.1264473.146857e-09
24.0-0.02465086.5687525.289709e-09
25.0-0.05383188.6812304.690585e-09
p-value小于显著性水平0.05,我们拒绝原假设,即认为序列具有相关性。因此具有ARCH效应。

3. ARCH波动率模型的建立

首先讲讲ARCH模型的阶次,可以用{ a t 2 a_t^2 at2}序列的偏自相关函数PACF来确定:

fig = plt.figure(figsize=(20,5))
fig = PACF(at2,lags = 30)

在这里插入图片描述

print(sm.tsa.arma_order_select_ic(at2,max_ar=10,max_ma=0,ic='aic')['aic_min_order'])
(10, 0)

因此我们可以定为10阶。然后建立关于残差平方的AR(10)模型 σ t 2 = α 0 + α 1 a t − 1 2 + ⋯ + α 10 a t − m 2 η = a t 2 − σ t 2 a t 2 = α 0 + α 1 a t − 1 2 + ⋯ + α 10 a t − m 2 + η t \large \sigma_t^2 = \alpha_0 + \alpha_1 a_{t-1}^2 + \cdots + \alpha_{10} a_{t-m}^2 \\ \large \eta =a_t^2 - \sigma_t^2 \\ \large a_t^2 = \alpha_0 + \alpha_1 a_{t-1}^2 + \cdots + \alpha_{10} a_{t-m}^2 + \eta_t σt2=α0+α1at12++α10atm2η=at2σt2at2=α0+α1at12++α10atm2+ηt

AR模型就不建立了,和上面一样的步骤建立的模型就是波动率的模型,根据模型结果即可得到波动率参数。但是事实上arch库可以一步到位。

总结上述的步骤是:先建立关于收益率序列的均值方程,然后根据均值方程的残差建立波动率ARCH模型(建立之前进行arch效应的检验)。

根据我们之前的分析,可以选择均值模型为AR(26)模型波动率模型选择ARCH(10)模型

am = arch.arch_model(r2.values,mean='AR',lags=26,vol='ARCH',p=10) 
res = am.fit()
res.summary()
Iteration:      1,   Func. Count:     40,   Neg. LLF: 40965152.75702708
Iteration:      2,   Func. Count:     86,   Neg. LLF: 8698.970310546452
Iteration:      3,   Func. Count:    128,   Neg. LLF: 2902.1288794018164
Iteration:      4,   Func. Count:    170,   Neg. LLF: 1309895.9030277207
Iteration:      5,   Func. Count:    211,   Neg. LLF: -1347.791200776411
Iteration:      6,   Func. Count:    252,   Neg. LLF: 243898.86093785244
Iteration:      7,   Func. Count:    296,   Neg. LLF: 15465.836561672153
Iteration:      8,   Func. Count:    340,   Neg. LLF: 736661.3830451616
Iteration:      9,   Func. Count:    384,   Neg. LLF: -1745.0926489160058
Optimization terminated successfully    (Exit mode 0)
            Current function value: -1745.09264841222
            Iterations: 13
            Function evaluations: 384
            Gradient evaluations: 9
AR - ARCH Model Results
Dep. Variable:y R-squared: 0.043
Mean Model:AR Adj. R-squared: 0.006
Vol Model:ARCH Log-Likelihood: 1745.09
Distribution:Normal AIC: -3414.19
Method:Maximum Likelihood BIC: -3241.19
No. Observations: 701
Date:Sat, Aug 12 2023 Df Residuals: 674
Time:13:24:05 Df Model: 27
Mean Model
coefstd errtP>|t|95.0% Conf. Int.
Const1.0522e-032.473e-03 0.425 0.670[-3.795e-03,5.899e-03]
y[1] 0.02299.396e-02 0.243 0.808[ -0.161, 0.207]
y[2] -0.01894.219e-02 -0.449 0.654[ -0.102,6.377e-02]
y[3] -0.01725.463e-02 -0.315 0.753[ -0.124,8.988e-02]
y[4] -0.0110 0.112-9.851e-02 0.922[ -0.230, 0.208]
y[5] 0.01087.599e-02 0.142 0.887[ -0.138, 0.160]
y[6] -0.05884.549e-02 -1.293 0.196[ -0.148,3.034e-02]
y[7] 0.04894.886e-02 1.001 0.317[-4.687e-02, 0.145]
y[8]6.7808e-03 0.1096.227e-02 0.950[ -0.207, 0.220]
y[9] -0.0200 0.125 -0.160 0.873[ -0.266, 0.226]
y[10] 0.03415.917e-02 0.576 0.565[-8.189e-02, 0.150]
y[11] -0.02725.563e-02 -0.489 0.625[ -0.136,8.185e-02]
y[12] 0.05693.627e-02 1.568 0.117[-1.422e-02, 0.128]
y[13] -0.03603.322e-02 -1.083 0.279[ -0.101,2.913e-02]
y[14] 0.01675.274e-02 0.316 0.752[-8.671e-02, 0.120]
y[15] -0.0638 0.194 -0.328 0.743[ -0.445, 0.317]
y[16] 0.04964.578e-02 1.084 0.279[-4.012e-02, 0.139]
y[17]8.2176e-035.988e-02 0.137 0.891[ -0.109, 0.126]
y[18] -0.02494.447e-02 -0.559 0.576[ -0.112,6.229e-02]
y[19] 0.02075.476e-02 0.378 0.706[-8.665e-02, 0.128]
y[20] 0.01734.791e-02 0.361 0.718[-7.659e-02, 0.111]
y[21]-8.7310e-035.982e-02 -0.146 0.884[ -0.126, 0.109]
y[22]5.7469e-038.029e-027.158e-02 0.943[ -0.152, 0.163]
y[23] 0.03013.645e-02 0.826 0.409[-4.133e-02, 0.102]
y[24] -0.04534.574e-02 -0.991 0.322[ -0.135,4.430e-02]
y[25] 0.05456.544e-02 0.833 0.405[-7.377e-02, 0.183]
y[26] -0.12766.602e-02 -1.9335.328e-02[ -0.257,1.802e-03]
Volatility Model
coefstd errtP>|t|95.0% Conf. Int.
omega1.9493e-041.482e-04 1.316 0.188[-9.549e-05,4.853e-04]
alpha[1] 0.0580 0.217 0.267 0.790[ -0.368, 0.484]
alpha[2] 0.0580 0.263 0.221 0.825[ -0.457, 0.573]
alpha[3] 0.05806.268e-02 0.926 0.355[-6.483e-02, 0.181]
alpha[4] 0.0580 0.113 0.513 0.608[ -0.164, 0.280]
alpha[5] 0.0580 0.164 0.353 0.724[ -0.264, 0.380]
alpha[6] 0.0580 0.296 0.196 0.845[ -0.523, 0.639]
alpha[7] 0.0580 0.147 0.395 0.693[ -0.230, 0.346]
alpha[8] 0.0580 0.299 0.194 0.846[ -0.529, 0.645]
alpha[9] 0.0580 0.9705.979e-02 0.952[ -1.844, 1.960]
alpha[10] 0.09119.790e-02 0.931 0.352[ -0.101, 0.283]


Covariance estimator: robust ```python res.params ```
Const        0.001052
y[1]         0.022875
y[2]        -0.018924
y[3]        -0.017207
y[4]        -0.010993
y[5]         0.010797
y[6]        -0.058818
y[7]         0.048907
y[8]         0.006781
y[9]        -0.020025
y[10]        0.034083
y[11]       -0.027176
y[12]        0.056871
y[13]       -0.035974
y[14]        0.016653
y[15]       -0.063768
y[16]        0.049611
y[17]        0.008218
y[18]       -0.024858
y[19]        0.020678
y[20]        0.017313
y[21]       -0.008731
y[22]        0.005747
y[23]        0.030099
y[24]       -0.045339
y[25]        0.054481
y[26]       -0.127592
omega        0.000195
alpha[1]     0.058013
alpha[2]     0.058013
alpha[3]     0.058013
alpha[4]     0.058013
alpha[5]     0.058013
alpha[6]     0.058013
alpha[7]     0.058013
alpha[8]     0.058013
alpha[9]     0.058013
alpha[10]    0.091128
Name: params, dtype: float64

模型的R-squared较小,拟合效果一般。

# 刺猬图用于展示模型对数据的拟合情况以及残差(方差残差)的分布。

res.hedgehog_plot()

在这里插入图片描述

从拟合结果来看,大致上的波动情况拟合效果还是比较好的

4.2 GARCH模型与波动率预测

虽然ARCH模型简单,但为了充分刻画收益率的波动率过程,往往需要很多参数,例如上面用到ARCH(10)模型,有时会有更高的ARCH(m)模型。因此,Bollerslev(1986)年提出了一个推广形式,称为广义的ARCH模型(GARCH)

GARCH(Generalized Autoregressive Conditional Heteroskedasticity)模型是一种用于建模金融时间序列数据中异方差性的统计模型。它是 ARCH(Autoregressive Conditional Heteroskedasticity)模型的扩展,通过引入过去的方差(方差残差)的高阶项来更准确地描述时间序列数据中的方差结构。

GARCH 模型的一般形式如下:

y t = μ t + ϵ t ϵ t = σ t z t σ t 2 = ω + ∑ i = 1 p α i ϵ t − i 2 + ∑ j = 1 q β j σ t − j 2 \begin{align*} y_t &= \mu_t + \epsilon_t \\ \epsilon_t &= \sigma_t z_t \\ \sigma_t^2 &= \omega + \sum_{i=1}^p \alpha_i \epsilon_{t-i}^2 + \sum_{j=1}^q \beta_j \sigma_{t-j}^2 \end{align*} ytϵtσt2=μt+ϵt=σtzt=ω+i=1pαiϵti2+j=1qβjσtj2

其中:

  • y t y_t yt 是时间序列的观测值。
  • μ t \mu_t μt 是平均值(可能是一个常数,也可能是一个模型)。
  • ϵ t \epsilon_t ϵt 是时间点 t t t 的标准化残差,通常假设为服从均值为零、方差为一的独立同分布的随机变量。
  • σ t 2 \sigma_t^2 σt2 是时间点 t t t 的方差,它是过去若干个标准化残差平方的加权和,权重由 α \alpha α β \beta β 参数确定。
  • z t z_t zt 是标准正态随机变量。
  • ω \omega ω α 1 , … , α p \alpha_1, \ldots, \alpha_p α1,,αp β 1 , … , β q \beta_1, \ldots, \beta_q β1,,βq 是 GARCH 模型的参数, ω \omega ω 表示常数项, α \alpha α 控制过去残差项的影响, β \beta β 控制过去方差项的影响。

GARCH 模型通过建模时间序列数据的方差结构,能够捕捉金融时间序列数据中的波动性和异方差性。通常,模型的参数可以通过最大似然估计等方法进行估计。

在 Python 中,可以使用一些统计库(如 statsmodels)或专门的金融时间序列库(如 arch)来拟合 GARCH 模型并进行时间序列分析。具体实现可能会因库的不同而有所变化。

a=int(len(r2)*0.05)
train = r2[:-a]
test = r2[-a:]
train.head()
return
date
2020-01-03-0.051530
2020-01-06-0.000586
2020-01-070.016870
2020-01-08-0.006484
2020-01-090.014713
## 4.2.1 GARCH模型定阶

与之前的ARCH模型建立过程类似,不过GARCH(m,s)的定阶较难,一般使用低阶模型如GARCH(1,1),GARCH(2,1),GARCH(1,2)等。

对于 GARCH(m,s) 模型,m表示 ARCH 部分的阶数,s 表示 GARCH 部分的阶数。一般使用ACF和PACF难以判断 因此我们使用信息准则来判断阶数。

import pandas as pd
import numpy as np
from arch import arch_model

# 定义可能的 GARCH(p,q) 阶数范围
p_range = range(0, 10)  # 替换为合适的范围
q_range = range(0, 10)  # 替换为合适的范围

best_aic = np.inf
best_order = None
best_results = None

for p in p_range:
    for q in q_range:
        try:
            # 拟合 GARCH(p,q) 模型
            model = arch_model(r2, vol='Garch', p=p, q=q)
            results = model.fit()
            
            # 计算 AIC 和 BIC
            aic = results.aic
            bic = results.bic
            
            # 判断是否是当前最优模型
            if aic < best_aic:
                best_aic = aic
                best_order = (p, q)
                best_results = results
        except:
            continue

print("Best AIC:", best_aic)
print("Best order (p, q):", best_order)

Best AIC: -3568.971155691478

Best order (p, q): (4, 3)

4.2.2 GARCH模型建立

下面我们以之前的数据为例,构建GARCH模型,均值方程为AR(26)模型,波动率模型为GARCH(4,3)

am = arch.arch_model(train.values,mean='AR',lags=26,vol='GARCH',p=4, q=3) 
res = am.fit()
res.summary()
AR - GARCH Model Results
Dep. Variable:y R-squared: 0.035
Mean Model:AR Adj. R-squared: -0.004
Vol Model:GARCH Log-Likelihood: 1644.01
Distribution:Normal AIC: -3218.02
Method:Maximum Likelihood BIC: -3060.52
No. Observations: 665
Date:Sat, Aug 12 2023 Df Residuals: 638
Time:13:37:46 Df Model: 27
Mean Model
coefstd errtP>|t|95.0% Conf. Int.
Const9.4586e-048.598e-04 1.100 0.271[-7.392e-04,2.631e-03]
y[1] 0.02573.921e-02 0.655 0.513[-5.118e-02, 0.103]
y[2] -0.01123.911e-02 -0.286 0.775[-8.783e-02,6.548e-02]
y[3] -0.03194.244e-02 -0.751 0.453[ -0.115,5.133e-02]
y[4] -0.01624.561e-02 -0.356 0.722[ -0.106,7.316e-02]
y[5]-8.7703e-033.993e-02 -0.220 0.826[-8.703e-02,6.949e-02]
y[6] -0.05354.372e-02 -1.225 0.221[ -0.139,3.215e-02]
y[7] 0.04314.307e-02 1.001 0.317[-4.132e-02, 0.128]
y[8]-8.9600e-043.808e-02-2.353e-02 0.981[-7.553e-02,7.374e-02]
y[9] -0.01763.955e-02 -0.446 0.655[-9.516e-02,5.987e-02]
y[10] 0.02764.843e-02 0.569 0.569[-6.737e-02, 0.122]
y[11] -0.03413.899e-02 -0.874 0.382[ -0.111,4.234e-02]
y[12] 0.04743.623e-02 1.309 0.190[-2.358e-02, 0.118]
y[13] -0.02673.607e-02 -0.739 0.460[-9.734e-02,4.404e-02]
y[14] 0.02703.661e-02 0.737 0.461[-4.477e-02,9.873e-02]
y[15] -0.05824.071e-02 -1.430 0.153[ -0.138,2.159e-02]
y[16] 0.03264.404e-02 0.740 0.459[-5.372e-02, 0.119]
y[17]-7.4221e-043.784e-02-1.962e-02 0.984[-7.490e-02,7.342e-02]
y[18] -0.02993.411e-02 -0.875 0.381[-9.670e-02,3.700e-02]
y[19] 0.03433.947e-02 0.869 0.385[-4.305e-02, 0.112]
y[20] -0.02013.920e-02 -0.514 0.607[-9.697e-02,5.668e-02]
y[21] -0.02384.241e-02 -0.562 0.574[ -0.107,5.927e-02]
y[22]9.5758e-034.121e-02 0.232 0.816[-7.119e-02,9.034e-02]
y[23] 0.02693.733e-02 0.720 0.471[-4.627e-02, 0.100]
y[24] -0.03913.708e-02 -1.053 0.292[ -0.112,3.362e-02]
y[25] 0.05083.337e-02 1.522 0.128[-1.461e-02, 0.116]
y[26] -0.12033.557e-02 -3.3817.218e-04[ -0.190,-5.056e-02]
Volatility Model
coefstd errtP>|t|95.0% Conf. Int.
omega5.3436e-051.748e-05 3.0572.239e-03[1.917e-05,8.770e-05]
alpha[1] 0.0498 0.114 0.435 0.663[ -0.175, 0.274]
alpha[2] 0.0498 0.108 0.462 0.644[ -0.161, 0.261]
alpha[3] 0.05186.577e-02 0.788 0.431[-7.711e-02, 0.181]
alpha[4] 0.0498 0.162 0.308 0.758[ -0.268, 0.367]
beta[1] 0.2325 1.574 0.148 0.883[ -2.853, 3.318]
beta[2] 0.2325 1.538 0.151 0.880[ -2.781, 3.246]
beta[3] 0.2325 0.213 1.094 0.274[ -0.184, 0.649]


Covariance estimator: robust ```python res.params ```
Const       0.000946
y[1]        0.025662
y[2]       -0.011171
y[3]       -0.031857
y[4]       -0.016236
y[5]       -0.008770
y[6]       -0.053549
y[7]        0.043091
y[8]       -0.000896
y[9]       -0.017646
y[10]       0.027556
y[11]      -0.034085
y[12]       0.047423
y[13]      -0.026651
y[14]       0.026982
y[15]      -0.058197
y[16]       0.032606
y[17]      -0.000742
y[18]      -0.029851
y[19]       0.034320
y[20]      -0.020146
y[21]      -0.023840
y[22]       0.009576
y[23]       0.026884
y[24]      -0.039052
y[25]       0.050793
y[26]      -0.120278
omega       0.000053
alpha[1]    0.049823
alpha[2]    0.049823
alpha[3]    0.051804
alpha[4]    0.049823
beta[1]     0.232454
beta[2]     0.232454
beta[3]     0.232454
Name: params, dtype: float64

我们得到波动率模型: σ t 2 = 0.000053 + 0.049823 a t − 1 2 + 0.049823 a t − 2 2 + 0.051804 a t − 3 2 + 0.049823 a t − 4 2 + 0.232454 σ t − 1 2 + 0.232454 σ t − 2 2 + 0.232454 σ t − 3 2 \large \sigma_t^2 = 0.000053 +0.049823a_{t-1}^2 + 0.049823 a_{t-2}^2 + 0.051804a_{t-3}^2 + 0.049823 a_{t-4}^2 + 0.232454\sigma_{t-1}^2 + 0.232454\sigma_{t-2}^2 +0.232454\sigma_{t-3}^2 σt2=0.000053+0.049823at12+0.049823at22+0.051804at32+0.049823at42+0.232454σt12+0.232454σt22+0.232454σt32

res.plot()
plt.plot(r2.values)

在这里插入图片描述

观察上图,第一张图为标准化残差,近似平稳序列,说明模型在一定程度上是正确的;

第二张图,橙色为原始收益率序列、蓝色为条件异方差序列,可以发现条件异方差很好得表现出了波动率。

res.hedgehog_plot()

在这里插入图片描述

观察拟合图发现,在方差的还原上还是不错的。

4.2.3 波动率预测

此前建立的模型中直接预测了收益率,然而直接预测收益率准确度并不是很高,因此很多时候我们主要用来预测波动率,根据上面建立的波动率模型:

σ t 2 = 0.000053 + 0.049823 a t − 1 2 + 0.049823 a t − 2 2 + 0.051804 a t − 3 2 + 0.049823 a t − 4 2 + 0.232454 σ t − 1 2 + 0.232454 σ t − 2 2 + 0.232454 σ t − 3 2 \large \sigma_t^2 = 0.000053 +0.049823a_{t-1}^2 + 0.049823 a_{t-2}^2 + 0.051804a_{t-3}^2 + 0.049823 a_{t-4}^2 + 0.232454\sigma_{t-1}^2 + 0.232454\sigma_{t-2}^2 +0.232454\sigma_{t-3}^2 σt2=0.000053+0.049823at12+0.049823at22+0.051804at32+0.049823at42+0.232454σt12+0.232454σt22+0.232454σt32

我们可以按照我们建立好的模型一步步计算。

len(test)
36
ini = res.resid[-25:]
a = np.array(res.params[1:26])
w = a[::-1] # 系数
for i in range(36):
    new =float(test.values[i]) - (res.params[0] + w.dot(ini[-25:]))
    ini = np.append(ini,new)
print(len(ini))
at_pre = ini[-36:]
at_pre2 = at_pre**2
at_pre2
61

array([1.01232203e-03, 5.03864617e-05, 1.10233346e-03, 7.45366735e-06,
       2.06208245e-04, 1.53182463e-06, 8.45075716e-04, 7.87922789e-05,
       9.38252028e-05, 6.13691187e-04, 1.09033703e-05, 7.73925075e-05,
       3.14698031e-03, 1.94830844e-05, 2.77432172e-04, 1.35996184e-06,
       6.79155523e-04, 9.95206154e-05, 5.21642002e-06, 4.91895152e-06,
       6.36277969e-04, 1.47598426e-05, 4.07490261e-05, 2.50428353e-04,
       4.76165619e-06, 4.34576525e-06, 9.68050383e-05, 1.15417106e-03,
       1.67343335e-04, 3.18757007e-04, 7.45178307e-06, 2.55272742e-04,
       5.73669611e-05, 9.97774368e-06, 2.65501364e-05, 6.28396273e-06])

接着根据波动率模型预测波动率:
σ t 2 = 0.000053 + 0.049823 a t − 1 2 + 0.049823 a t − 2 2 + 0.051804 a t − 3 2 + 0.049823 a t − 4 2 + 0.232454 σ t − 1 2 + 0.232454 σ t − 2 2 + 0.232454 σ t − 3 2 \large \sigma_t^2 = 0.000053 +0.049823a_{t-1}^2 + 0.049823 a_{t-2}^2 + 0.051804a_{t-3}^2 + 0.049823 a_{t-4}^2 + 0.232454\sigma_{t-1}^2 + 0.232454\sigma_{t-2}^2 +0.232454\sigma_{t-3}^2 σt2=0.000053+0.049823at12+0.049823at22+0.051804at32+0.049823at42+0.232454σt12+0.232454σt22+0.232454σt32

res.conditional_volatility[-4:]
array([0.03698157, 0.03344135, 0.03366974, 0.03276049])
res.params
Const       0.000946
y[1]        0.025662
y[2]       -0.011171
y[3]       -0.031857
y[4]       -0.016236
y[5]       -0.008770
y[6]       -0.053549
y[7]        0.043091
y[8]       -0.000896
y[9]       -0.017646
y[10]       0.027556
y[11]      -0.034085
y[12]       0.047423
y[13]      -0.026651
y[14]       0.026982
y[15]      -0.058197
y[16]       0.032606
y[17]      -0.000742
y[18]      -0.029851
y[19]       0.034320
y[20]      -0.020146
y[21]      -0.023840
y[22]       0.009576
y[23]       0.026884
y[24]      -0.039052
y[25]       0.050793
y[26]      -0.120278
omega       0.000053
alpha[1]    0.049823
alpha[2]    0.049823
alpha[3]    0.051804
alpha[4]    0.049823
beta[1]     0.232454
beta[2]     0.232454
beta[3]     0.232454
Name: params, dtype: float64
ini2 = res.conditional_volatility[-3:] #上3个条件异方差值
i=5
for i in range(36):
    new = res.params[-8] + res.params[-7]*at_pre2[i-4]+ res.params[-6]*at_pre2[i-3]+res.params[-5]*at_pre2[i-2]+res.params[-4]*at_pre2[i-1]+ res.params[-3]*ini2[-3]+res.params[-2]*ini2[-2]+res.params[-1]*ini2[-1]
    ini2 = np.append(ini2,new)
vol_pre = ini2[-36:]
vol_pre
array([0.02327402, 0.02095812, 0.01800726, 0.01462951, 0.01262221,
       0.01064216, 0.00892807, 0.00758952, 0.00642488, 0.00543744,
       0.00465656, 0.00393425, 0.00335403, 0.00302198, 0.00261849,
       0.00231972, 0.00207602, 0.00173262, 0.00153203, 0.00133422,
       0.00116177, 0.00102694, 0.00090656, 0.00080768, 0.00073766,
       0.00063937, 0.00057625, 0.00052524, 0.00052108, 0.00050378,
       0.00050064, 0.00049077, 0.00043832, 0.00041812, 0.00038316,
       0.000359  ])

我们将原始数据、条件异方差拟合数据及预测数据一起画出来,分析波动率预测情况

plt.figure(figsize=(15,5))
plt.plot(r2.values,label='origin_data')
plt.plot(res.conditional_volatility,label='conditional_volatility')
x=range(691,727)
plt.plot(x,vol_pre,'.r',label='predict_volatility')
plt.legend(loc=0)

在这里插入图片描述

保存波动率

am = arch.arch_model(r2.values,mean='AR',lags=26,vol='GARCH',p=4, q=3) #用整个文件
res = am.fit()
ddf=pd.DataFrame(res.conditional_volatility)
ddf.head(10)
ddf.to_excel('波动率.xlsx')
plt.figure(figsize=(15,5))
plt.plot(r2.values,label='origin_data')
plt.plot(res.conditional_volatility,label='conditional_volatility')
plt.legend(loc=0)

在这里插入图片描述

小结

本篇是时间序列基础课程的最后一篇,重点还是在基础的概念和python实现上。事实上要真学好这些模型,少不了更多的参考和实验。

另外,还有很多扩展的或改进的模型如求和GARCH、GARCH-M模型、指数GARCH、EGARCH模型等等。 对于波动率模型,还有比较常用的有随机波动率模型等, 有兴趣可以去研究下。

参考文献

1.《金融时间序列分析》 第2版 Ruey S.Tsay著 王辉、潘家柱 译

2.Time Series analysis tsa http://nipy.bic.berkeley.edu/nightly/statsmodels/doc/html/tsa.html

3.Python arch 3.2 [https://pypi.python.org/pypi/arch]
(https://pypi.python.org/pypi/arch)

4.Python statsmodels [https://www.statsmodels.org/stable/index.html]

5.优矿作者fyiqi的分享[https://uqer.datayes.com/community/user/56d7ce6b228e5b57c243d4b4/shares]

关注gzh“finance 褪黑素”获取案例代码等更多学习资料。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐