文章目录
金融数据常见类型为:
- 截面数据
- 时间序列数据
- 面板数据
时间数据序列时序图
import pandas as pd
import matplotlib.pyplot as plt
Index = pd.read_table('TRD_Index.txt', sep='\t', index_col='Trddt')
SHindex = Index[Index.Indexcd == 1]
# 提取上证综指的收盘指数数据
Clsindex = SHindex.Clsindex
# 将收盘指数转换成时间序列格式
Clsindex.index = pd.to_datetime(Clsindex.index)
# 最后,绘制时间序列图
Clsindex.plot()
plt.show()
选取特点时期的时间序列数据
将index转换为时间序列,即可根据特定的条件从时间序列数据中提取出子集。
# 截取2014年10月8日到10月31日的数据
SHindex.index = pd.to_datetime(SHindex.index)
SHindexPart = SHindex['2014-10-08':'2014-10-31']
# 截取2015年数据
SHindex2015 = SHindex['2015']
# 选取2015年初以后的数据
SHindexAfter2015 = SHindex['2015':]
# 选取2015年以前的数据
SHindexBefore2015 = SHindex[:'2014-12-31']
# 选取2014年9月到年底的数据
SHindex9End = SHindex['2014-09':'2014']
时间序列描述性统计
Clsindex.hist()
plt.show()
# 求最大值
Clsindex.max()
# 求最小值
Clsindex.min()
# 求均值
Clsindex.mean()
# 求中位数
Clsindex.median()
# 求标准差
Clsindex.std()
# 总结数据分布情况
print(Clsindex.describe())
# count 311.000000
# mean 2490.001161
# std 563.700980
# min 1991.253000
# 25% 2052.140500
# 50% 2224.654000
# 75% 2996.395000
# max 4135.565000
# Name: Clsindex, dtype: float64
时间序列基本性质
自相关性
即,一个时间序列的两个不同时间点的变量是否有关联。
自协方差 - Autocovariance Function
自相关系数 - Autocorrelation Coefficient Function
偏自相关系数 - Partial Autocorrelation Coefficient Function
Python操作
from statsmodels.tsa import stattools
from statsmodels.graphics.tsaplots import *
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('TRD_Index.txt', sep='\t', index_col='Trddt')
sh_index = data[data.Indexcd == 1]
sh_index.index = pd.to_datetime(sh_index.index)
sh_return = sh_index.Retindex
acfs = stattools.acf(sh_return)
pacfs = stattools.pacf(sh_return)
plot_acf(sh_return, use_vlines=True, lags=30)
plot_pacf(sh_return, use_vlines=True, lags=30)
plt.show()
平稳性
只有基于平稳的时间序列的预测才是有效的。
强平稳
即,该序列的任何统计性质都不会随时间改变,理论和实际应用中都很难检验。
弱平稳
满足三个条件即可:
- 序列的均值为常数
- 存在二阶矩
- l 阶自协方差的大小不随着 t 值变动,只与 l 值有关
Python检验时间序列平稳性
# method 1 - 绘时序图
import pandas as pd
import matplotlib.pyplot as plt
sh_close = sh_index.Clsindex
sh_close.plot()
plt.show()
sh_return.plot()
plt.show()
下图⇩前半段平稳,后半段不平稳
下图⇩总体平稳
# method 2 - 绘制ACF/PACF图
from statsmodels.graphics.tsaplots import *
plot_acf(sh_return, use_vlines=True, lags=30)
plot_pacf(sh_return, use_vlines=True, lags=30)
plot_acf(sh_close, use_vlines=True, lags=30)
plt.show()
一般平稳的时间序列,其自相关系数或者偏自相关系数大都快速减小至0附近或者在某一阶段后变为0。
↓↓↓ sh_return较为平稳;sh_close不平稳。
# method 3 - 单位根检验[常见方法有:ADF,DF,PP]
from arch.unitroot import ADF
adf_sh_return = ADF(sh_return)
print(adf_sh_return.summary().as_text())
adf_sh_close = ADF(sh_close)
print(adf_sh_close.summary().as_text())
↓↓↓ 统计量小于1%显著性水平下的临界值,所以拒绝原假设(序列非平稳)——即sh_return序列是平稳的。
↓↓↓ 统计量大于1%、5%、10%显著性水平下的临界值,所以无法拒绝原假设(序列非平稳)——即sh_close序列是非平稳的。
白噪声
即,白噪声序列一定是平稳的时间序列,均值为常数、方差为常数,其间隔大于0的自协方差都恒等于0[平稳性序列的自协方差只与时间间隔相关,而不与时间的起始点相关的要求]。
btw,白噪声只代表序列各期无相关性,不代表各期之间相互独立。
import matplotlib.pyplot as plt
import numpy as np
white_noise = np.random.standard_normal(size=500)
plt.plot(white_noise, c='b')
plt.title('white noise')
plt.show()
Python——白噪声检验__Ljung-Box检验
Ljung-Box检验的原假设:序列为纯随机序列/白噪声序列。
from statsmodels.tsa import stattools
import pandas as pd
data = pd.read_csv('TRD_Index.txt', sep='\t', index_col='Trddt')
sh_index = data[data.Indexcd == 1]
sh_index.index = pd.to_datetime(sh_index.index)
sh_return = sh_index.Retindex
sh_close = sh_index.Clsindex
ljung_Box1 = stattools.q_stat(stattools.acf(sh_return)[1:13], len(sh_return))
print(ljung_Box1[1][-1]) # 0.4936174964502932--接受原假设,是随机序列
ljung_Box2 = stattools.q_stat(stattools.acf(sh_close)[1:13], len(sh_close))
print(ljung_Box2[1][-1]) # 0.0--序列存在自相关性
时间序列预测
移动平均预测
- 简单移动平均
- 加权移动平均
- 指数加权移动平均
ARMA模型预测
模型 | ACF | PACF |
---|---|---|
AR(p) | 拖尾 (几何型或震荡型) | p阶截尾 |
MA(q) | q阶截尾 | 拖尾 (几何型或震荡型) |
ARMA(p,q) | 拖尾 (几何型或震荡型) | 拖尾 (几何型或震荡型) |
import pandas as pd
import matplotlib.pyplot as plt
cpi = pd.read_csv('CPI.csv', index_col='time')
cpi.index = pd.to_datetime(cpi.index)
print(cpi.shape) # (161, 1)
cpi = cpi.sort_index()
cpi.plot(title='CPI 2001-2014')
plt.show()
from arch.unitroot import ADF
# 选取训练集,评价模型准确度
cpi_train = cpi[:-3].dropna()
print(ADF(cpi_train, max_lags=10).summary().as_text())
所以我们可以认为序列平稳。
from statsmodels.tsa import stattools
ljungBox = stattools.q_stat(stattools.acf(cpi_train)[1:12], len(cpi_train))
print(ljungBox[1][-1]) # 0.0005560128948515362<0.05 ---- 拒绝原假设,不是白噪声序列
识别ARMA模型的p和q。
from statsmodels.graphics.tsaplots import *
ax1 = plt.subplot(211)
plot_acf(cpi_train, lags=30, ax=ax1)
ax2 = plt.subplot(212)
plot_pacf(cpi_train, lags=30, ax=ax2)
plt.show()
有图像可知,ACF&PACF均为拖尾。
判断p,q取值,运用AIC准则选出AIC值最小的模型。
from statsmodels.tsa import arima_model
model_1 = arima_model.ARIMA(cpi_train, order=(1, 0, 1)).fit()
print(model_1.summary())
↓↓↓
(p,q) | (1,1) | (1,2) | (2,1) | (2,2) | (3,1) | (3,2) | (3,3) |
---|---|---|---|---|---|---|---|
AIC | 308.678 | 310.521 | 307.933 | 309.271 | 310.972 | 308.496 | 310.484 |
所以选择ARMA(2,1)模型。
接下来,进行模型诊断。
- 系数显著性检验
- 残差序列是否为白噪声的检验
# Step 1
print(model_3.conf_int())
# 0 1
# const 100.216756 100.286655
# ar.L1.CPI 1.101874 1.404685
# ar.L2.CPI -0.458490 -0.146583
# ma.L1.CPI -1.039059 -0.960941
所有系数的置信区间都不包含0,因此5%(conf_int()函数默认α=0.05)置信水平下,所有系数都是显著的。
# Step 2
import math
std_resid = model_3.resid / math.sqrt(model_3.sigma2)
plt.plot(std_resid)
plot_acf(std_resid, lags=20)
plt.show()
↑↑↑无法确定残差是不是白噪声序列。
因此,作LB检验。
ljung_Box = stattools.q_stat(stattools.acf(std_resid)[1:20], len(std_resid))
print(ljung_Box)
查看LB的p值可知,12阶后存在p<5%。因此模型的残差不是一个白噪声序列。
再查看残差自相关系数图。
plot_acf(std_resid, lags=40)
plt.show()
↑↑↑可以发现12、24、36阶系数显著,由此可判断需要季节性调整——ARIMA模型。
print(model_3.forecast(3)[0], '\n', cpi[-3:])
# [100.27850933 100.21018 100.19155332]
# CPI
# time
# 2014-03-01 99.5
# 2014-04-01 99.7
# 2014-05-01 100.1
另外,如果利用模型对未来的序列值进行预测,可以用forecast函数,但此案例中根据训练集建模的预测结果并不是很好。
平稳时间序列建模
import pandas as pd
from arch.unitroot import ADF
from statsmodels.tsa import stattools
da_tang = pd.read_csv('Datang.csv', index_col='time')
da_tang.index = pd.to_datetime(da_tang.index)
returns = da_tang.datang['2014-01-01':'2016-01-01']
# 检验序列是否平稳
print(ADF(returns).summary())
# 检验序列是否为白噪声
print(stattools.q_stat(stattools.acf(returns)[1:12], len(returns))[1])
↓↓↓↓↓平稳&不是白噪声
# 确认pq值
print(stattools.arma_order_select_ic(returns, max_ma=4))
# ARMA(1,0)建模
from statsmodels.tsa import arima_model
model = arima_model.ARIMA(returns, order=(1, 0, 0)).fit()
print(model.summary())
print(model.conf_int())
# 0 1
# const -0.331197 0.614627
# ar.L1.datang 0.053630 0.236092
# 残差诊断
import math
from statsmodels.graphics.tsaplots import *
import matplotlib.pyplot as plt
std_resid = model.resid / math.sqrt(model.sigma2)
plt.plot(std_resid)
plot_acf(std_resid, lags=20)
plt.show()
l_b = stattools.q_stat(stattools.acf(std_resid)[1:12], len(std_resid))
print(l_b[1])
# [0.99403632 0.9995103 0.77556433 0.53779996 0.60674717 0.69723692
# 0.70864821 0.21276688 0.22902475 0.10008502 0.1410863 ]
残差项之间不存在显著的自相关性,对于LB检验也有较高的p值,所以基本上模型符合要求。
↓↓↓↓↓↓
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。