
随着人们生活水平的提高,人们的投资方式也在发生着巨大的变化,越来越多的人开始关注并参与到股票市场投资中去。股票具有高收益的同时也具有高风险性,股票市场受众多因素的影响,价格令人无法捉摸,股票价格预测的研究具有巨大的价值,因此对于股票价格的预测从股票市场诞生之日起,就成了股民与学者们不懈探索的难题。
本文以此为背景,建立ARIMA模型,用于研究股票的趋势,并且得出股票预测的估计值,拟合度较高,适应性良好。
本文的数据来源于某股市的交易数据,其中date 、 open 、high 、low 、close 、volumn各字段的含义分别为股票日期、开盘价、最高价、最低价、收盘价、股票价格。
import csvimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom datetime import datetimeimport scipy as statsimport statsmodels.api as smfrom scipy import statsfrom statsmodels.tsa.arima_model import ARIMAdf=pd.read_csv('stock_ren.csv',index_col='date') df.head()
df.index = pd.to_datetime(df.index) df.index
plt.rcParams['font.sans-serif'] = ['simhei'] plt.rcParams['axes.unicode_minus'] = False ts.plot() plt.title("Renshou Insurance") plt.xticks(rotation=45) plt.xlabel('日期') plt.ylabel('开盘价')
做出开盘价的趋势图,可以看出该股票的开盘价格具有波动性。
# 绘制自相关图from statsmodels.graphics.tsaplots import plot_acf #导入自相关函数plot_acf(ts,use_vlines=True,lags=30) #"lags"自相关函数的滞后取值范围,此处之后30阶,绘制出原始数据"ts"的自相关图plt.show() #展示原始数据"ts"的自相关图
由自相关图认为该样本序列具有一定趋势性且初步判断为非平稳时间序列。
plot_acf(ts,use_vlines=True,lags=30) plt.show()
print(u'原始序列的ADF检验结果为:', ADF(df[u'open']))
由检验的结果显示,Test Statistic的值是-1.5261142019098892,大于Critical Value给出的1%,5%,10%显著性水平下的临界值,同时p-value=-1.5261142019098892>0.05,因此无法拒绝原假设,说明该股票的开盘价序列是非平稳的。
为消除随机趋势对于股票数据建模的影响 ,在此我们决定采用差分来消除随机趋势。
D_ts = ts.diff().dropna() D_ts.columns = [u'open差分']
D_ts.plot() plt.title("Renshou Insurance Open") plt.show()
由差分后的时序图,可以看出股票开盘价的随机趋势趋于平稳。
from statsmodels.graphics.tsaplots import plot_acf #导入自相关函数
# 绘制差分后自相关图与偏自相关图plot_acf(D_ts,use_vlines=True,lags=30) #"lags"自相关函数的滞后取值范围,此处之后30阶,绘制出原始数据"ts"的自相关图plt.show() #展示差分后数据"D_ts"的自相关图
由一阶差分自相关图,可以看出,该序列是趋于平稳的。
from statsmodels.graphics.tsaplots import plot_pacf #导入偏自相关函数plot_pacf(D_ts,use_vlines=True,lags=30) #"lags"偏自相关函数的滞后取值范围,此处之后30阶,绘制出原始数据"ts"的自相关图plt.show() #展示差分后数据"D_ts"的偏自相关图
由一阶差分偏自相关图,同样可以看出该序列趋于平稳。
print(u'原始序列的ADF检验结果为:', ADF(D_ts))
由检验结果显示得出,Test Statistic的值是-18.212736826608307小于Critical Value给出的1%,5%,10%显著性水平下的临界值,同时p-value=2.3904790005983094e-30<0.05,因此拒绝原假设,说明该开盘价序列经一阶差分后是平稳的。
# 对差分后数据进行白噪声检验from statsmodels.tsa import stattools #对差分后达到平稳的数据进行白噪声检验LjungBox=stattools.q_stat(stattools.acf(D_ts)[1:12],len(D_ts)) #展示白噪声检验结果,返回统计量和p值LjungBox[1][-1]
由运行出来的结果,我们可以得知,p-value=0.5486639075658513>0.05,因此无法拒绝原假设,也就是说此时差分后开盘价序列是平稳白噪声序列。
经一阶差分后,数据序列变为平稳白噪声序列,因此可初步判断模型为AR(1)模型。
from statsmodels.tsa.arima_model import ARIMA model=ARIMA(ts,order=(1,1,0))result=model.fit(disp=-1)result.summary()
上述模型诊断结果中,通过z检验,我们发现P值均大于0.05,即无法拒绝原假设,说明模型诊断不通过,且系数的置信区间包含零,因此不能说在5%的置信水平下,所有系数都是显著的,从而推翻AR(1)模型。
sm.tsa.arma_order_select_ic(D_ts,max_ar=6,max_ma=4,ic='aic')['aic_min_order'] from statsmodels.tsa.arima_model import ARIMAmodel=ARIMA(ts,order=(2,1,2))result=model.fit(disp=-1)result.summary()
说明新修正的的模型为ARIMA(2,1,2),紧接着进行相应的诊断上述模型诊断结果中,通过z检验,我们发现所有P值中除截距项之外均小于0.05(说明没有常数项),即拒绝原假设,说明模型诊断通过。为使模型更加精确,我们再进一步用confint()函数计算模型中的系数区间,上述运行结果中,可以看出,除截距项外,所有系数的置信区间都不包含零,因此我们可以说在5%的置信水平下,所有的系数都是显著的,即模型通过检验。
fig, ax = plt.subplots(figsize=(12, 8))ax = ts.ix['2015-09':].plot(ax=ax)fig = result.plot_predict(5,285)plt.show()
由图可以看出数据拟合效果还可以,真实值与预测值相差不大。因此该模型对数据的预测有较好的效果。