01
引言
时间序列建模广泛用于序列相关的数据,例如对股票收益率数据进行建模和预测,分析下一季度的业务绩效,天气预报,信号处理等。时间序列建模的最简单方法是线性自回归模型,其中自回归模型指定输出变量线性地取决于其自身的先前值和随机项,即假定时间序列的均值和方差在所考虑的整个时间段内保持不变,但现实数据往往很难满足这样的条件。由于某些结构上的变化,时间序列的波动性从一个时期到下一个时期可能发生剧烈变化。例如,在政策或宏观经济冲击后,股票价格可以从趋势急剧改变为波动。区制转换模型(Regime shift models,简称RSM)通过将时间序列分为不同的“状态”,来解决基本时间序列建模中的不足,这些模型在时间序列文献中也被广泛称为状态空间模型。本文简单介绍区制转移模型的基本原理,以及基于Python使用RSM模型对股票价格进行建模分析。关于时间序列建模分析可参考公众号系列推文:【Python量化基础】时间序列的自相关性与平稳性;【手把手教你】使用Python玩转金融时间序列模型;Python玩转金融时间序列之ARCH与GARCH模型。
02
RSM模型概述
区制转移模型也称为状态空间模型或动态线性模型,其基本思路是,时间序列存在于两个或多个状态,每个状态都有自己的概率分布,并且一个状态到另一个状态的转换由另一个过程或变量控制。区制转移模型有三种类型:阈值模型(Threshold models)、预测模型(Predictive models)和马尔科夫转换自回归模型(Markov switching autoregressive models)。
阈值模型观察到的变量超过阈值会触发状态转换。例如,价格跌破200天移动均线将触发“看跌状态”或下降趋势。预测模型,可以使用机器学习算法之类的预测方法,将GDP,失业,长期趋势,债券收益率,贸易平衡等宏观经济变量作为输入,并预测下一时期的风险。当模型预测高风险数字时,市场处于高风险状态。当模型预测低风险数字时,市场处于趋势状态。马尔科夫转换自回归模型(MSAM),假定状态为“隐藏状态”,并假定潜在状态的的转换遵循同质一阶马尔可夫链,而下一个状态的概率仅取决于当前状态。可以通过最大似然法来估计从一个状态到下一个状态的转移概率,通过使似然函数最大化来估计参数值。
03
MSAM建模分析实例
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
#%是jupyter notebook的魔法命令
%matplotlib inline
#正常显示画图时出现的中文和负号
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
#获取上证综指数据
import tushare as ts
df=ts.get_k_data('sh',start='2000-01-01',end='2020-06-16')
df.index=pd.to_datetime(df.date)
df.head()
由于价格数据一般是非平稳的,而收益率数据是平稳的,因此下面是对收益率而不是价格数据进行建模。此外,日收益率包含的噪声较大,将其转换为周收益率在进行建模。
#上证综指周收益率
df_ret=df.close.resample('W').last().pct_change().dropna()
df_ret.plot(title='上证综指周收益率',figsize=(15,4))
plt.show()
#平稳性检验
#使用arch包中的单位根检验unitroot导入ADF
from arch.unitroot import ADF
ADF(df_ret)
Test Statistic | -4.780 |
P-value | 0.000 |
Lags | 20 |
Trend: Constant
Critical Values: -3.44 (1%), -2.86 (5%), -2.57 (10%)
Null Hypothesis: The process contains a unit root.
Alternative Hypothesis: The process is weakly stationary.
ADFuller检验p值接近于0,可见收益率序列是平稳的。
从上述周收益率数据的时间序列图可以看出,其波动存在一定的集聚性,2007-2008和2015-2016两个时期的波动性特别大,其他时间相对较小。下面基于MSAM模型,假设上证综指的波动率有三种状态:低波动、中波动和高波动(k_regimes=3),并且没有均值效应(trend='nc')。switching_variance默认是False,即时间序列的波动性(标准差)保持不变,这里考虑存在三种状态,因此设置为True。
#模型拟合
mod = sm.tsa.MarkovRegression(df_ret.dropna(),
k_regimes=3, trend='nc', switching_variance=True)
res = mod.fit()
res.summary()
下面对上证综指波动性状态的平滑概率进行可视化。
fig, axes = plt.subplots(3, figsize=(12,8))
ax = axes[0]
ax.plot(res.smoothed_marginal_probabilities[0])
ax.set(title='上证综指低波动平滑概率图')
ax = axes[1]
ax.plot(res.smoothed_marginal_probabilities[1])
ax.set(title='上证综指中波动平滑概率图')
ax = axes[2]
ax.plot(res.smoothed_marginal_probabilities[2])
ax.set(title='上证综指高波动平滑概率图')
fig.tight_layout()
从平滑概率图上可以看出,上证综指在2007-2019、2015-2016的波动性最高,其余期间是小幅波动,这两个期间的高波动性对应了股指的大牛市(大熊市),注意暴涨过后往往是暴跌。
为了分析更多的指数或个股,下面将上述分析过程使用函数表示:
def plot_rsm(code,title,start='2010-01-01',end='2020-06-17'):
df=ts.get_k_data(code,start=start,end=end)
df.index=pd.to_datetime(df.date)
df_ret=df.close.resample('w').last().pct_change().dropna()
#模型拟合
mod = sm.tsa.MarkovRegression(df_ret.dropna(), k_regimes=3, trend='nc', switching_variance=True)
res = mod.fit()
fig, axes = plt.subplots(3, figsize=(12,8))
ax = axes[0]
ax.plot(res.smoothed_marginal_probabilities[0])
ax.set(title=title+'低波动平滑概率图')
ax = axes[1]
ax.plot(res.smoothed_marginal_probabilities[1])
ax.set(title=title+'中波动平滑概率图')
ax = axes[2]
ax.plot(res.smoothed_marginal_probabilities[2])
ax.set(title=title+'高波动平滑概率图')
fig.tight_layout()
先来看看创业板的情况。创业板的高波动期间相对较多,除了2015那波大牛市(及接下来的暴跌),2019年一季度和2020年的一季度波动性也较大,实际上2020年一季度创业板屡次次新股。
plot_rsm('cyb','创业板')
个股的波动性往往会比指数更有集聚性,省广集团对应的高波动性期间较大,其中2020年3月以来出现了连续波动峰值,近期有所下降。该股凭借今日头条、大数据中心、RCS富媒体等热点概念,被资金持续炒作。
plot_rsm('002400','省广集团')
04
结语
本文只是简单介绍了使用Python基于马尔科夫区制转换模型对指数(股票)进行时间序列建模,感兴趣的读者可以进一步利用模型对样本数据进行训练,然后做预测,构建基于波动性的交易策略。任何模型都有其局限性,区制转换模型也不例外,不同数据期间的样本训练得到的参数可能存在较大差异,但关于状态转换(牛市、熊市、震荡市)的分析思路和框架是考察股票市场规律的一个较好视角,尤其是A股,能长期持有的个股凤毛麟角,选择在高(中)波动性期间再介入可提高资金的使用效率。
参考资料:
statsmodels官方文档和安装包原生代码
https://www.statsmodels.org/stable/index.html
关于Python金融量化
专注于分享Python在金融量化领域的应用。加入知识星球,可以免费获取量化投资视频资料、量化金融相关PDF资料、公众号文章Python完整源码、量化投资前沿分析框架,与博主直接交流、结识圈内朋友等。