tushare ID:469868
tushare官网:https://tushare.pro
一、获取数据
本文选取了上证指数作为研究对象,利用python从tushare接口调取了其1998年至2021年的月度数据,操作R软件对上证指数进行ARIMA建模。
训练集:1998年-2018年
预测集:2019年-2021年
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
import tushare as ts
token='your token'
pro=ts.pro_api(token)
#上证指数
df = pro.index_monthly(ts_code='000001.SH', start_date='19980101', end_date='20211230')
df.index=pd.to_datetime(df.trade_date)
index_df=df.sort_index()
index_df.to_csv('./上证指数.csv')
二、ARIMA建模
建模过程主要是用R软件进行
library(tseries)
library(forecast)
# 读取数据
da = read.csv('/Users/yangyuting/Documents/sametime-baidu/我的量化策略/pycharm文件/Python金融量化-笔记/tushare任务/上证指数.csv', header = T, na.strings=c("NA"))
head(da)
str(da)
# 所有数据收盘价
data.all <- ts(da$close,frequency=12,start=c(1998,1))
#可以拆掉最后3年来做样本的训练集,再将最后3年做样本的测试集
data1 <-ts(as.vector(da$close[1:251]),frequency=12,start=c(1998,1))
1.平稳性检验
#时序图
plot(data1)
data1的明显存在一个向上的趋势,用1阶差分方法消除趋势
s1<-diff(data1,1)
plot(s1)
从图上看,基本围绕了0在振动,基本平稳,进一步使用adf检验,看一下是否存在单位根(验证平稳性,若存在则不平稳
#单位根检验通过(p<0.05,显著拒绝存在单位根),说明序列平稳
adf.test(s1)
# 白噪声检验(α=0.05
for (i in 1:2){
print(Box.test(s1, lag = 6*i, type = 'Ljung'))
}
# p-value < 0.05 拒绝原假设,说明为非白噪声
所以,一阶差分后的序列是平稳非白噪声序列,可以开始建模了
2.模型定阶
#定阶
#tsdisplay来观察,它包含了时序图,以及acf、pacf两个相关图
tsdisplay(s1)
图形显示acf图,q=3之后拖尾(太后面的不用管),pacf图超出虚线较多,但从整体上看,从16阶之后截断。而上面的线可以大概看到(2,4,6,9)这五个数超出虚线甚多,所以,可以每个都测试一下。
形成(2,1,0)(4,1,0),(6,1,0),(9,1,0) 然后判断一下各自的AIC值,取最小值即可。
acf图可以看出有点像是存在一个12阶的季节性影响因素,然后通过作滞后12阶的图看一下是否消除
tsdisplay(diff(s1,12))
图形可以看出,已经消除了季节性的影响,所以ARIMA季节参数中周期应该为12,由于季节性图的acf图和pacf上看到最后一个超出虚线的阶数均为1,季度参数可以这么设置(1,1,1)[12]
#拟合模型,看一下哪个模型最好,注意,拟合模型使用的data是原始数据,并不是差分之后的数据!
arima(data1,order=c(2,1,3),seasonal=list(order=c(1,1,1),period=12))#AIC=3285.45
arima(data1,order=c(4,1,3),seasonal=list(order=c(1,1,1),period=12))#AIC=3280.19
arima(data1,order=c(6,1,3),seasonal=list(order=c(1,1,1),period=12))#AIC=3285.84
arima(data1,order=c(8,1,3),seasonal=list(order=c(1,1,1),period=12))#AIC=3278.03
从上面的拟合可以看出,选择(8,1,3)(1,1,1)[12]的模型AIC值最小,也可以使用auto.arima函数来自动确定这些参数:
auto.arima(data1)
#ARIMA(0,1,0) AIC=3417.06
auto.arima函数确定的参数的AIC值较大,所以ARIMA(8,1,3)(1,1,1)[12]模型较好。我们来看看预测效果。
fit1<-stats::arima(data1,order=c(8,1,3),seasonal=list(order=c(1,1,1),period=12))
tsdiag(fit1)
记得加上stats::,不然会报错!!!
然后使用tsdiag看一下各自的结果,
ARIMA(8,1,3)[12]图中表明残差标准差基本都在[-1,1]之间,残差的自回归都为0(两虚线内),Ljung-Box检验的p都在0.05之上,结果不错。
#预测
f.p1<-forecast(fit1,h=36,level=c(99.5))
#看一下fit1【即(1,1,0)(1,1,1)[12]】的效果
plot(f.p1,ylim=c(100,700))
lines(f.p1$fitted,col="green")
lines(air,col="red")
从上面的图(红色为全部真实数据,绿色为利用上证指数计算出来的原始数据拟合值,蓝色段为预测值),可以看出,预测效果一般。怎么继续优化的话,我后续学会了再来更新。