基于AI排序算法的指数增强策略

自定义因子
自定义函数
自定义特征
指数增强
量化研究每周精选
标签: #<Tag:0x00007f20bdead938> #<Tag:0x00007f20bdead780> #<Tag:0x00007f20bdead5c8> #<Tag:0x00007f20bdead438> #<Tag:0x00007f20bdead2f8>

(iQuant) #1

在介绍AI排序算法之前我们先介绍另外一个术语:特征工程

特征工程是使用专业背景知识和技巧来处理数据,使得特征能在机器学习算法上发挥更好作用的工程实践。这样解释可能并不直观。举例说明,当我们选择用指标来评估一个人身体健康程度时,我们一般联想到的是身高和体重指标,这是两个不同的维度对数据进行记录,如果我们用身高除以体重这个衍生计算出来的比值来评估一个人身体健康状况,可能预测准确率比单单以身高或者体重进行预测效果好,这就是特征工程中如何构建特征的具体运用。

股票市场上机构最常见的量化选股策略为:多因子选股策略,其基本假设是:相似的资产会有相似的回报, 由于某些特定的原因(特征,也称为因子),资产会表现的十分类似,例如价量变化、行业、规模或者利率变化。因此通过股票的因子就能预测股票未来收益率,一些常年有效的因子包括:动量因子、反转因子、成长因子、财务质量因子、盈利能力因子、股东因子、波动率因子等等。多因子选股策略从本质上来说也是机器学习中特征工程的运用,通过构建衍生因子来对股票未来收益率进行预测。

互联网领域由于数据量大,天生就是机器学习的主战场,本文要介绍的排序学习算法在互联网领域已经有着广泛而成熟的运用。排序学习是一种广泛使用的监督学习方法 (Supervised Learning),比如推荐系统的候选产品、用户排序,搜索引擎的文档排序,机器翻译中的候选结果排序等等,该算法可以很好地将排序和选股结合起来。

策略设计

指数增强

指数增强类产品近两年比较火,一般指买入某个指数成分股,并通过择时、仓位动态调整等方式获得超越指数收益的策略。本文的策略有所差异,不是买入所有指数成分,而是以某一指数确定股票池,然后通过算法对指数成分股票进行排序,买入排序靠前的股票来实现获得超越指数收益的目的。

股票池
以上证50指数成分股为股票池。同理,也可以以沪深300、中证800或者某一行业的股票为股票池。

训练集和测试集确定
本文以2011-01-01至2016-01-01期间的数据作为训练集,以2016-01-01至2018-01-22期间的数据作为测试集。因此本文的策略回测区间为2016年以来。

数据标注
将股票未来5日的收益率进行离散化,映射到1至20共20个分类,标注高表示收益率高,这里离散化采取的是等宽离散化。

特征抽取
本文抽取的特征需要特别介绍的是个股相对于上证50指数(000016)的超额收益率数据,该特征的抽取采取的是方法是:用户自定义表达式函数抽取衍生特征,该方法能够非常自由灵活地抽取特征,比如可以抽取A股票相对于B股票的涨幅这类的特征,将大大丰富机器学习策略所需用到的因子体系,推进机器学习量化策略的开发提升到新的高度。

资金管理
多因子选股策略一般是按月调仓,但是本文的策略并不是按月调仓,而是每日调整部分持仓,这样做最大的好处就是能够及时更新选股结果,适应市场状况,尤其是采用了一些短期变化剧烈的价量因子的时候。我们也尝试过按固定周期全部仓位调仓,效果确实差一些。在买入股票的时候,本文策略也并不是多因子策略的等权重买入股票的思想,因为AI排序算法本身是对股票是否值得买入的一个综合排序,等权重思想与之不太切合,排序在前的股票买入权重越大、排序靠后的股票买入权重越小的思想更为适合,因此每只股票的买入权重可能差异很大。

回测交易
当AI排序算法在预测集上进行预测以后,我们可以通过一些机器学习的指标(比如NDCG)来检验预测的准确性,但对于策略思想检验而言,这并不直观,最直观的方式就是按照预测结果指导投资交易行为,采取收益率曲线来检验算法预测的准确性。本文策略回测区间为测试集时间跨度,策略基准为上证50指数。

策略效果
策略总收益为52.07%,年化收益为23.37%,夏普比率为0.95,最大回撤为16.04%。由于基准总收益率为29.31%,策略总收益为52.07%,因此该策略确实达到了指数上的增强效果。

接着看了一下该策略的风险暴露,发现基本上是集中在价值因子和规模因子上,这很好解释,因为上证50的股票本身规模很大,从公司价值本身来看都很不错。完整代码 在文末附件,对量化感兴趣的朋友可以接着开发优化。

附件

代码地址:基于AI排序算法的指数增强策略(代码)

更多阅读


基于AI排序算法的指数增强策略(代码)
社区干货与精选整理(持续更新中...)
(chaoskey) #4

学习了.


(matrixreloaded) #5

请教两个问题:

  1. M.instruments.v2, 这个文档在哪里,貌似没找到。
  2. 成分股每半年调整一次,有换进换出,如何使用动态成分股股票池?因为如果成分股种有现在才有的股票代码,那么有可能有未来函数了。望复,谢谢。

(iQuant) #6

问题1,M.instrument.v2是模块名称,M是Module的缩写。模块方面的文档社区文档里可能还未及时更新。

成分股的确会调整。机器学习划分训练集和测试集能一定程度规避此类未来函数。其实,称之为 幸存者偏差 肯定更为合理。

在BigQuant上比较好处理,就是在预测集每天选出来的股票上,再进行一次过滤,比如考虑买入的股票必须在上证50指数之内才能买入(即in_sse_0 ==0)。这个在Trade交易模块的主函数里加入一个判断逻辑即可。

希望对您的疑惑有所帮助!


(matrixreloaded) #7

谢谢楼主指正,是幸存偏差,哈哈。

可以不可以认为比如:
如果训练start_date=‘2011-01-01’,
end_date=‘2016-01-01’,
需要把这5年的所有曾经进入50指数的所有股票都放到instrument_list里面,然后进行训练?所以列出来的50指数才有75只?

有没有函数可以直接调出成分股股票名字?谢谢!


(iQuant) #8

是的。75只说明有调整,把整个区间内曾经出现在上证50的股票都放进去了。幸存者偏差问题是量化常见的问题,但一般的幸存者偏差不是特别严重,比如现在回测,全市场选股,但是只拿今天的全市场股票放进证券池,这样就会产生幸存者偏差。我们的处理方式是,instrument获取不是今天最新的全市场股票列表,而是从开始到最后整个区间上的股票列表,因此一些退市的股票也会放进来。不仅如此,最为关键的是在真正回测的那一天,应该做一个检查,检查当天该股票是否符合一定的特征,否则不予买入。

结合本策略,可以在买入的时候做一个当天的一个检查达到股票的过滤。这样就规避了幸存者问题。

获取成分股股票代码如下:

image

date='2017-05-23'
df = D.history_data(D.instruments(date, date),date,date,fields=['in_sse50'])
sz50 = set(df[df['in_sse50']==1]['instrument'])
sz50

(matrixreloaded) #9

还想问一下如何创建动态股票池?比如如何选择构建市值在选股当天时间大于总市值五百亿且上市满5年的蓝筹股之类的?谢谢!


(iQuant) #10

动态选股就是每日选出满足既定条件的股票池。
可以参考:《如何选出符合一定条件的股票》中下面截图的例子。

image