DeepAlpha短周期因子系列研究之:StockRanker在量化选股中的应用
由xiaoshao创建,最终由xiaoshao 被浏览 673 用户
引言
在BigQuant平台(www.bigquant.com)上线的第一天,我们从互联网搜索引擎领域借鉴了PageRank算法引入到金融市场,提出了StockRanker算法,5年时间悄然过去,时间证明了StockRanker算法在金融量化选股领域的有效性。 今天,我们对DeepAlpha-StockRanker进行简单介绍。
什么是DeepAlpha
Alpha在金融市场有特定含义,表示跑赢市场的超越收益,Deep借用深度学习(Deep Learning)“深度”一词,因此DeepAlpha指通过人工智能深度学习的技术挖掘超越市场的ALPHA收益的技术路线,示意如下:
从上图看出,在因子数据的基础上,通过深度学习模型,我们可以快速开发出AI量化选股策略。这里的深度学习模型包括一些基本的深度网络,比如全连接深度网络(DNN)、卷积神经网络(CNN)、长短期记忆网络(LSTM)、对抗生成网络(GAN)、ResNet、TabNet等,同时我们也会引入NLP领域近年来炙手可热的算法,比如BERT、Transformer算法、GPT、XLNet算法,不仅如此,在其他领域我们还会引入图神经网络和深度强化学习等算法。
除了深度学习算法,使用机器学习算法来获取非线性收益的方式也是DeepAlpha研究内容,因此本文对StockRanker算法进行测评。
第一部分:StockRanker基本原理以及StockRanker的在股市使用的可行性说明
StockRanker有如下特点:
- 选股:股票市场和图像识别、机器翻译等机器学习场景有很大不同。StockRanker充分考虑股票市场的特殊性,可以同时对全市场3000只股票的数据进行学习,并预测出股票排序
- 排序学习 (Learning to Rank):排序学习是一种广泛使用的监督学习方法 (Supervised Learning),比如推荐系统的候选产品、用户排序,搜索引擎的文档排序,机器翻译中的候选结果排序等等。StockRanker 开创性的将排序学习和选股结合,并取得显著的效果 (具体见即将发布的benchmark报告)。
- 梯度提升树 (GBDT):有多种算法可以用来完成排序学习任务,比如SVM、逻辑回归、概率模型等等。StockRanker使用了GBDT,GBDT是一种集成学习算法,在行业里使用广泛。
StockRanker的领先效果还得益于优秀的工程实现,我们在学习速度、学习能力和泛化性等方面,都做了大量的优化,并且提供了参数配置,让用户可以进一步根据需要调优。
第二部分:因子生成
交易型阿尔法体系
DeepAlpha属于交易型阿尔法研究体系。传统阿尔法体系的收益来源,往往集中于财务数据的挖掘、分析师一致预期数据的挖掘,而只有一小部分是中低频价量特征的数据。而在 A 股,市场交易行为具有很强的随机性,机构投资者的交易效率较之成熟市场亦不十分有效,加之 T+0、融券卖空等交易机制的缺乏,导致在短周期由于交易行为所产生的定价非有效十分常见。只要是投资者交易产生的价格序列,就一定不是随机序列,而这一特征在 A 股更为明显。
交易型阿尔法体系关注的特征主要是价格和成交量。对价量特征进行因子化处理的最大优势在于,避免了利用单一模式在时间序列上进行买点和卖点的选择,因为这牵涉到开平仓参数的敏感性问题等,会带来很大的不确定性和参数过拟合的问题。交易型阿尔法体系精髓在于,以当前市场的运行特征,寻找价格运行的规律。如果说传统阿尔法体系更加重视因子背后的价值投资逻辑,那么交易型阿尔法体系则更加重视交易行为背后的规律显著性,从某种意义上而言,这恰恰是最为直白朴素的投资逻辑。
再深度的神经网络也无法从无效的信息中掘金,因此在构建DNN模型之前,我们需要构建有效的市场因子,让模型能学习到市场的有效信息。
在因子生成上,我们参考了《华泰人工智能系列三十二——AlphaNet:因子挖掘神经网络》中的因子选择和构建的方式,然后再此基础上,提出了一套新的因子生成表达式。AlphaNet依照基本的价量因子构建特征“图片”,并在其上构建类似CNN的结构来识别并组合价量因子,例如使用相关系数、标准差、时序最大、时序最小、时序求和、加权平均等统计聚合方法。
基础数据
和《华泰人工智能系列三十二——AlphaNet:因子挖掘神经网络》基本一致,为了保证研究的客观性,我们没有给出富有ALPHA信息的因子,而是直接从量价行情基础数据中去构建因子。因此,我们使用了开盘价、最高价、最低价、收盘价、换手率、当日收益率、成交量这7个基础数据。只用这些基础数据,更多也是希望验证深度学习算法的预测能力。
生成表达式
在我们的DNN模型中,我们使用了时序求平均(mean)、时序求最大(ts_max)、时序求最小(ts_min)、时序标准差(std)、时序排序(ts_rank)、时序加权平均(decay_linear)、时序相关性(correlation)这6个表达式,和上述研报相比,我们并没有使用计算协方差(ts_cov)和计算Z得分(ts_zcore)这两个表达式,原因是协方差与时序相关性(correlation)基本一致,Z得分本质属于时序归一化,与时序排序(ts_rank)比较相关,这两个表达式无法产生更多具备预测信息含量的衍生因子,因此我们将其舍弃。
表达式 | 含义 | 说明 |
---|---|---|
mean | 时序平均 | 共生成7个衍生因子,例如mean(close_0, 5) |
ts_max | 时序求最大 | 共生成7个衍生因子,例如ts_max(close_0, 5) |
ts_min | 时序求最小 | 共生成7个衍生因子,例如ts_min(close_0, 5) |
std | 时序标准差 | 共生成7个衍生因子,例如std(close_0, 5) |
ts_rank | 时序排序 | 共生成7个衍生因子,例如ts_rank(close_0, 5) |
decay_linear | 时序加权平均 | 共生成7个衍生因子,例如decay_linear(close_0, 5) |
correlation | 时序相关性 | 生成21个个衍生因子,例如correlation(close_0, volume_0, 5) |
向前偏移 | 7*5=35个,例如close_4 | |
衍生因子数 | 共计98个 (7*6+21+35) |
在生成好98个因子后,我们未对因子进行标准化处理。 因为树模型可不要求数据标准化。
第三部分:构建StockRanker基准模型
开发流程
如下是一个AI策略主要流程的示意图:
相对于传统策略开发的复杂流程和调参等大量重复工作,AI策略开发更简单,将我们的脑力从重复工作上解放出来,专注在更有创造性的地方。
BigQuant 对AI策略开发做了抽象,设计了如下开发流程 (以 StockRanker 算法为例,也可以使用其他算法):
- 目标:首先定义机器学习目标并标注数据。很多机器学习场景,需要人来做数据标注,例如标注图片里的是猫或者狗。对于股票,我们关注的风险和收益是可以明确定义并自动计算出来的。所以,我们一般使用未来N天的收益或者收益风险比作为标注分数。本文使用未来给定天数的收益作为标注
- 数据:我们需要训练数据集来训练模型,已经评估数据集来评估效果。在模型参数研究中,我们一般还需要一个测试集用来观察调参效果
- 特征(因子):特征是量化研究的核心之一,在AI策略上,特征直接影响了模型的学习效果。这也是本文的目的之一,通过AI找出在A股有效的因子,并最大化的挖掘出他们的效果
- 算法模型:本文使用StockRanker算法,使用 M.stock_ranker_train 来训练模型,使用 M.stock_ranker_predict 来做出预测
- 回测:使用回测引擎来根据预测做股票交易,并得到策略收益报告和风险分析,并以此来评估策略的最终效果
基准模型参数
训练集时间:2010年1月1日到2017年12月31日
测试集时间:2018年1月1日到2022年4月20日
预测目标:未来5日收益率
模型:StockRanker
学习算法:排序
叶节点数量: 30
每叶节点最小样本数:1000
树的数量: 20
学习率: 0.1
特征值离散化数量: 1023
特征使用率:1
回测:
- 股票池:所有A股
- 交易成本:买入万分之3、卖出千分之1.3,不足5元按5元收取
- 买入规则:每天买入全市场所有股票中排序靠前的50只股票
- 卖出规则:每天卖出持仓股票中排序靠后的股票
- 资金管理:每个交易日进行交易,每个交易日等资金配置
- 股票权重:股票权重与股票排序结果成正比
- 回测中的模拟成交剔除停牌、涨跌停等异常情况
基准模型测试结果如下:
总体来看,18年1月1日到2022那年4月20日,总共收益22.75%,年化收益5.08%,虽然超越了基准收益率0.99%,但夏普比率为0.2并不高。
效果不是特别好的原因很多,比如训练集划分、模型参数、数据清洗处理、模型长期未更新等,因此给予了研究员更多的优化方向。
第四部分:模型稳定性测试
我们对叶节点数量、每叶节点最小样本数、树的数量、学习率四个模型超参数进行测试,验证模型对此参数稳定性。结果见下表,可横向左右拖动。
模型 | 总收益 | 年化收益率 | 最大回撤 | 夏普比率 | 收益波动率 |
---|---|---|---|---|---|
Baseline模型(叶节点数量: 30每叶节点最小样本数:1000树的数量: 20学习率: 0.1) | 22.75% | 5.08% | 24.08% | 1.06 | 21.16% |
叶节点数量对照组 | number_of_leaves | https://bigquant.com/experimentshare/fcad8f4e29ad4fd5b29f3aece6ea7ddc | |||
叶节点数量:10 | -14.64% | -3.75% | 39.4% | -0.22 | 20.68% |
叶节点数量:20 | 30.22% | 6.59% | 24.24% | 0.27 | 20.51% |
叶节点数量:40 | 8.49% | 1.99% | 27.39% | 0.07 | 22.12% |
叶节点数量:50 | 15.97% | 3.64% | 25.3% | 0.14 | 21.41% |
每叶节点最小样本数对照组 | minimum_docs_per_leaf | https://bigquant.com/experimentshare/2088e5909447410ca648173b547887ff | |||
每叶节点最小样本数 500 | -18.27% | -4.76% | 39.13% | -0.33 | 18.64% |
每叶节点最小样本数 800 | 12.29% | 2.84% | 29.17% | 0.1 | 21.7% |
每叶节点最小样本数 1200 | 4.89% | 1.16% | 27.51% | 0.02 | 20.86% |
每叶节点最小样本数1500 | 3.77% | 0.9% | 27.34% | 0 | 19.75% |
树的数量对照组 | number_of_trees | https://bigquant.com/experimentshare/e48bec32113447839d439451820ab79b | |||
树的数量:10 | 45.43% | 9.47% | 25.98% | 0.38 | 22.72% |
数的数量:20 | 30.14% | 6.57% | 27.1% | 0.27 | 21.97% |
数的数量:40 | 12.58% | 2.9% | 26.72% | 0.1 | 20.86% |
数的数量:50 | 10.36% | 2.41% | 27.55% | 0.08 | 21.02 |
学习率对照组 | learning_rate | https://bigquant.com/experimentshare/d5bc98bf794d4f70a61c293e39cbbab6 | |||
学习率:0.05 | 17.05% | 3.88% | 26.31% | 0.15 | 22.53% |
学习率:0.15 | 0.68% | 0.16% | 32.92% | -0.02 | 21.66% |
学习率:0.2 | 8.22% | 1.93% | 25.93% | 0.05 | 20.42% |
学习率:0.25 | 16.2% | 3.69% | 29.15% | 0.14 | 21.99% |
交易成本对照组 | |||||
双边费用 buy_cost=0.0003, sell_cost=0.0013 | |||||
双边费用 buy_cost=0.0008, sell_cost=0.0018 | 8.31% | 1.95% | 28.23% | 0.06 | 21.03% |
双边费用 buy_cost=0.001, sell_cost=0.002 | 0.16% | 0.04% | 30.93% | -0.03 | 20.89% |
双边费用 buy_cost=0.001, sell_cost=0.003 | -20.39% | -5.36 | 41.52% | -0.31 | 20.63 |
双边费用 buy_cost=0.002, sell_cost=0.002 | -14.77% | -3.79% | 38.4% | -0.22 | 20.79% |
双边费用 buy_cost=0.002, sell_cost=0.004 | -40.91% | -11.94% | 49.62% | -0.66 | 20.57% |
稳定性测试可以看出目前基准模型默认的参数是表现不错的一组,这得益于我们17、18年在大量的数据上进行过参数测试,选出了模型效果不错的一组参数。
第五部分:滚动训练回测
滚动训练机制
金融市场每个时间阶段具有不同的风格特征,找到任何时间都能战胜市场的模型不太现实,比如17年出现过“漂亮50与要命3000”,18年有白马股回调,20年的大盘成长,因此我们需要不断地更新模型更新策略,以适应不断变化的市场。在该DNN模型当中,我们采用了滚动训练的方式来更新迭代模型,以模拟真实的市场交易和模型训练。我们选择使用前3年的数据进行训练,后一年的数据进行测试,以滚动训练的方式测试我们的DNN模型。滚动训练机制介绍如图所示:
上图是滚动训练的一个简介,看出随着时间的流逝,我们会定期用最新的数据重新训练一个新的模型。
滚动训练回测结果
可以看出,这是一个具有正收益系统的量化策略,收益曲线整体长期向上。对AI量化感兴趣的研究员可以在此基础上进行调优。
滚动训练年度统计
从年度数据统计来看,有大约65%的年份超过了基准。
回测时间 | 收益率 | 年化收益率 | 基准收益率 | 夏普率 | 收益波动率 | 最大回撤 | 是否超越基准 |
---|---|---|---|---|---|---|---|
2009年1月5日-2009年12月31日 | 348.07% | 370.66% | 96.71% | 5.29 | 29.66% | 14.98% | 是 |
2010年1月4日-2010年12月31日 | 70.92% | 74.75% | -12.51% | 2.17 | 25.9% | 21.64% | 是 |
2011年1月4日-2011年12月30日 | -6.11% | -6.3% | 25.01% | -0.27 | 24.43% | 23.57% | |
2012年1月4日-2012年12月31日 | 27.67% | 28.83% | 7.55% | 0.94 | 28.05% | 20.43% | 是 |
2013年1月4日-2013年12月31日 | 88.83% | 96.02% | -7.65% | 2.82 | 23.82% | 13.5% | 是 |
2014年1月2日-2014年12月31日 | 113.29% | 117.96% | 51.66% | 3.23 | 24.19% | 14.57% | 是 |
2015年1月5日-2015年12月31日 | 2.76% | 2.85% | 5.58% | 0.21 | 41.88% | 45.92% | |
2016年1月4日-2016年12月30日 | 45.95% | 47.77% | -11.28% | 1.33 | 30.78% | 16.26% | 是 |
2017年1月3日-2017年12月29日 | -8.51% | -8.78% | 21.78% | -0.33 | 26.23% | 22.16% | |
2018年1月2日-2018年12月28日 | 4.51% | 4.68% | -25.31 | 0.21 | 31.64% | 27.1% | 是 |
2019年1月2日-2019年12月31日 | 40.53% | 42.1% | 36.07% | 1.45 | 24.27% | 17.14% | 是 |
2020年1月2日-2020年12月31日 | -1.91% | -1.98% | 27.21% | -0.17 | 18.59% | 18.91% | |
2021年1月4日-2021年12月31日 | 20.85% | 21.7% | -5.2% | 1.11 | 16.24% | 12.33% | 是 |
2022年1月4日-2022年04月20日 | -17.52% | -51.03% | -15.67% | -2.81 | 25.32% | 21.22% |
研究总结
StockRanker具备选股能力
该算法能挖掘出交易型收益来源,在大量数据上看到了一定的选股效果。
手续费对策略影响很大
在手续费参数的测试中,我们发现因为该策略 换手率较高,因此手续费直接影响到策略收益率,建议用户可设置较高的手续费,例如单边千2来二次验证策略的有效性和 收益能力。
模型不能静态不变
基准模型因为只训练了一次就长期没有更新,因此夏普比率并不高,我们看到当模型滚动训练,每一年用最新的数据进行一次更新,策略效果更好。
超参搜索很有必要
我们不鼓励像炼丹师那样去寻找全局最佳参数,但是也不支持直接固定的一组参数,不同的市场下模型的平原参数会动态变化,因此建议不能缺失超参数搜索这一步骤。