量化投资的利器:隐马尔可夫模型(四)

之前的《量化投资的利器:隐马尔可夫模型(三)》讨论了如何在监督式学习的场景下使用隐马尔可夫模型。在监督式学习(针对序列数据)里,搭建模型的训练数据为{(X_i, y_i)},其中y_i表示事物的状态,它是能被观察的(训练数据里有这个变量)。但在现实生活中的很多情况下,变量y_i是隐藏的、观测不到的,得到的训练数据里只有X_i,如图1所示。

图1

比如《量化投资的利器:隐马尔可夫模型(一)》中的例子:只能观察到小安每天的活动,并不知道每天的天气情况;又比如在股票市场,我们只能看到股票价格、成交量等信息,但无从知道当前股市的状态(分为牛市、熊市和震荡3种状态),这些场景都是所谓的非监督式学习,下面讲讨论如何在这些场景下使用HMM模型。

:在Github上可以下载本文中所用到的训练数据和模型代码。

一、股票市场:非监督式学习

对于这种类型的数据,我们希望也能像之前一样,搭建模型预测变量y_i(根据变量X_i)。这是一个很困难的任务,因为这要求模型能像变魔术一样,“无中生有”地变成相应的y_i来。比较经典的逻辑回归、支持向量学习机等判别式模型完全没办法处理这类型数据,但作为生成式模型的隐马尔可夫模型却能很好地完成这个建模任务。事实上,解决这种非监督式学习问题才是隐马尔可夫模型的设计初衷,也是这个模型最常用的使用方法。从文字上来讲,隐马尔可夫这个名字中的隐字就对应着变量y_i不可观测这个事实。

隐马尔可夫模型是如何做到这一点的呢?要回答这个问题,我们先来看看在已知y_i的情况下,隐马尔可夫模型是如何估计模型参数的。正如前面文章讨论的那样,隐马尔可夫模型估计模型参数的原则是最大似然估计法,就是最大化序列数据的联合概率P(X, y),如公式(1)所示,其中\theta表示模型参数,(X, y) = {(X_i, y_i)}表示训练数据。

P(X, y | \theta) = P(y_0 | \theta) \prod_i P(y_i | y_{i - 1}, \theta) \prod_j P(X_j | y_j, \theta) \\ \hat{\theta} = argmax_\theta P(X, y | \theta) \tag{1}

在非监督学习中,变量是未知的,但依然可以类似地定义模型的似然函数,如公式(2)所示:

P(X | y, \theta) = P(y_0 | \theta) \prod_i P(y_i | y_{i - 1}, \theta) \prod_j P(X_j | y_j, \theta) \\ \hat{\theta}, \hat{y} = argmax_{\theta, y} P(X| y, \theta) \tag{2}

与监督式学习相比(公式(1)),变量从已知的训练数据变成了一类特殊的“模型参数”,但整个似然函数的“架子”(数学公式)还是不变的。针对这类似然函数,依然可以使用最大似然估计法的原则来估计模型参数以及被预测量。但与监督式学习相比,由于新加入了未知量,需要估计的“参数”个数更多了,所以需要用到特殊的估计算法:最大期望算法(Expectation-Maximization Algorithm,EM)。下面就以multinomial HMM为例介绍,如何在非监督式学习场景里使用EM算法估计模型参数。

数学上可以证明,如果将上面的两步重复交叉使用,就可以最终得到公式(2)的解。这就是EM算法,其中第一步被称为M step,而第二步被称为E step,具体如图2所示。

图2

在讨论完有点艰深晦涩的模型理论后,我们重新回到股票市场,讨论如何使用隐马尔可夫模型对其建模。正如本节开头讨论的,将股票市场分为如下两层。

  • 第一层是观察得到的股票市场特征包括5日的收益率、20日收益率、5日成交额增长率以及20日成交额增长率,用变量X_i表示。
  • 第二层是观察不到的市场状态,一共包含3种状态,分布是牛市、熊市和震荡(当然也可细分为更多的市场状态,这里仅以3种状态举例),用变量y_i表示。

