本篇文章重在阐述如何对单变量进行波动率进行建模,并使用python进行实现。后续文章将会继续探讨如何对多维资产组合的波动率进行建模。
一、 Garch模型的背景——波动率特征
1. 使用波动率的场景
1) 期权定价BS公式
2) 计算头寸的风险值
3) 均值-方差框架下的资产配置
4) 提升参数估计和区间预测的精确度
使用期权的价格得到隐含波动率:即由BS公式反推出条件标准差,(假设:标的资产的价格符合几何布朗运动)
一般而言,金融市场的波动率具有如下特征:
1) 条件异方差和波动率聚集:即波动率在一些时间段上高,在另外一些时间段上低
2) 波动率以连续方式随时间变化,鲜有跳跃的场景。
3) 波动率不发散到无穷,一般在固定的范围内变化,从而从统计角度来说是平稳的
4) 波动率对价格大幅上升和价格大幅下降的反应是不同的——杠杆效应
因此,资产收益率往往会呈现条件异方差性的效果,使用Garch模型可以提高波动率估计的准确性。
二、收益率的序列相关性
下图绘制了沪深300指数的收益率图像,可以看出指数收益率存在较为明显的波动率聚集情况。即,大的波动率后面一般会有着波动延续。这一现象也可以直接从金融逻辑来理解。当市场出现较大波动时,这种波动可能会持续下去。因此,简单的使用过去方差对未来方差进行预测就出出现较大偏误
三、 对资产收益率序列建立一个波动率模型的步骤
一般而言,标准的波动率建模服从以下步骤
(1) 通过检验数据的序列相关性建立一个均值方程,并消除可能存在的线性依赖,如使用ARMA模型
(2) 对均值方程的残差进行ARCH检验,即进行条件异方差性检验
(3) 如果ARCH效应在统计上是显著的,则指定一个波动率模型,并对均值方程和波动率方程进行联合估计
(4) 检验所拟合的模型,并进行改进。
四、 ARCH 模型
上述步骤中,我们提到了ARCH(Auto Regressive Conditional Heteroskedasticity,自回归条件异方差,by Engle,1992)模型
ARCH模型的基本思想是:
(1) 资产收益率的扰动a_t是序列不相关的,但不是独立的
(2) a_t的不独立性可以用其延迟值的简单二次函数来表述
ARCH(m)模型可以设为:
从模型结构来看,大的过去的扰动会导致信息的条件异方差。从而有取绝对值较大的值的倾向。即,在ARCH的框架下,大的扰动会倾向于紧接着出现另一个大的扰动。即,类似于波动率聚集的现象。
五、 GARCH模型
ARCH模型存在的一个较大问题在于,在估计方差回归方程的时候,需要估计p个参数,并且,滞后多少阶也并不好确定。因此,Bollerslev(1986)提出了广义ARCH模型(GARCH),GARCH模型可以由下面的方程表示:
其中为资产收益率的标准差。并且,模型设定一般只选取Garch(1,1)即可。
六、使用Python对沪深300指数进行波动率建模,并比较样本外预测效果
#------1.使用train的model来对波动率进行GARCH建模----------------------
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os as os
from arch import arch_model
data0 = pd.read_csv('300data.csv')
data = np.array(data0['pct_chg'])
train = data[:-10]
test = data[-10:]
am = arch_model(train,vol='Garch')
res = am.fit()
res.summary()
#可以看出,此时garch的两个参数都十分显著
#绘制标准化残差,发现残差基本上为平稳的,说明拟合效果较好#绘制条件方差,并在上面绘制原始收益率曲线,发现拟合的效果较好
res.plot()
plt.plot(data,'y-')
# 对样本内的方差进行拟合,发现拟合效果较好
res.hedgehog_plot()
#-----------------------------2.使用GARCH模型预测------------------------------------------
# 波动率模型为:sigmat2 = omega + alpha*at_tminus2 + beta*sigma_tminus2
# 收益率预测为常系数模型:at = rt - mu
# 首先计算at
at_pre = test - res.params[0]
at_pre2 = at_pre * 2
# 接着计算波动率
# 拿出最后两个条件方差
ini = res.conditional_volatility[-2:]
for i in range(10):
new = res.params[1] + res.params[2]*at_pre2[i] + res.params[3]*ini[-1]
ini = np.append(ini,new)
vol_pre = ini[-10:]
vol_pre
# 绘图比较原始数据,条件方差,及10步预测方差,发现预测效果较好
plt.figure(figsize=(15,5))
plt.plot(data,'y-',label='origin_data')
plt.plot(res.conditional_volatility,label='conditional_volatility')
x=range(3611,3621)
plt.plot(x,vol_pre,'.r',label='predict_volatility')
plt.legend(loc=0)
上图中,数据总长度为3622日,我们使用3612日作为train集,10日作为test集。对3612日进行波动率建模,并对剩余10日进行波动率预测。将条件方差和原始收益率曲线绘制在一起,可以发现,garch(1,1)模型对波动率取得了较好的估计效果。
参考文献:
1. Financial Econometrics Notes, Kevin Sheppard, Oxford University
2. Analysis of Financial Time Series 3rd Edition, Ruey S. Tsay