HMM模型

隐马尔科夫模型(HMM)择时应用的量化策略。 仅为研究学习使用, 不作为任何投资策略建议。

文章内容从各处整理汇总而成, 感谢各位大神分享。  具体策略代码均调试通过。

一、从大奖章讲起

Renaissance & Medallion(文艺复兴科技和大奖章)量化圈都非常熟悉了。Simons一群物理学家和数学家碰撞在一起,1989年到2008年的yearly return达到35.6%。文艺复兴大概一百多个员工,AUM:50亿美金,在全球金融危机的08年,大部分对冲基金都亏损,而大奖章的return高达80%。

神秘的文艺复兴科技和神秘的大奖章基金,到底一群数学家和物理学家聚在一起搞出了什么赚钱利器?外界猜测众说纷纭。而隐马尔科夫模型也由于一些原因被推举出来。

成立初期的创始人中,有一位科学家发明了广泛应用在语音识别等领域的鲍姆-威尔士算法,用来确定不可确知的变量可能出现的概率。今天要介绍的HMM模型,也是在语音识别中运用非常成功的模型,最早是由鲍姆等人提出的。

之前拜读人大的一位教授14年写的一本书,解密复兴科技:基于隐蔽马尔科夫模型的时序分析方法(亚马逊链接),书中介绍了为什么觉得HMM是Renaissance使用的模型,并且含有详细的公式推导和运算,以及附上了一些些实证结果(个人认为还有很多有待补充和粗糙的地方)。感兴趣推荐研读。

二、认识模型

HMM模型,又叫隐马尔科夫模型。要正确的理解和搞懂模型,教材里有很多经典的例子。我从自己理解后的角度尽量浅显的给大家做一个解释,方便大家快速理清概念投入应用。

(摘自某次做汇报的PPT)

我们能观测到的序列

Y1,...,YnY1,...,Yn

称为可观测序列,如股价,成交量,资金净额等等。

而每一个可观测值的产生对应着市场状态序列

Z1,...,ZnZ1,...,Zn

,每个状态通过不同的分布函数来产生观测值。

通过HMM模型,可以用简单的输入,来得出对目前市场状态的判断,从而帮助我们进行择时选择。因为市场状态不是显性可观测的,属于隐藏状态,我们通过对可观测变量的处理来进行推测。

这里对HMM模型进行了扩展得到HMS-GMD模型,因为收益率序列尖峰厚尾的特性导致的非正态分布,引入了混合高斯分布作为状态到观测值之间产生关系的分布函数。

将HMM模型看作一个黑箱子,这个黑箱子可以利用极其方便、简洁的数据,处理后得出:

  1. 每个时刻对应的状态序列;
  2. 混合分布的均值和方差矩阵;
  3. 混合分布的权重矩阵;
  4. 状态间转移概率矩阵。

而黑箱子需要事先给定两个参数:状态数目、混合高斯分布的成分数目。

当然,输入这里是拿单一的价格序列举例。输入也可以是并行的数据矩阵,比如从价格、成交量、资金净额等多个角度来看。

总结一下,使用模型需要在初期设定:

  1. 隐藏状态数目
  2. 输入的观测变量
  3. 混合高斯分布成分数目

三、A股市场实证

下面拿A股市场来做检验。

模型的设定如下:

  1. 隐藏状态数目:8
  2. 输入变量:当日对数收益率,五日对数收益率,当日对数高低价差(其他备选因素成交量、成交额等大家可以自行尝试)
  3. 混合高斯分布成分数目:1(为了简便,假定对数收益率服从单一高斯分布)

HMM模型的算法使用hmmlearn模块。

数据与观测序列准备

from hmmlearn.hmm import GMMHMM,GaussianHMM
import datetime
import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import cm
from matplotlib import pyplot
startdate = '2013-01-01'
enddate = '2017-12-31'
#data = get_price('000300.XSHG',start_date=startdate, end_date=enddate,frequency='1d')
#print(data[0:6])
df = get_price(['000300.XSHG'], start_date=startdate, end_date=enddate, frequency='daily', fields=['open','close','volume','high','low','money'])
open=df['open']['000300.XSHG'][5:]
close = df['close']['000300.XSHG'][5:]
high = df['high']['000300.XSHG'][5:]
low = df['low']['000300.XSHG'][5:]
volume = df['volume']['000300.XSHG'][5:]
money = df['money']['000300.XSHG'][5:]
datelist = pd.to_datetime(close.index[:])
#logreturn = (np.log(np.array(close[1:]))-np.log(np.array(close[:-1])))
#logreturn5 = np.log(np.array(close[5:]))-np.log(np.array(close[:-5]))
logreturn = np.append(np.array([0]),np.log(np.array(close[1:]))-np.log(np.array(close[:-1])))
logreturn5 = np.append(np.array([0,0,0,0,0]), np.log(np.array(close[5:]))-np.log(np.array(close[:-5])))
diffreturn = (np.log(np.array(high))-np.log(np.array(low)))
closeidx = close[:]
X = np.column_stack([open,close,high,low,volume])
#X = np.column_stack([diffreturn,logreturn,logreturn5])
print('open:'+str(len(open))+',close:'+str(len(close))+', high:'+str(len(high))+', low:'+str(len(low))+',volume:'+str(len(volume)) )
print('X: '+str(len(X))+',    datelist: '+str(len(datelist))+', closeidx: '+str(len(closeidx)) )
print('diffreturn: '+str(len(diffreturn))+',    logreturn: '+str(len(logreturn))+', logreturn5: '+str(len(logreturn5)) )

