添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
金融数据中的时间序列分析——ARMA模型

金融数据中的时间序列分析——ARMA模型

在对金融数据进行分析时,不可避免地会遇到时间序列数据,常见的时间序列模型有AR自回归模型,MA移动平均模型和 ARMA 模型等模型。本文主要介绍 ARMA 模型 [1]

ARMA 模型可以理解为 AR(p) 自回归模型和 MA(q) 移动平均模型的合并

  • AR(p) 模型尝试解释我们在交易市场中观察到的动量和均值回归效应
  • MA(q) 模型则试图捕获白噪声项的冲击效应

ARMA 作为二者合并的金融时间序列模型,既可以捕获动量、均值回归效应,也能够捕获冲击效应。同时 ARMA 模型不考虑波动集群现象——收益率的巨大变化通常伴随着进一步的巨大变化。

ARMA(1,1) 模型可以表示如下:

e(t) 代表白噪声,且相应的期望为0( E[e(t)] = 0

ARMA 在使用时候通常比单独使用 AR(p) 自回归模型或 MA(q) 模型需要更少的参数。

下面根据给定的参数模拟一个 ARMA(2,2) 的过程,然后根据模拟的数据拟合一个 ARMA(2,2) 模型,来看看它是否能够正确地估计那些参数。这里设置自回归参数 α 为[0.5,-0.25],移动平均参数 β 为[0.5,-0.3]

首先导入相应的包

 import pandas as pd
 import numpy as np
 import statsmodels.tsa.api as smt
 import statsmodels.api as sm
 import scipy.stats as scs
 import statsmodels.stats as sms
 import matplotlib.pyplot as plt
 %matplotlib inline

然后编写对应的函数

 def tsplot(y, lags=None, figsize=(10, 8), style='bmh'):
     if not isinstance(y, pd.Series):
         y = pd.Series(y)
     with plt.style.context(style):    
         fig = plt.figure(figsize=figsize)
         layout = (3, 2)
         ts_ax = plt.subplot2grid(layout, (0, 0), colspan=2)
         acf_ax = plt.subplot2grid(layout, (1, 0))
         pacf_ax = plt.subplot2grid(layout, (1, 1))
         qq_ax = plt.subplot2grid(layout, (2, 0))
         pp_ax = plt.subplot2grid(layout, (2, 1))
         y.plot(ax=ts_ax)
         ts_ax.set_title('Time Series Analysis Plots')
         smt.graphics.plot_acf(y, lags=lags, ax=acf_ax, alpha=0.05)
         smt.graphics.plot_pacf(y, lags=lags, ax=pacf_ax, alpha=0.05)
         sm.qqplot(y, line='s', ax=qq_ax)
         qq_ax.set_title('QQ Plot')        
         scs.probplot(y, sparams=(y.mean(), y.std()), plot=pp_ax)
         plt.tight_layout()
     return

下面模拟生成对应的数据

 max_lag = 30
 n = int(5000) # 总的样本个数
 burn




    
 = int(n/10) # 拟合前丢弃的样本量
 alphas = np.array([0.5, -0.25])
 betas = np.array([0.5, -0.3])
 ar = np.r_[1, -alphas]
 ma = np.r_[1, betas]
 arma22 = smt.arma_generate_sample(ar=ar, ma=ma, nsample=n, burnin=burn)
 _ = tsplot(arma22, lags=max_lag)

下面对模拟生成的数据拟合 ARMA 模型

 mdl = smt.ARMA(arma22, order=(2, 2)).fit(
     maxlag=max_lag, method='mle', trend='nc', burnin=burn)
 print(mdl.summary())
 ARMA Model Results                              
 ====================================================================
 Dep. Variable:              y   No. Observations:         5000
 Model:             ARMA(2, 2)   Log Likelihood       -7054.211
 Method:                   mle   S.D. of innovations      0.992
 Date:         Mon, 8 Jun 2020   AIC                  14118.423
 Time:                21:27:58   BIC                  14151.009
 Sample:                     0   HQIC                 14129.844
 ====================================================================
                coef  std err        z    P>|z|    [0.025      0.975]
 --------------------------------------------------------------------
 ar.L1.y      0.5476    0.058    9.447    0.000     0.434       0.661
 ar.L2.y     -0.2566    0.015  -17.288    0.000    -0.286      -0.228
 ma.L1.y      0.4548    0.060    7.622    0.000     0.338       0.572
 ma.L2.y     -0.3432    0.055   -6.284    0.000    -0.450      -0.236
                                     Roots                                    
 ====================================================================
                Real         Imaginary         Modulus      Frequency
 --------------------------------------------------------------------
 AR.1          1.0668         -1.6609j          1.9740        -0.1591
 AR.2          1.0668         +1.6609j          1.9740         0.1591
 MA.1         -1.1685         +0.0000j          1.1685         0.5000
 MA.2          2.4939         +0.0000j          2.4939         0.0000
 --------------------------------------------------------------------

如果你运行几次上方的代码,你会发现有些实际的参数值并不在估计的参数的置信区间内。这意味着即使我们知道真实的参数值,在尝试进行模型拟合时也可能会出问题。

然而,出于交易使用的目的,大多时候只要求模型有超过随机预测的结果同时能够产生产生净收益的预测能力,保证长远来看是盈利的。

那在进行模型拟合时,如何决定 ARMA 模型的 p q 这两个值呢?

通常情况下,利用AIC准则去判断一组 (p,q) 参数组合的好坏,同时运用 Ljung-Box test 去判断数据是否被较好地拟合。如果对应的p值大于设定的显著性水平,则可以认为残差是独立的,且是白噪声。

ARMA(3,2) 模型为例进行演示

 max_lag = 30
 n = int(5000)
 burn = 2000
 alphas = np.array([0.5, -0.4, 0.25])
 betas = np.array([0.5, -0.3])
 ar = np.r_[1, -alphas]
 ma = np.r_[1, betas]
 arma32 = smt.arma_generate_sample(ar=ar, ma=ma, nsample=n, burnin=burn)
 _ = tsplot(arma32, lags=max_lag)
 best_aic = np.inf 
 best_order = None
 best_mdl = None
 rng = range(5)
 for i in rng:
     for j in rng:
         try:
             tmp_mdl = smt.ARMA(arma32,
                       order=(i, j)).fit(method='mle', trend='nc')
             tmp_aic = tmp_mdl.aic
             if tmp_aic < best_aic:
                 best_aic = tmp_aic
                 best_order = (i, j)
                 best_mdl = tmp_mdl
         except: continue
 print('aic: %6.2f | order: %s'%(best_aic, best_order))

得到的 best_order 为(3,2), best_aic 为14110.88

再进行后续的检验

 sms.diagnostic.acorr_ljungbox(best_mdl.resid, lags=[20], boxpierce=False)

这里的p值大于0.05,说明 ARMA(3,2) 模型能够较好地拟合原始数据。

下面检查一下模型的残差是否是白噪声

 _ = tsplot(best_mdl.resid, lags=max_lag)
 from statsmodels.stats.stattools import jarque_bera