我们希望能搭建这样一个模型,它能根据一段时间的市场表现(变量X_i),预测当前的市场状态以及未来一段时间的市场状态(变量y_i)。在金融界,针对股票市场有一个很重要的假说,那就是有效市场假说[1]。这个假说的意思是当前的股票价格已经反映了所有历史信息的价值。换句话说,当前的市场状态已经完全包含了历史市场状态,因此在已知当前市场的条件下,未来和过去是相互独立的,即y_i可以认为是一个马尔可夫链,这是使用隐马尔可夫模型的基础。除此之外,进一步假设在市场状态已知的情况下,股票的日收益率和成交量服从正态分布[2]。根据这些假设,搭建隐马尔可夫模型如下。

  • 先验分布P(X_i | y_i):正如上面的假设,这个分布是一个正态分布,而且显然在不同的市场环境下,日收益率和交易量对应的协方差矩阵显然是不一样的。因此,假设X_i | (y_i = l) \sim N(\mu_l, \Sigma_l)
  • 初始分布P(y_0):由于变量是离散的,因此假设P(y_0 = l) = a_l(这和《量化投资的利器:隐马尔可夫模型(三)》中的multinomial HMM是一致的)。
  • 转移矩阵P(y_i | y_{i - 1}),它表示3种状态间相互转移的可能性,于是假设矩阵的元素为P(y_i = l | y_{i - 1} = t) = b_{l, t}(这和multinomial HMM也是一致的)。

由于这个隐马尔可夫模型是基于正态分布的,因此它在学术上被称为Gaussian HMM。

二、股票市场之代码实现

讨论完理论部分后,现在来看看具体的代码实现。本节将使用Gaussian HMM模型对上证指数的历史数据进行建模。所用数据是从2005-06-01到2017-08-28的上证指数以及相应的每日成交额(事实上,数据里还有每日最高最低价等有用信息,但为了表示简洁,本节的建模例子并不使用这些变量)。
对金融市场比较了解的读者会知道,中国的A股(也就是被人熟知的深市和沪市)开始于1990年12月19日,但A股在最初阶段并不是一个很成熟的金融市场,这主要表现在上市公司内部普遍存在“股权分置”的现象[3]。2005年6月开始的股改是一个标志性的事件,表明中国的A股市场与国际开始接轨,并逐步迈向成熟。这个时间点前后的股票市场是截然不同的两个市场,因此只使用股改开始后的数据进行建模。

除了具体价格,股票市场每天的成交额(买卖股票的总金额)也是反映市场状态的一个很重要的指标。通常认为,在牛市里成交额会逐步放大,而在熊市里成交额会极度萎缩。针对A股市场,在使用成交额这个数据时需要特别注意这一点。1990年至今(2017年),中国经历了人类历史上罕见的经济高速发展期。伴随着经济的快速增长,通货膨胀是不可避免的,比如1990年末的货币供应量M2为15 293.4亿,而2016年末的M2为1 550 100亿元,增长了大约100倍。因此,在利用成交额搭建模型时,需要使用通货膨胀率对其做相应的折现处理[4]。在本节的例子中,我们使用的是5日成交额增长率以及20日成交额增长率,这就很巧妙地避开了上述的通货膨胀问题。

虽然scikit-learn并没有实现将要使用的Gaussian HMM模型[5],但有比较成熟的开源方案:hmmlearn。它的安装方法很简单,只需运行“pip install -U --user hmmlearn”即可。

模型的代码实现很简单,如程序清单1(完整代码请参考stock_analysis.py)所示。

  1. 第三方库hmmlearn实现了3种用于非监督式学习的HMM模型,分别是Gaussian mixture HMM、multinomial HMM以及Gaussian HMM。本节将使用Gaussian HMM,它的具体实现为GaussianHMM,如第1行所示。

  2. 从原始数据中提取4个特征搭建模型,它们分别是5日的收益率(“r_5”)、20日收益率(“r_20”)、5日成交额增长率(“a_5”)以及20日成交额增长率(“a_20”),如第7行代码所示。

  3. GaussianHMM里的参数“n_components”表示内在状态的个数,本例中这个值等于3,如第8行代码所示。
    参数“covariance_type”表示先验分布里协方差矩阵的类型(在状态已知的情况下,特征服从正态分布)。这个值等于“full”表示在不同市场状态下协方差矩阵是不同的,而且可以是任意半正定对称矩阵(也就是说并不要求协方差矩阵是对角矩阵)。其他可能的取值为“spherical”(协方差矩阵为单位矩阵)、“diag”(协方差矩阵为对角矩阵)以及“tied”(不同状态下的协方差矩阵是一样的)。
    参数“n_iter”则表示EM算法的最大循环次数。

  4. GaussianHMM的模型API与scikit-learn非常相似,如第9、10行代码所示,使用fit方法训练模型;使用predict方法对数据做预测。