输出:

生成隐含状态序列

hmm = GaussianHMM(n_components = 8, covariance_type='diag',n_iter = 10000).fit(X)
latent_states_sequence = hmm.predict(X)
#print(hmm.startprob_)
#print(hmm.transmat_)
#print(hmm.mean_)
#print(hmm.covars_)
#latent_states_sequence=hmm.decode
print(len(latent_states_sequence))
print(latent_states_sequence)
print(hmm.score(X))

输出:

sns.set_style('white')
plt.figure(figsize = (15, 8))
for i in range(hmm.n_components):state = (latent_states_sequence == i)print(i,len(state),len(datelist[state]),len(closeidx[state]))plt.plot(datelist[state],closeidx[state],'.',label = 'latent state %d'%i,lw = 1)plt.legend()plt.grid(1)

输出:

以上。我们看到了八个状态的HMM模型输出的市场状态序列。需要注意的是:HMM模型只是能分离出不同的状态,具体对每个状态赋予现实的市场意义,是需要人为来辨别和观察的。

下面我们来用简单的timming策略来识别8种latent_state所带来的效果。

data = pd.DataFrame({'datelist':datelist,'logreturn':logreturn,'state':latent_states_sequence}).set_index('datelist')
plt.figure(figsize=(15,8))
for i in range(hmm.n_components):state = (latent_states_sequence == i)idx = np.append(0,state[:-1])data['state %d_return'%i] = data.logreturn.multiply(idx,axis = 0) plt.plot(np.exp(data['state %d_return' %i].cumsum()),label = 'latent_state %d'%i)plt.legend()plt.grid(1)

输出:

上图可以看出:

  1. 状态0——蓝色——牛市上涨
  2. 状态1——绿色——牛市下跌
  3. 状态2——红色——牛市下跌
  4. 状态3——紫色——小幅的上涨
  5. 状态4——黄色——震荡下跌
  6. 状态5——浅蓝色——震荡下跌

以上的意义归结是存在一定主观性的。因为HMM模型对输入的多维度观测变量进行处理后,只负责分出几个类别,而并不会定义出每种类别的实际含义。所以我们从图形中做出上述的判断。

四、择时策略

我们根据模拟出来的隐藏状态,来进行择时。

1. 理论版:股指期货可卖空。

策略是这样设计的:

  1. 当天处在状态0,3时,买入指数基金;
  2. 当天处在状态1,2,4,5时,卖空股指期货;

我们来看一下收益效果:

buy = (latent_states_sequence == 1) + (latent_states_sequence == 2)
buy = np.append(0,buy[:-1])
sell = (latent_states_sequence == 0) + (latent_states_sequence == 3) \+ (latent_states_sequence == 4) + (latent_states_sequence == 5)
sell = np.append(0,sell[:-1])
data['backtest_return'] = data.logreturn.multiply(buy,axis = 0) \- data.logreturn.multiply(sell,axis = 0)plt.figure(figsize = (15,8))
plt.plot_date(datelist,np.exp(data['backtest_return'].cumsum()),'-',label='backtest result')
plt.legend()
plt.grid(1)

输出:

2. A股版

鉴于卖空指数对散户来说没什么可操作性,我们单看能做多的A股市场。选择嘉实沪深300基金来复制沪深300指数。

策略是这样设计的:

  1. 当天处在状态0,3时,买入指数基金;
  2. 当天处在状态1,2,4,5时,空仓;

鉴于研究模块自己搭伪回测算出来的收益曲线很难考虑到滑点、交易规则限制等各方面的要求,所以如下的策略回测只贴上最后的图。代码具体见策略。

采取的方式是把研究模块得出的状态序列导出,导入到回测模块使用。

回测结果截图贴在这。回撤和收益都看起来很漂亮。虽然我也没太懂为什么跟可卖空的结果差不多= =,可能是单纯算收益率的伪回测不太准吧。第二是状态1(绿色)有涨有跌,卖空它也有亏钱的时候。

五、最后的结论

搞量化的小伙伴们每每总是以为发现了『天上掉钱』的秘籍法宝,但仔细想想每一个模型都不是那么简单的。而且相信一部分人已经反映过来了,这是个In-Sample的测试,模型是根据全部时间段的数据得出状态序列的。也就是,天然的,我们就提前知道了什么时候涨跌。简单说,有未来函数。

