时序分析 17 状态空间模型 上 (隐含马尔可夫模型)

时序分析 17 状态空间模型 上

隐含马尔可夫模型

    Dynamic State Space Model(DSSM), 状态空间模型在数据分析、时序分析,机器学习领域有非常重要的应用。它假设一个系统的状态是动态变化的,且当前状态依赖于过去的状态,这种假设是比较符合客观上我们所能观测到的现象。

​     本文和下一篇文章,我们将讨论动态空间模型中两种最重要的模型:隐含马尔可夫模型和卡拉曼滤波。

状态空间模型

​     定义系统当前的状态 x t = f ( x t − 1 , x t − 2 , …   ) x_t=f(x_{t-1},x_{t-2},\dots) xt=f(xt1,xt2,) ,只是一个离散序列,时间 t t t 的测量值以整数递增。以概率形式表示: P ( x t ∣ x t − 1 , x t − 2 , …   ) P(x_t|x_{t-1},x_{t-2},\dots) P(xtxt1,xt2,)

马尔可夫模型

​     马尔可夫模型(阶数为p)限制了依赖过去状态的个数, P ( x t ∣ x t − 1 , x t − 2 , … , x t − p ) P(x_t|x_{t-1},x_{t-2},\dots,x_{t-p}) P(xtxt1,xt2,,xtp)

​ 实践中比较常用的是一阶马尔可夫模型, P ( x t ∣ x t − 1 ) P(x_t|x_{t-1}) P(xtxt1)
时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第1张图片

隐含马尔可夫模型

    在隐含马尔可夫模型中,隐含的状态不能直接被观测到。我们可以观测到一个由隐含状态所影响的随机变量 ,可以提供我们关于隐含状态的间接信息。
时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第2张图片

​ 更详细的模型表示:
时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第3张图片
    关于隐含马尔可夫模型可在本人的机器学习讲义中有较为详细的介绍,这里只是简单回顾其理论框架。

实践

    我们在这个实践例子中,将采用HMM(隐含马尔可夫模型)来估算市场阶段,例如牛市或者熊市。背后的逻辑显而易见,市场的价格是可观测的,但是市场的价格肯定会收到背后的驱动因素如牛市还是熊市的影响,但市场处于哪一种状态是不可观测的,这就是所提到的隐含状态。
    我们可以用HMM来对这个问题进行建模,估测市场处于哪一个状态。在这个例子中,我们定义隐含状态可能为高波动率,中波动率和低波动率。

导入工具包
import pandas as pd
from pandas_datareader import data as pdr
import sklearn.mixture as mix

import numpy as np
import scipy.stats as scs

import matplotlib as mpl
from matplotlib import cm
import matplotlib.pyplot as plt
from matplotlib.dates import YearLocator, MonthLocator
%matplotlib inline

import seaborn as sns
import missingno as msno
from tqdm import tqdm
读取SPY(标普500 ETF)数据
import yfinance as yf
yf.pdr_override()
# get fed data

start = pd.to_datetime('2005-01-01')
end = pd.to_datetime('2015-01-01')

mkt = 'SPY'
MKT = pdr.get_data_yahoo([mkt],start=start,end=end)['Adj Close']
读取TED基差,10年国债和2年国债基差,10年和3个月债券基差

注:TED基差是Libor - T bill rate

# get fed data

f1 = 'TEDRATE' # ted spread
f2 = 'T10Y2Y' # constant maturity ten yer - 2 year
f3 = 'T10Y3M' # constant maturity 10yr - 3m

MKT_spy =MKT.to_frame()
MKT_spy.columns=[mkt]
#MKT_spy.assign(sret=lambda x: np.log(x[mkt]/x[mkt].shift(1)),inplace=True).dropna()
MKT_spy['sret']=np.log(MKT_spy[mkt]/MKT_spy[mkt].shift(1))
MKT_spy.dropna(inplace=True)
data = (pdr.get_data_fred([f1, f2, f3], start, end)
        .join(MKT_spy, how='inner')
        .dropna()
       )

