在本文中,我想向您展示如何应用S&P500股票市场指数的交易策略。
策略概述
该策略在“滚动”预测的基础上执行:
什么是ARMA(p,q)模型?
在介绍ARMA模型之前,我们先来看看其构成基础AR(p)和MA(q)模型。
AR(Autoregressive Model)模型即自回归模型,其描述了历史值对当前值的影响。举个实际例子,比如CRSP价值加权指数的月收益率就具有统计上显著的滞后期为1的自相关系数,这个事实说明我们是可以用上一期的CRSP月收益率来预测当期的月收益率的。这也是AR模型的主要作用,用历史值来预测未来,默认历史会重演。其具体表现形式可以表示为:
MA(Moving Average Model)模型即移动平均模型,其认为当前值是自回归模型误差项的累和。关于MA模型的理解,我们既可以将其看成是白噪声序列的简单推广,也可以将其理解为参数受到某种约束的无穷阶AR模型,这个具体推导过程详见教程或相关文献。但MA模型有一个特殊的性质就是其总是弱平稳的,主要在于其表现形式是白噪声序列的有限线性组合,从而其前两阶矩不随时间而变化。MA模型可以表示为:
在介绍完这两种基本的模型后,我们再回到初始介绍的ARMA(p,q)模型上来。 ARMA(Autoregressive moving average model)即自回归移动平均模型。既然AR和MA模型能够刻画绝大部分的时间序列的动态过程,为什么要引入ARMA模型呢?ARMA模型的引入主要是为了解决有些需要高阶的AR或MA模型才能充分描述的动态数据结构,起到了一个类似‘降维’的作用,减少了参数估计量,降低了参数估计难度。结合上面的两个表达式,我们很容易就能够想到ARMA(p,q)的模型表现形式了:
我们这里具体地了解一下其各个参数的含义:如果代表资产的t期对数收益率,则代表滞后i 期的收益率,而则表示滞后j 期的扰动项,但扰动项本身是一个均值为0,方差为的白噪声序列。和则分别代表相应变量对应的系数。这些含义也适用于接下来的波动率模型,所以下文不再赘述。
这里澄清一点:对金融中的资产收益率进行建模其实是很少用到ARMA模型的!当然这在前面也提到了,但并不妨碍我们的思路继续进行。
什么是GARCH(1,1)模型?
虽然要多一点真诚,少一些套路,但这里请原谅我要继续按套路出牌了。<邪恶脸>根据前面介绍ARMA的套路,在介绍GARCH之前,我们先来简单了解一下其前身ARCH模型。 ARCH(Autoregressive conditional heteroscedasticity model)即自回归条件异方差模型,其首次出现在Robert-Engle教授于1982年发表在《Econometrica》期刊上的一篇论文中,主要用来解决时间序列的波动性问题。那为什么需要对波动率进行建模呢?概括起来主要有以下几个方面:1.波动率建模提供了一个简单的方法来计算风险管理中一个金融头寸的风险值;2.时间序列的波动率建模能够改进参数估计的有效性和区间预测的精准度;3.市场的波动率本身也可以构建成一个交易工具,用来对冲风险,比如CBOE构建的VIX(波动率指数)就有相应的交易品种在交易所交易。讲到这里,我们来看看ARCH模型的具体表现形式:
根据ARCH模型的表现形式,我们可以知道其一些特点,简单概括一下,因为后面建模会涉及到对性质的利用。ARCH模型分布的尾部相比于正态分布尾部更厚,即其‘扰动’比高斯白噪声序列更容易产生异常值,这与实证研究中资产收益率表现出的异常值多于正态分布一致,而且ARCH模型能够很好地刻画波动率聚集效应。但其也存在着一些缺点,比如说,ARCH模型假定正的扰动和负的扰动对波动率有相同的影响,因为根据其表达式,我们知道波动率依赖于扰动项的平方。但实证研究中,金融资产价格对正的和负的扰动反应是不同的。同时ARCH模型对参数的限制比较强,尤其是对高阶的ARCH模型,参数约束会更加复杂,这导致ARCH模型不能很好地刻画超额峰度,最后ARCH模型给出的波动率预测值会偏高,因为它对收益率序列大的孤立的‘扰动’反应缓慢。
啰嗦了这么多,那到底什么是GARCH模型,其跟我前文介绍的内容又有什么关系嘛?我们知道每一个新的模型的提出都是为了解决之前模型的一些缺点,GARCH也不例外。在ARCH模型中,其假设时间序列的变量的波动幅度(方差)是一个常数,而在实证研究中,学者们早就发现收益率的波动幅度是随时间变化的,并非是固定的值。因此Bollerslev在1986年提出了GARCH(Generalized autoregressive conditional heteroscedasticity model) 模型,即广义自回归条件异方差模型,其在方差的影响因素中增加了方差的滞后项。GARCH模型对ARCH模型的另一大改进是使得高阶ARCH模型退出了历史舞台,因为高阶的ARCH对于波动率建模参数约束太多,并且难以估计,就是上面提到的第二个缺点,这其实又与前面的 ARMA模型相互呼应了。然而GARCH依然没有解决杠杆效应的问题。当然GARCH的衍生模型很好地解决了,不过这是后话了。现在我们先来看一下GARCH(p, q)模型的表现形式:
是不是有一种似曾相识的感觉?是的,没错,GARCH模型可以看作是一个ARMA(p,q)模型的‘变脸’,其将因变量由收益率变为了波动率的平方。至于GARCH的性质大家可以对照上文介绍的ARCH来理解,改进部分我也在前面提到了。这里补充一点,关于波动率模型上面都只是给出了波动率的表达式,其实其还有均值方程以及扰动项方程,完整形式应如下所示:
- 对于每一天,股票指数的对数收益的前k天被用作拟合最佳ARIMA和GARCH模型的窗口。
- 组合模型用于对第二天的收益进行预测。
- 如果预测为负,则在上一个收盘时做空股票,而如果预测为正,则做多。
- 如果预测与前一天的方向相同,则什么都不会改变。
策略实施
第一个任务是在R中安装和导入必要的库:
如果已经安装了库,则可以简单地导入它们:
> library(quantmod)
> library(lattice)
> library(timeSeries)
> library(rugarch)
完成后,将把该策略应用于S&P500。
然后,我们可以创建标准普尔500的“收盘价”的对数收益率差分序列,并去除初始NA值:
根据Akaike信息准则,循环过程将为我们提供“最佳”拟合ARMA模型,然后我们可以将其用于输入GARCH模型:
> final.aic <- Inf
> final.order <- c(0,0,0)
> for (p in 0:5) for (q in 0:5) {
> if ( p == 0 && q == 0) {
> next
> }
>
> arimaFit = tryCatch( arima(spReturnsOffset, order=c(p, 0, q)),
> error=function( err ) FALSE,
> warning=function( err ) FALSE )
>
> if( !is.logical( arimaFit ) ) {
> current.aic <- AIC(arimaFit)
> if (current.aic < final.aic) {
> final.aic <- current.aic
> final.order <- c(p, 0, q)
> final.arima <- arima(spReturnsOffset, order=final.order)
> }
> } else {
> next
> }
> }
如果GARCH模型无法收敛,那么我们只需将日期设置为产生“长期”预测 。
为了准备CSV文件的输出,我创建了一个字符串,其中包含用逗号分隔的数据,并带有第二天的预测方向:
> if(is(fit, "warning")) {
> forecasts[d+1] = paste(index(spReturnsOffset[windowLength]), 1, sep=",")
> print(paste(index(spReturnsOffset[windowLength]), 1, sep=","))
> } else {
> fore = ugarchforecast(fit, n.ahead=1)
> ind = fore@forecast$seriesFor
> forecasts[d+1] = paste(colnames(ind), ifelse(ind[1] < 0, -1, 1), sep=",")
> print(paste(colnames(ind), ifelse(ind[1] < 0, -1, 1), sep=","))
> }
> }
倒数第二步是将CSV文件输出 。
确保在与forecasts.csv
文件相同的目录中运行:
forecasts = open("forecasts.csv", "r").readlines()
至此,我们已将更正的指标文件存储在中forecasts_new.csv
。
策略结果
现在,我们已经生成了指标CSV文件,我们需要将其效果与“买入并持有”进行比较。
我们首先从CSV文件中读取指标并将其存储为spArimaGarch
:
然后,我们将ARIMA + GARCH预测的日期与S&P500的原始收益集相交。
一旦获得ARIMA + GARCH策略的收益,就可以为ARIMA + GARCH模型和“买入并持有”创建资产曲线。最后,我们将它们合并为一个数据结构:
> spArimaGarchCurve = log( cumprod( 1 + spArimaGarchReturns ) )
> spBuyHoldCurve = log( cumprod( 1 + spIntersect[,2] ) )
> spCombinedCurve = merge( spArimaGarchCurve, spBuyHoldCurve, all=F )
最后,我们可以在同一图上绘制两条收益曲线:
> xyplot(
> spCombinedCurve,
> superpose=T,
> col=c("darkred", "darkblue"),
> lwd=2,
> key=list(
> text=list(
> c("ARIMA+GARCH", "Buy & Hold")
> ),
> lines=list(
> lwd=2, col=c("darkred", "darkblue")
> )
> )
> )
资产曲线如下:
如您所见,在65年的时间里,ARIMA + GARCH策略的表现明显优于“买入并持有”。但是,您还可以看到,大部分收益发生在1970年至1980年之间。
因此,在将此类模型应用于历史序列真的合适吗?
另一种选择是开始将模型应用于最新数据。实际上,我们可以考虑一下从2005年1月1日至今的最近十年的表现:
随时关注您喜欢的主题
现在,我们已经完成了ARIMA和GARCH模型的讨论,我想通过考虑长状态空间模型和协整时间序列来继续进行时间序列分析讨论。
时间序列的这些后续领域将向我们介绍一些模型,这些模型可以改善我们的预测,这将大大提高我们的交易获利能力和/或降低风险。