但是,这不能否认模型优秀的模式识别能力。接下来要做的,是真正的分开In-Sample和Out-Sample来做回测。用一段时间训练得到的模型参数来分析之后一段时间的市场状态。

隐马尔科夫模型(HMM)择时应用的量化策略相关推荐

  1. 隐马尔科夫模型HMM自学 (3)

    Viterbi Algorithm 本来想明天再把后面的部分写好,可是睡觉今天是节日呢?一时情不自禁就有打开电脑.......... 找到可能性最大的隐含状态序列 崔晓源 翻译 多数情况下,我们都希望 ...

  2. 隐马尔科夫模型HMM自学 (2)

    HMM 定义 崔晓源 翻译 HMM是一个三元组 (,A,B).  the vector of the initial state probabilities;  the state transitio ...

  3. 隐马尔科夫模型HMM自学(1)

    介绍 崔晓源 翻译 我们通常都习惯寻找一个事物在一段时间里的变化规律.在很多领域我们都希望找到这个规律,比如计算机中的指令顺序,句子中的词顺序和语音中的词顺序等等.一个最适用的例子就是天气的预测. 首 ...

  4. 【NLP】用于语音识别、分词的隐马尔科夫模型HMM

    大家好,今天介绍自然语言处理中经典的隐马尔科夫模型(HMM).HMM早期在语音识别.分词等序列标注问题中有着广泛的应用. 了解HMM的基础原理以及应用,对于了解NLP处理问题的基本思想和技术发展脉络有 ...

  5. python地图匹配_基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法

    1. 摘要 本篇博客简单介绍下用隐马尔科夫模型(Hidden Markov Model, HMM)来解决地图匹配(Map-Matching)问题.转载请注明网址. 2. Map-Matching(MM ...

  6. 隐马尔科夫模型 HMM 与 语音识别 speech recognition (1):名词解释

    0.引言 想在 CSDN 上看一下隐马尔科夫模型,简称HMM(Hidden Markov Model)的例子,找了几篇博文,却发现大部分都是转载的,转载的还没有出处,文中的表述与逻辑也看的人晕头转向, ...

  7. 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数

    在本篇我们会讨论HMM模型参数求解的问题,这个问题在HMM三个问题里算是最复杂的.在研究这个问题之前,建议先阅读这个系列的前两篇以熟悉HMM模型和HMM的前向后向算法,以及EM算法原理总结,这些在本篇 ...

  8. 一、隐马尔科夫模型HMM

    隐马尔科夫模型HMM(一)HMM模型基础 隐马尔科夫模型(Hidden Markov Model,以下简称HMM)是比较经典的机器学习模型了,它在语言识别,自然语言处理,模式识别等领域得到广泛的应用. ...

  9. 隐马尔科夫模型 (HMM) 算法介绍及代码实现

    Table of Contents Hidden Markov Model (隐马尔科夫模型) 定义 基本问题 前向算法 算法流程 实现代码 后向算法 算法流程 实现代码 Viterbi算法 算法流程 ...

最新文章

  1. 混合云环境中扩展Kubernetes的挑战及方案
  2. oracle10g sql跟踪,SQL性能的度量 - 语句级别的SQL跟踪autotrace
  3. cpu线程_记w3wp占用CPU过高解决过程Dictionary线程安全
  4. Java中的数组怎么弄随机数_Java – 如何从值数组中创建随机数
  5. tomcat启动报错APR问题
  6. Head First 设计模式--1策略模式 组合优于继承
  7. JAVA安装详细教程
  8. Servlet基础:容器
  9. 使用matlab画图中图
  10. 5G商用元年开启万亿市场, 25G服务器端口出货量大幅增长
  11. 数独的生成算法和解题算法
  12. unity 3d开发的大型网络游戏
  13. Office Tips 3 - 如何设置电脑屏幕背景色为淡绿色
  14. linux下zip文件密码破解Fcrackzip
  15. 什么是Window【What Is a Window?】
  16. 02 | 论文中的「题目、目录、摘要和结论」应该怎么写?
  17. idea 设置编辑器 table 全部显示
  18. 今日头条组图下载本地,并存入MongoDB
  19. open-falcon开源监控使用
  20. 第十二篇:Unity与UE4的通信机制(二):UE4与UE4通信

热门文章

  1. 解决你的常见问题,这4款优秀的PC软件值得你尝试
  2. 消防相关的微信公众号图文不知道怎么排版?看这里!
  3. 权能博弈——分享经验技巧助你“大获全胜”
  4. java毕业设计派大星水产商城mp4mybatis+源码+调试部署+系统+数据库+lw
  5. 046:cesium加载高德地图(多种形式)
  6. 矩形波 matlab,在MATLAB中, 周期性矩形波(方波)信号 和方波信号函数
  7. python-numpy--矩阵与数组的操作
  8. python 特性和方法同名_脚本语言系列之Python | Python面向对象
  9. 穿过镜头看历史:斯皮尔伯格的二战情结
  10. fpimlauncher啥意思_action.MAIN、category.LAUNCHER、category.DEFAULT 啥意思