同花顺Supermind量化交易 财务分析建模 --隐马尔科夫模型应用于市场择时

196 阅读8分钟

作为现在最为热门的一项技术,机器学习以及数据挖掘变得逐渐令人熟知。隐马尔科夫模型(HMM)作为机器学习中的一个重要分支已经被人所广泛应用。著名数学家西蒙斯成立的大奖章基金纯粹采用技术量化方法进行投资,成立以来到2008年,大奖章基金的平均年度净回报是35.6%。HMM是大奖章基金一个重要的组成部分。本文首先就HMM进行介绍,并且对于HMM和股票市场的共性做出分析,最后写出HMM多因子择股的策略。

第九篇:隐马尔科夫模型应用于市场择时

导语:作为现在最为热门的一项技术,机器学习以及数据挖掘变得逐渐令人熟知。隐马尔科夫模型(HMM)作为机器学习中的一个重要分支已经被人所广泛应用。著名数学家西蒙斯成立的大奖章基金纯粹采用技术量化方法进行投资,成立以来到2008年,大奖章基金的平均年度净回报是35.6%。HMM是大奖章基金一个重要的组成部分。本文首先就HMM进行介绍,并且对于HMM和股票市场的共性做出分析,最后写出HMM多因子择股的策略。

隐马尔科夫模型 :

  HMM是是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。HMM包含一个可观测序列以及一个隐藏状态序列,比如说我不知道这个地区是不是富裕,但是我根据我所看到的比如这个地区高楼的数量,汽车的数量等从这些变量中我可以推测出来这个地区是不是富裕,这样是否富裕就是一种隐藏状态,而高楼汽车的数量则是一个观察变量。

  HMM是一个典型的黑箱模型,但是金融市场很多也是同样的黑箱模型,比如说在金融市场特别是股票市场中,我们并不知道现在市场是不是在牛市中或者是熊市当中,我们可以将这个看做隐藏状态,然后我们可以得到一系列可观察的数据,比如说成交量,收益率,成交量差等当做观察序列对市场隐藏状态状态进行预测,并且根据现在市场的状态决定是否进行买卖操作,这样很明显我们构造出了一个隐马尔科夫模型。但是隐马尔科夫模型也有一个很大的缺点就是我们并不能直接知道哪个状态是买入状态,哪个状态是卖出状态,所以我们要对每个状态的收益进行比较从而得出买入和卖出的结论。

模型测试:

  对中国的沪深300市场进行了HMM的训练集数据提取以及训练样本的测试,时间从2005/01/01-2013/01/01。下图为各个状态与沪深300走势的拟合情况:

  隐藏状态数:6

  特征向量:一日对数收益率,五日对数收益率,和五日成交量对数差。

  从图中我们可以看出,黄色的点明显都处于上升之中而红色的点基本都在下降之中出现,但是我们需要更加直观的观测出每个状态所代表的意义,所以我们对每个状态下的收益进行计算,结果如下图:

  从图中能够清楚的看出0,3状态是明显的牛市状态,状态2,5是明显的熊市状态,状态1是一个震荡状态。所以我们可以很容易的得到一个策略,在状态0,3是进行开仓操作,状态2,5时如果有仓位则进行平仓,状态1,4我们认为是震荡状态,不进行操作。

  但是由于HMM是一种概率模型,也就是说不是每次数据集回测的时候0,3状态永远表现最好,所以我们每次选择表现最好的两个状态作为买入状态而表现最差的两个状态作为卖出状态。

  此外由于HMM对于特征值的输入需要时一组序列,所以我们将回测期进行循环合成组成序列。这样我们就得到了简单的策略。

隐马尔科夫模型策略思想:

  第一步:选取沪深300中所有股票从2012/01/01-2015/01/01之间交易日的一日对数收益率,五日对数收益率,和五日成交量对数差作为观察序列属性。

  第二步:假设这些属性值服从正太高斯分布(HMM的强假设),我们直接利用这些历史数据完成HMM的构造,并且计算出其中表现最好的两个状态作为买入状态,其中表现最差的两个状态作为卖出状态

  第三步:在回测过程中将当前回测日的特征值和之前训练集特征数据构成一个可观察序列,放入HMM中进行状态序列的预测。

  第四步:每个回测日取出前一日的状态,如果此状态在买入状态中则进行买入沪深300,如果此状态在卖出状态中而且我们有持仓则卖出沪深300。

最终结果:

策略回测区间:2015.08.01-2018.12.31
回测频率:日级回测
回测资金:10000000
回测结果:红色曲线为策略收益率曲线,蓝色曲线为相应基准指数收益率曲线

策略源代码:

In [ ]:

#HMM择时
"""
    策略思想:先选取沪深300中所有股票从2012/01/01-2015/01/01之间交
    易日的一日对数收益率,五日对数收益率,和五日成交量对数差作为观
    察序列属性,假设这些属性值服从正太高斯分布(HMM的强假设),我们
    直接利用这些历史数据完成HMM的构造,并且计算出其中表现最好的两个
    状态作为买入状态,其中表现最差的两个状态作为卖出状态,然后在回
    测过程中将当前回测日的特征值和之前训练集特征数据构成一个可观察
    序列,放入HMM中进行状态序列的预测,每个回测日取出前一日的状态,
    如果此状态在买入状态中则进行买入沪深300,如果此状态在卖出状态中
    而且我们有持仓则卖出沪深300。
    
    初始资金:1000000
    回测频率:每天
    回测日期:2015-08-01——2018-12-31
"""
#导入HMM模型所需的包0
from hmmlearn.hmm import GaussianHMM

import datetime
import numpy as np
#导入画图所需要的包
from matplotlib import cm, pyplot as plt
import matplotlib.dates as dates
import pandas as pd
import seaborn as sns

def HMMModel(stklist, start, end, n):
    """获取训练好的HMM模型以及买入和卖出状态
    
    参数
    ----------
    stklist : 列表
        训练数据包含的股票代码.
        
    start : '%Y%m%d'形式字符串
        训练数据的起始日期.
    
    end : '%Y%m%d'形式字符串
        训练数据的结束日期.
        
    n :整数类型
        HMM模型中隐含的状态数.
    
    返回值
    ----------
    model : HMM模型
        训练好的HMM模型.  
    
    buystates : 列表
        买入的状态
    
    sellstates : 列表
        卖出的状态
        
    feature : 数组
        训练样本的特征数据集
    """
    df = get_price(stklist, start, end, '1d', ['close', 'volume'], True)
    
    #计算单日对数收益率
    df['1return'] = np.log(df['close']).diff(1)
    
    #计算五日对数收益率
    df['5return'] = np.log(df['close']).diff(5)
    
    #计算五日交易量对数差
    df['volume'] = np.log(df['volume'])
    df['5volume'] = df['volume'].diff(5)
    
    df = df.dropna()
    x = df['close']
    del df['close']
    
    #选取单日对数收益率,五日对数收益率,以及五日交易量对数差作为观测序列的特征因子
    feature = df.iloc[:,-3:].values
    
    #根据训练数据对HMM模型进行拟合
    model = GaussianHMM(n_components= n, covariance_type='diag', n_iter=2000).fit(feature)
    
    #通过训练数据计算不同隐含状态的累积收益率,选取前三作为买入状态后三个作为卖出状态
    hidden_states = model.predict(feature)
    x = pd.DataFrame(x)
    for i in range(n):
        x['%s'%i] = x['close']
        x['%s'%i] = 1
    for i in range(n):
        for j in range(0,len(x)-1):
            if hidden_states[j] == i:
                x.iloc[j+1,i+1] = (x.iloc[j+1,0]/x.iloc[j,0])*x.iloc[j,i+1]
            else:
                x.iloc[j+1,i+1] = x.iloc[j,i+1]
    ans = x.iloc[-1,1:]
    ans = ans.sort_values()
    buystates = ans.index.values[-2:]
    sellstates = ans.index.values[:2]
    for i in range(len(buystates)):
        buystates[i] = int(buystates[i])
        sellstates[i] = int(sellstates[i])
    return model, buystates, sellstates, feature

# 初始化函数,全局只运行一次
def init(context):
    #设置要交易的证券(000300.SH 沪深300)      
    context.security = '000300.SH' 
    #初始化全局变量
    context.clf, context.buy, context.sell, context.feature  = HMMModel(context.security, '20120101', '20150101', 6)

## 开盘时运行函数
def handle_bar(context, bar_dict):
    #计算测试集特征数据
    testdf = history(context.security, ['close','volume'], 10, '1d', True)
    testdf['1return'] = np.log(testdf['close']).diff(1)
    testdf['5return'] = np.log(testdf['close']).diff(5)
    testdf['volume'] = np.log(testdf['volume'])
    testdf['5volume'] = testdf['volume'].diff(5)
    testdf = testdf.dropna()
    
    #得到回测日前一日的特征数据
    feature_test = testdf.iloc[-1,-3:].values
    feature_test = feature_test.reshape(1,3)
    
    #将特征数据和之前的训练样本数据集结合起来当做观察序列
    context.feature = np.concatenate((context.feature,feature_test))

    if (context.clf.predict(context.feature)[-1] in context.buy):
        order_value(context.security,context.portfolio.available_cash)
    if context.portfolio.positions[context.security].market_value > 0:
        if (context.clf.predict(context.feature)[-1] not in context.buy):
            order_target(context.security, 0)

查看以上策略详情请到supermind量化交易官网查看:同花顺Supermind量化交易 财务分析建模 --隐马尔科夫模型应用于市场择时