data.head()

时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第4张图片
采用高斯发射概率假设,以HMM对该问题进行建模。

col = 'sret'
select = data.iloc[:].dropna()

ft_cols = [f1, f2, f3, 'sret']
X = select[ft_cols].values
from hmmlearn import hmm
np.random.seed(42)
# model = mix.GaussianMixture(n_components=3, 
#                            covariance_type="full", 
#                            n_init=100, 
#                            random_state=7).fit(X)
model = hmm.GaussianHMM(n_components=3,
                       covariance_type="full",
                        n_iter=100,
                       random_state=7).fit(X)
# Predict the optimal sequence of internal hidden state
hidden_states = model.predict(X)

print("Means and vars of each hidden state")
for i in range(model.n_components):
    print("{0}th hidden state".format(i))
    print("mean = ", model.means_[i])
    print("var = ", np.diag(model.covars_[i]))
    print()

Means and vars of each hidden state
0th hidden state
mean = [4.56845472e-01 1.60832282e-01 3.45699793e-01 3.99911911e-04]
var = [1.30936319e-02 8.43026360e-02 4.56688228e-01 6.32908070e-05]

1th hidden state
mean = [2.30271809e-01 2.15384633e+00 2.56913624e+00 6.64919229e-04]
var = [5.23387251e-03 2.10754227e-01 4.13676824e-01 9.27640037e-05]

2th hidden state
mean = [ 1.22366300e+00 1.62089798e+00 2.11779208e+00 -1.00140436e-03]
var = [4.93656239e-01 3.21316327e-01 7.71565826e-01 4.64366565e-04]

从上面所显示的波动率的值可知,隐含状态2代表着高波动期间、中和低波动期间分别对应着隐含状态1和0.

sns.set(font_scale=1.25)
style_kwds = {'xtick.major.size': 3, 'ytick.major.size': 3,
              'font.family':u'courier prime code', 'legend.frameon': True}
sns.set_style('white', style_kwds)

fig, axs = plt.subplots(model.n_components, sharex=True, sharey=True, figsize=(12,9))
colors = cm.rainbow(np.linspace(0, 1, model.n_components))
for i, (ax, color) in enumerate(zip(axs, colors)):
    # Use fancy indexing to plot data in each state.
    mask = hidden_states == i
    ax.plot_date(select.index.values[mask],
                 select[col].values[mask],
                 ".-", c=color)
    ax.set_title("{0}th hidden state".format(i), fontsize=16, fontweight='demi')

    # Format the ticks.
    ax.xaxis.set_major_locator(YearLocator())
    ax.xaxis.set_minor_locator(MonthLocator())
    sns.despine(offset=10)

plt.tight_layout()

时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第5张图片

sns.set(font_scale=1.5)
states = (pd.DataFrame(hidden_states, columns=['states'], index=select.index)
          .join(select, how='inner')
          .assign(mkt_cret=select.sret.cumsum())
          .reset_index(drop=False)
          .rename(columns={'index':'Date'}))
print(states.head())

sns.set_style('white', style_kwds)
order = [0, 1, 2]
fg = sns.FacetGrid(data=states, hue='states', hue_order=order,
                   aspect=1.31, size=12)
fg.map(plt.scatter, 'Date', mkt, alpha=0.8).add_legend()
sns.despine(offset=10)
fg.fig.suptitle('Historical SPY Regimes', fontsize=24, fontweight='demi')

时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第6张图片
时序分析 17 状态空间模型 上 (隐含马尔可夫模型)_第7张图片
总结
    本文总结了状态空间模型的基本理论框架且简要回顾了隐含马尔可夫模型的主要逻辑,最后以HMM结合真实市场数据对市场的波动率分段进行建模,从结果上看还是有一定作用的。

你可能感兴趣的:(时序分析,python,机器学习,隐含马尔可夫模型,金融市场分段,状态空间模型)