對2016年至2018年滬深300指數的漲跌幅數據建立ARCH(1)、EWMA和GARCH(1,1)三種波動率模型,並以30天前的數據為起點,逐一預測後一天的波動率。
import numpy as npimport pandas as pddf=pd.read_excel('C:/Users/Desktop/滬深300指數.xlsx',header=0,index_col=0)data=(df.iloc[:,0]/df.iloc[:,0].shift(1)-1).dropna()data.name='滬深300漲跌幅'from arch import arch_modelarch=arch_model(y=data,mean='Constant',lags=0,vol='ARCH',p=1,o=0,q=0,dist='normal')archmodel=arch.fit()archmodel.summary()archmodel.plot()Out[6]: <class 'statsmodels.iolib.summary.Summary'>""" Constant Mean - ARCH Model Results ==============================================================================Dep. Variable: 滬深300漲跌幅 R-squared: -0.000Mean Model: Constant Mean Adj. R-squared: -0.000Vol Model: ARCH Log-Likelihood: 2232.59Distribution: Normal AIC: -4459.18Method: Maximum Likelihood BIC: -4445.41 No. Observations: 730Date: Sun, Mar 29 2020 Df Residuals: 727Time: 18:59:32 Df Model: 3 Mean Model ============================================================================== coef std err t P>|t| 95.0% Conf. Int.------------------------------------------------------------------------------mu -3.0768e-04 4.190e-04 -0.734 0.463 [-1.129e-03,5.135e-04] Volatility Model ============================================================================ coef std err t P>|t| 95.0% Conf. Int.----------------------------------------------------------------------------omega 8.9476e-05 8.234e-06 10.866 1.671e-27 [7.334e-05,1.056e-04]alpha[1] 0.4000 0.107 3.754 1.737e-04 [ 0.191, 0.609]============================================================================Covariance estimator: robust
可以看到ARCH(1)模型的參數ω=0.0000895,α=0.4,因此模型表達式為σn2=0.0000895+0.4(un-1)2。
garch=arch_model(y=data,mean='Constant',lags=0,vol='GARCH',p=1,o=0,q=1,dist='normal')garchmodel=garch.fit()garchmodel.paramsOut[7]: mu 0.000465omega 0.000003alpha[1] 0.100000beta[1] 0.880000Name: params, dtype: float64garchmodel.plot()
可以看到GARCH(1,1)模型的參數ω=0.00000298,α=0.1,β=0.88,因此模型表達式為σn2=0.00000298+0.1(un-1)2+0.88(σn-1)2。下面計算長期波動率,即√VL:
vol=np.sqrt(garchmodel.params[1]/(1-garchmodel.params[2]-garchmodel.params[3]))volOut[10]: 0.012212037954677738
由於實踐證明對於日收益率數據,λ=0.94時預測效果最好,因此EWMA模型為σn2=0.06(un-1)2+0.94(σn-1)2。
根據上述三種模型的結果,我們就可以根據前一天的波動率和收益率數據來預測下一天的波動率。最後30天數據日期為2018年11月19號-2018年12月28號,因此隨著每一天的數據更新,我們可以用以上三種模型預測2018年11月20號-2018年12月29號的波動率數據,並畫圖比較:
vol301=np.zeros(30)u30=data[-30:]vol301[0]=np.sqrt(0.0000895+0.4*data[-31]**2)for i in range(29): vol301[i+1]=np.sqrt(0.0000895+0.4*u30[i]**2)vol302=np.zeros(30)vol302[0]=data[-34:-29].std()for i in range(29): vol302[i+1]=np.sqrt(0.00000298+0.1*u30[i]**2+0.88*vol302[i]**2)vol303=np.zeros(30)vol303[0]=data[-34:-29].std()for i in range(29): vol303[i+1]=np.sqrt(0.06*u30[i]**2+0.94*vol302[i]**2)import datetimeriqi=(u30.index+datetime.timedelta(days=1)).strftime("%Y-%m-%d")import matplotlib.pyplot as pltplt.figure(figsize=(15,5))plt.plot(riqi,vol301,label='ARCH(1)')plt.plot(riqi,vol302,label='GARCH(1,1)')plt.plot(riqi,vol303,label='EWMA') plt.xticks(rotation=30)plt.legend()plt.grid()
可以發現GARCH(1,1)和EWMA模型的預測結果是非常相似的。
思路和估計波動率一樣,方差換成了協方差,u²n-1換成了ux n-1· uy n-1:
注意上式中Covn-1 = ρxy,n-1×σx,n-1×σy,n-1,後面三項都可以通過同一種方法估算出來,比如5日MA。計算出Covn後代入相關係數公式可得ρxy,n = Covn / σx,n×σy,n。下面簡單介紹相關係數5日MA的計算方法:
df2=pd.read_excel('C:/Users/Desktop/滬深300指數與上證180指數的日漲跌幅.xlsx',header=0,index_col=0)cor=df2.rolling(window=5).corr().dropna();corOut[16]: 滬深300漲跌幅 上證180漲跌幅日期 2016-01-08 滬深300漲跌幅 1.000000 0.999923 上證180漲跌幅 0.999923 1.0000002016-01-11 滬深300漲跌幅 1.000000 0.999783 上證180漲跌幅 0.999783 1.0000002016-01-12 滬深300漲跌幅 1.000000 0.999685 ... ...2018-12-26 上證180漲跌幅 0.966159 1.0000002018-12-27 滬深300漲跌幅 1.000000 0.984355 上證180漲跌幅 0.984355 1.0000002018-12-28 滬深300漲跌幅 1.000000 0.987533 上證180漲跌幅 0.987533 1.000000[1454 rows x 2 columns]c=cor.loc[(slice(None),'滬深300漲跌幅'),:]d=pd.Series(c.iloc[:,1].values,index=df2.index[4:],name='5日移動平均相關係數')d.index.name='date'd.plot()
其中cor.loc[(slice(None),『滬深300漲跌幅』),:]的各參數的解釋如下:loc[(a,b),c]中第一個參數元組為索引內容,a為level0索引對應的內容,b為level1索引對應的內容;因為cor是一個dataframe,所以要用c即『:』來指定任意的列;slice(None)是切片操作,這裡用來選擇任意的level0索引,也就是日期。