程序清单1 Gaussian HMM

 1  |  from hmmlearn.hmm import GaussianHMM
 2  |  
 3  |  def getHiddenStatus(data):
 4  |      """
 5  |      使用Gaussian HMM对数据进行建模,并得到预测值
 6  |      """
 7  |      cols = ["r_5", "r_20", "a_5", "a_20"]
 8  |      model = GaussianHMM(n_components=3, covariance_type="full", n_iter=1000)
 9  |      model.fit(data[cols])
10  |      hiddenStatus = model.predict(data[cols])
11  |      return hiddenStatus

根据模型的分类结果,将不同的状态的上证指数表示在不同的坐标系里可以得到如图3所示的结果,其中标记1为所有的市场交易数据,而标记2、3、4则是分类结果。图3表示模型的分类结果基本符合预期,比如在标记2中,股市上涨和下跌的比例大致相同,而且都在一个比较窄的区间内变化,因此对应的是震荡这个市场状态。类似地,可以推断出标记3表示的是熊市,而标记4表示的是牛市[6]

图3

基于上面的模型结果,很容易就能得到较为有效的量化交易策略,比如执行这样的策略就能获得不错的收益:若当天的隐藏状态是牛市(根据模型结果),则买入或继续持有股票,否则卖出股票或保持空仓。

如果实际生产中真的使用这个模型来做交易,你会沮丧地发现实际效果远不如历史数据的测算结果。这是因为隐马尔可夫模型的预测公式如下所示(程序清单1中第10行代码中的predict方法就是这么计算的):

\hat{Y} = argmax_Y P(y_0, ..., y_T | X_1, ..., X_T) \tag{3}

也就是说,在测算历史数据时,预测变量y_1时,就已经知道了后来的实际交易数据X_2, ..., X_T。这一点在实际生活中是不可能实现的,因为没有办法预知未来。因此,为了使模型的测算结果更加符合现实,需要循环地调用公式(3)来预测,而不是一次性地得到全部数据的预测结果。

三、广告时间

这篇文章的大部分内容参考自我的新书《精通数据科学:从线性回归到深度学习》

李国杰院士和韩家炜教授在读过此书后,亲自为其作序,欢迎大家购买。

另外,与之相关的免费视频课程请关注这个链接


  1. 有效市场假说(efficient-market hypothesis)是金融学里最重要的理论之一。这个理论认为,投资者无法通过建模等技术手段从市场上获取超过平均水平的收益,也就是说对股票市场进行建模是无意义的。

  2. 金融学里常常假设市场是一个服从正态分布的随机游走,而且实际数据也大致符合这个假设。另外数学上对正态分布的处理也最为成熟,基于该分布进行建模可行性是最高的,因此传统的量化金融模型大多会使用这一假设。但在实际生活中,市场并不总是服从正态分布的,这会导致传统量化模型在特定条件下表现很差。由于金融市场离钱最近,即使很小的模型偏差也会导致巨大而直接的金钱损失,这就是所谓的“黑天鹅”事件。所以现代量化金融的研究重点是利用非正态的概率分布(non Gaussian distribution)搭建模型。

  3. 在股票市场刚成立时,大部分上市公司是国有企业。这些企业大多数有3种类型的股份:国有股、法人股以及普通股。其中只有普通股能在股票市场上交易,于是这3种类型的股份形成了“同股不同权,同股不同利”的局面,也就是所谓的“股权分置”现象。

  4. 折现就是利用折现率(可以理解为更广义的通货膨胀率),将现在的货币折算成等价的过去货币。举个简单的例子,假设当前时间距离过去的基准时间点为t年,需要折现的金额为a,折现率为\beta,则折现后的金额为a\beta^{t}

  5. 事实上,较早版本的scikit-learn(在0.17之前)是包含隐马尔可夫模型的,但后来因为项目目标的变化,这部分代码被移出了scikit-learn,变成了本节将要使用的hmmlearn。

  6. 虽然Gaussian HMM能将数据分类,但与监督式学习有所不同的是,分类结果并没有直接的物理意义。也就是说,模型只能将数据分类,但无法告诉我们每个类别的具体含义。因此需要人为地根据各个类别里的数据特点,给类别赋予含义。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容