基于遗传规划的选股因子挖掘 (副本)
由sztuwhr创建,最终由sztuwhr 被浏览 144 用户
发布时间:2019年6月10日
研究团队:华泰金融工程
研究员:林晓明S0570516010001、陈烨S0570518080004
核心观点
本文通过原理分析和系统测试,介绍了遗传规划在选股因子挖掘中的应用 ====遗传规划是一种启发式的公式演化技术,通过模拟自然界中遗传进化的过程来逐渐生成契合特定目标的公式群体,适合进行特征工程。将遗传规划运用于选股因子挖掘时,可以充分利用计算机的强大算力,同时突破人类的思维局限,挖掘出某些隐藏的、难以通过人脑构建的因子==。==本文介绍了遗传规划应用的完整流程,对遗传规划程序包gplearn进行了深度定制改进。测试结果显示,==遗传规划能从有限的量价数据中挖掘出具有增量信息的因子,为选股因子研究提供了一种新的思路。==
针对因子挖掘问题,本文对遗传规划程序包gplearn进行了深度定制改进 本文在遗传规划的应用中做出了以下贡献:(1)应用成熟的gplearn项目,对gplearn的关键参数进行了详细说明。(2)扩充了gplearn中的函数集,添加了一批适合于构造选股因子的函数。(3)==将单因子测试过程引入gplearn,可以对待挖掘因子进行传统风格因子中性化==。(4)使用了Python的并行运算技术,加快了因子矩阵的运算速度,缩短了因子挖掘时间。
经过测试,遗传规划能从有限的量价数据中挖掘出具有增量信息的因子 在遗传规划框架中,==我们设定预测目标为个股20个交易日后的收益率,初步挖掘出了6个选股因子。这些因子在剔除了行业、市值、过去20日收益率、过去20日平均换手率、过去20日波动率五个因子的影响后,依然具有较稳定的RankIC。==6个因子都具有良好的可解释性,其中大部分因子的相关性不高,==说明遗传规划能从有限的量价数据中挖掘出具有增量信息的因子。==
遗传规划是一套灵活的框架,或许能为选股因子研究提供更多的可能性 本着“授人以鱼不如授人以渔”的想法,本文旨在为读者展示遗传规划在选股因子挖掘中的详细流程,流程中的各环节依然有较大的调整空间。在实际应用中,读者可以根据自己特定的数据源、股票池、调仓周期、函数集以及评价指标来构建遗传规划框架。作为一种“先有公式、后有逻辑”的因子研究方法,遗传规划或许能为选股因子研究提供更多的可能性。
\
使用遗传规划的缺点与风险
风险提示:通过遗传规划挖掘的选股因子是历史经验的总结,存在失效的可能。遗传规划所得因子可能过于复杂,可解释性降低,使用需谨慎。本文仅对因子在全部A股内的选股效果进行测试,测试结果不能直接推广到其它股票池内。
\
本文研究导读
在华泰金工人工智能系列前期的报告中,我们重点研究人工智能算法在多因子选股中因子合成方面的应用。本文则从一个新的角度出发,探索如何使用人工智能算法进行选股因子挖掘。在众多人工智能算法中,==遗传规划(genetic programming)借鉴了生物进化的过程,是一种适合进行特征工程的算法==。本文将详细讨论如何在股票量价数据中使用遗传规划进行选股因子挖掘。本文将主要关注以下三个问题:
\1. 遗传规划的基本原理是什么?有哪些重要的参数?
\2. 在将遗传规划运用于选股因子挖掘时,需要进行哪些定制化改进?
\3. 遗传规划所得选股因子的表现如何?因子的含义如何解读?
遗传规划简介
物竞天择,适者生存。——《天演论》
遗传规划(genetic programming)是演化算法(evolutionary algorithm)的分支,是一种启发式的公式演化技术。遗传规划从随机生成的公式群体开始,通过模拟自然界中遗传进化的过程,来逐渐生成契合特定目标的公式群体。==作为一种监督学习方法,遗传规划可以根据特定目标,发现某些隐藏的、难以通过人脑构建出的数学公式==。==传统的监督学习算法主要运用于特征与标签之间关系的拟合,而遗传规划则更多运用于特征挖掘(特征工程)==。
在量化多因子选股领域中,选股因子的挖掘是一个关注度经久不衰的主题。以往的因子研究中,人们一般从市场可见的规律和投资经验入手,进行因子挖掘和改进,即“先有逻辑、后有公式”的方法,常见的因子如估值、成长、财务质量、波动率等都是通过这种方法研究得出的。随着市场可用数据的增多和机器学习等先进技术的发展,我==们可以借助遗传规划的方法在海量数据中进行探索,通过“进化”的方式得出一些经过检验有效的选股因子,再试图去解释这些因子的内涵,即“先有公式、后有逻辑”的方法==。以上两种方式对应于选股因子研究方法中的“演绎法”与“归纳法”,都有一定的存在基础。而后者的优势在于可以充分利用计算机的强大算力进行启发式搜索,同时突破人类的思维局限,挖掘出某些隐藏的、难以通过人脑构建的因子,为因子研究提供更多的可能性。
遗传规划的总体流程
图表1展示了遗传规划的总体流程。一开始,一组未经选择和进化的原始公式会被随机生成(第一代公式),通过某种规则计算每个公式的适应度,从中选出适合的个体作为下一代进化的父代。这些被选择出来的父代通过多种方法进化,形成不同的后代公式,然后循环进行下一轮进化。随着迭代次数的增长,公式不断繁殖、变异、进化,从而不断逼近数据分布的真相。
遗传规划中公式的表示方式
为了方便进行公式的进化,遗传规划中的公式一般会被表示成二叉树的形式。假设有特征X0和X1,需要预测目标y。一个可能的公式是:
在遗传规划中上式用S-表达式(S-expression)表示:
公式里包括了变量(X0和X1)、函数(加、减、乘)和常数(3和0.5)。我们可以把公式表示为一个二叉树,如图表2所示:
在这个二叉树里,所有的叶子都是变量或者常数,内部节点则是函数。树内的任意子树都可以被修改或替代。公式的输出值可以用递归的方法求得。
遗传规划中的适应度
==类比于自然界中个体对其生存环境的适应程度,在遗传规划中,每个公式也有自己的适应度,适应度衡量了公式运算结果与给定目标的相符程度,是公式进化的重要参考指标==。在不同的应用中,可以定义不同的适应度,例如对于回归问题,可以使用公式结果和目标值之间的均方误差为适应度,对于分类问题,可以使用公式结果和目标值之间的交叉熵为适应度。对于使用遗传规划生成的选股因子来说,==可以使用因子在回测区间内的平均RankIC或因子收益率来作为适应度==。
遗传规划中公式的进化方法
遗传规划的核心步骤是公式的进化,算法会参照生物进化的原理,使用多种方式对公式群体进行进化,来生成多样性的、更具适应性的下一代公式群体。本节将依次介绍这些进化方法。
交叉
交叉是在两个已有公式树之间生成子树的方法,是最常用也最有效的进化方式。交叉需要通过两次选取找到父代和捐赠者,如图表3所示,首先选取适应度最高的公式树A作为父代,从中随机选择子树A1进行替换; 然后在剩余公式树中找到适应度最高的公式树B作为捐赠者,从中随机选择子树B1,并将其插入到公式树A中替换A1以形成后代。
子树变异
子树变异是一种激进的变异操作,父代公式树的子树可以被完全随机生成的子树所取代。这可以将已被淘汰的公式重新引入公式种群,以维持公式多样性。如图表4所示,子树变异选择适应度最高的公式树A作为父代,从中随机选择子树A1进行替换,然后随机生成用以替代的子树B,并将其插入到公式树A中以形成后代。
点变异
点变异是另一种常见的变异形式。与子树变异一样,它也可以将已淘汰的公式重新引入种群中以维持公式多样性。如图表5所示,点变异选取适应度高的父代公式树A,并从中随机选择节点和叶子进行替换。叶子A2被其他叶子替换,并且某一节点A1上的公式被与其含有相同参数个数的公式所替换,以此形成后代。
** **
Hoist变异
Hoist(提升)变异是一种对抗公式树过于复杂的方法。这种变异的目的是从公式树中移除部分叶子或者节点,以精简公式树。如图表6所示,Hoist变异选取适应度高的父代公式树A并从中随机选择子树A1。然后从该子树中随机选取子树A11,并将其“提升”到原来子树A1的位置,以此形成后代。
遗传规划中公式的表示方式
gplearn的简介和关键参数说明
gplearn(https://gplearn.readthedocs.io)是目前最成熟的Python遗传规划项目之一。gplearn提供类似于scikit-learn的调用方式,并通过设置多个参数来完成特定功能。图表7展示了gplearn的主要参数。
gplearn的改进
gplearn提供了一套简洁、规范的遗传规划实现代码,但是不能直接运用于选股因子的挖掘。我们从源代码的层面,对gplearn进行了深度改进,使得其能运用于选股因子的挖掘。
首先,我们扩充了gplearn的函数集(function_set),提供了更多特征计算方法,以提升其因子挖掘能力。除了gplearn提供的基础函数集(加、减、乘、除、开方、取对数、绝对值等),我们还自定义了一些函数(包括多种时间序列运算函数,这是gplearn不支持的),函数列表详细展示在图表8中。
其次,我们改进了gplearn使得其能进行单因子测试。在测试过程中,还可以对待挖掘因子进行传统风格因子中性化。另外,遗传规划由于涉及到大量的随机操作,时间开销较大,我们还使用了Python中的并行运算技术,加快了因子矩阵的运算速度,缩短了因子挖掘时间。
遗传规划选股因子挖掘的测试流程
测试流程包含下列步骤:
\1. 数据获取和特征提取:
\1) 股票池:全A股,剔除ST、PT股票,剔除每个截面期下一交易日停牌的股票。
\2) 回测区间:2010/1/4~2019/5/31。
\3) ==因子列表如图表9所示,都是个股的原始量价信息,未经过特征工程。==
==\4) 预测目标:个股20个交易日后的收益率。==
\2. 使用遗传规划进行因子挖掘:
\1) 使用图表9中的因子和图表8中的函数集,生成大量公式,并按照图表1的流程进行公式的进化和筛选。
\2) 公式适应度的计算:假设有公式F,得出该公式在截面t上对所有个股因子向量后,我们会对因子进行以下处理:
经过以上处理后,==计算处理后因子在每个截面上与20个交易日后收益率的RankIC,取RankIC均值为公式F的适应度。==
\3. 对遗传规划挖掘出的因子,进行更详细的单因子测试,包含IC测试、回归测试和分层测试。尝试对因子含义进行解释。
\4. ==对遗传规划挖掘出的因子进行IC值衰减分析,相关性分析。==
遗传规划的主要参数设置和测试结果
本文的遗传规划中主要参数设置在图表10中。遗传规划与其他机器学习算法不同,其参数难以使用网格搜索寻优,主要根据计算机算力和实际因子挖掘结果调整。
在遗传规划的运行过程中,我们可以监控公式群体的一些统计信息来得知当前公式进化的状况。图表11展示了某次测试中的统计信息。可以看出,公式进化到了第三代,第一代公式是随机生成的,平均长度较长,平均适应度很低。第二代公式平均长度减小,平均适应度明显提升。第三代公式在第二代公式的基础上继续进化,平均长度稍长,平均适应度继续提升。
我们的测试在一台有2个E5-2650处理器的计算机上进行,1000个公式进化3代耗时约14个小时。图表12展示了遗传规划挖掘出的选股因子。在计算适应度(RankIC)时,因子已经进行了行业、市值、20日收益率、20日换手率、20日波动率中性化。
遗传规划所得因子的单因子测试
本章中,我们首先介绍单因子测试方法。然后详细展示图表12中因子的单因子测试结果,并尝试对因子的含义进行解释。
单因子测试方法简介
回归法
回归法是一种最常用的测试因子有效性的方法,具体做法是将第T+1期的因子暴露度向量与期的股票收益向量进行线性回归,所得到的回归系数即为因子在期的因子收益率,同时还能得到该因子收益率在本期回归中的显著度水平——t值。在某截面期上的个股的因子暴露度(Factor Exposure)即指当前时刻个股在该因子上的因子值。第期的回归模型具体表达式如下。
回归模型构建方法如下:
1. 股票池:全A股,剔除ST、PT股票,剔除每个截面期下一交易日停牌的股票。
2. 回溯区间:2010/1/4~2019/5/31。
3. 截面期:每个交易日作为截面期计算因子值,与该截面期之后20个交易日内个股收益进行回归。
4. 数据处理方法:
- a) 因子计算方法详见图表12;
- b) 中位数去极值:设第T期某因子在所有个股上的暴露度向量为 ,为该向量中位数,为向量的中位数,则将向量中所有大于的数重设为,将向量中所有小于的数重设为;
- c) 中性化:以行业及市值中性化为例,在第T期截面上用因子值(已去极值)做因变量、对数总市值因子(已去极值)及全部行业因子(0/1哑变量)做自变量进行线性回归,取残差作为因子值的一个替代,这样做可以消除行业和市值因素对因子的影响;
- d) 标准化:将经过以上处理后的因子暴露度序列减去其现在的均值、除以其标准差,得到一个新的近似服从N(0,1)分布的序列,这样做可以让不同因子的暴露度之间具有可比性;
- e) 缺失值处理:因本文主旨为单因子测试,为了不干扰测试结果,如文中未特殊指明均不填补缺失值(在构建完整多因子模型时需考虑填补缺失值)。
5. 回归权重:由于普通最小二乘回归(OLS)可能会夸大小盘股的影响(因为小盘股的财务质量因子出现极端值概率较大,且小盘股数目很多,但占全市场的交易量比重较小),并且回归可能存在异方差性,故我们参考Barra手册,采用加权最小二乘回归(WLS),使用个股流通市值的平方根作为权重,此举也有利于消除异方差性。
6. 因子评价方法:
- a) t值序列绝对值均值——因子显著性的重要判据;
- b) t值序列绝对值大于2的占比——判断因子的显著性是否稳定;
- c) t值序列均值——与a)结合,能判断因子t值正负方向是否稳定;
因子收益率序列均值——判断因子收益率的大小。
IC值分析法
因子的IC值是指因子在第T期的暴露度向量与T+1期的股票收益向量的相关系数,即
上式中因子暴露度向量一般不会直接采用原始因子值,而是经过去极值、中性化等手段处理之后的因子值。在实际计算中,使用Pearson相关系数可能受因子极端值影响较大,使用Spearman秩相关系数则更稳健一些,这种方式下计算出来的IC一般称为Rank IC。
IC值分析模型构建方法如下:
\1. 股票池、回溯区间、截面期均与回归法相同。
\2. 先将因子暴露度向量进行一定预处理(下文中会指明处理方式),再计算处理后的T期因子暴露度向量和T+1期股票收益向量的Spearman秩相关系数,作为T期因子Rank IC值。
\3. 因子评价方法:
a) Rank IC值序列均值——因子显著性;
b) Rank IC值序列标准差——因子稳定性;
c) IC_IR(Rank IC值序列均值与标准差的比值)——因子有效性;
d) Rank IC值序列大于零的占比——因子作用方向是否稳定。
分层回测法
依照因子值对股票进行打分,构建投资组合回测,是最直观的衡量因子优劣的手段。分层测试法与回归法、IC值分析相比,能够发掘因子对收益预测的非线性规律。也即,若存在一个因子分层测试结果显示,其Top组和Bottom组的绩效长期稳定地差于Middle组,则该因子对收益预测存在稳定的非线性规律,但在回归法和IC值分析过程中很可能被判定为无效因子。
分层测试模型构建方法如下:
- \1. 股票池、回溯区间、截面期均与回归法相同。
- \2. 换仓:在每个截面期核算因子值,构建分层组合,在截面期下一个交易日按当日vwap换仓,交易费用默认为单边0.15%。
- \3. 分层方法:先将因子暴露度向量进行一定预处理(下文中会指明处理方式),将股票池内所有个股按处理后的因子值从大到小进行排序,等分N层,每层内部的个股等权重配置。当个股总数目无法被N整除时采用任一种近似方法处理均可,实际上对分层组合的回测结果影响很小。分层测试中的基准组合为股票池内所有股票的等权组合。
- \4. 多空组合收益计算方法:用Top组每天的收益减去Bottom组每天的收益,得到每日多空收益序列r1,r2,...rn,则多空组合在第n天的净值等于(1+r1)(1+r3)...(1+rn)。
- \5. 本文分层测试的结果均不存在“路径依赖”效应,我们以交易日=20天为例说明构建方法:首先,在回测首个交易日K_0构建分层组合并完成建仓,然后分别在交易日K_i,K_(i+20),K_(i+40),⋯按当日收盘信息重新构建分层组合并完成调仓,i取值为1~20内的整数,则我们可以得到20个不同的回测轨道,在这20个回测结果中按不同评价指标(比如年化收益率、信息比率等)可以提取出最优情形、最差情形、平均情形等,以便我们对因子的分层测试结果形成更客观的认知。
评价方法:全部N层组合年化收益率(观察是否单调变化),多空组合的年化收益率、夏普比率、最大回撤等。
遗传规划所得因子的回归测试、IC测试结果汇总
图表13展示了遗传规划所得因子的回归测试、IC测试结果汇总。其中最后一种情况中的4个常见风格分别指市值、20日收益率、20日换手率、20日波动率。可以看出,在进行了行业+4个常见风格中性后,遗传规划所得因子依然具有较显著的增量信息。
接下来,我们将详细展示以上6个因子在进行了行业+4个常见风格中性后的测试结果。
Alpha1因子的详细测试结果
Alpha1 = correlation(div(vwap, high), high, 10)
Alpha1计算的是个股的div(vwap, high)和high之间在10个交易日内的相关系数。从分层测试上看,Alpha1的第1层表现欠佳,第2层表现最好。第2层到第10层的表现呈单调变化。从回归和IC测试上来看,Alpha1具有较稳定的因子收益率和RankIC,IC_IR为0.94。
Alpha2因子的详细测试结果
Alpah2 = ts_sum(rank(correlation(high, low, 20)),20)
Alpah2计算的是个股的high和low在20个交易日内相关系数的排序数之和。Alpah2因子值越高的股票,其日最高价和最低价在走势上“步调”越一致。从分层测试上看,Alpha2的1~10层表现单调,但是前3层在最近几年的超额收益并不明显。从回归和IC测试上来看,Alpha2的因子收益率和RankIC都比Alpha1高,但稳定性略差,IC_IR为0.78。
Alpha3因子的详细测试结果
Alpha3 = -ts_stddev(volume, 5)
Alpha3的意义非常简明,其描述的是个股成交量近5日的波动率。从分层测试上来看,Alpha3呈现出“中间好,两头差”的情况,也就是说,成交量5日波动率偏低或偏高的股票组合表现不如成交量5日波动率中等的股票组合。Alpha3的因子收益率和RankIC都不太稳定,IC_IR为0.36。
Alpha4因子的详细测试结果
Alpha4 = -mul(rank(covariance(high, volume, 10)) , rank(ts_stddev(high, 10)))
Alpha4因子由两部分相乘而得,左边部分rank(covariance(high, volume, 10)衡量个股的10日量价同步程度,右边部分rank(ts_stddev(high, 10))衡量个股的10日最高价波动率。
从分层测试上来看,Alpha4第1层和第2层表现欠佳,第4~第10层表现单调。 Alpha4的因子收益率和RankIC较为稳定,IC_IR为0.59。
Alpha5因子的详细测试结果
Alpha5 = -mul(ts_sum(rank(covariance(high, volume, 5)), 5), rank(ts_stddev(high, 5)))
Alpha5的逻辑和Alpha4类似,二者的总体表现也接近。Alpha5的因子收益率均值和RankIC均值比Alpha4略低。
Alpha6因子的详细测试结果
Alpha6 = ts_sum(div(add(high,low)), close), 5)
Alpha6描述了个股最近5日内每日的多头力量(high)和空头力量(low)强度的对比。Alpha6的分层测试表现欠佳,首先分层的单调性一般,其次表现最好的层相比基准的超额收益也不明显。Alpha6的因子收益率均值和RankIC均值也较低。
因子的IC衰减测试
图表33展示了各因子的半衰期,半衰期的计算方式为因子实际Rank IC首次衰减到一半时的滞后期数。如需调整因子参数,或可参考半衰期来进行调整。
因子之间的相关性
图表34展示了因子Alpha1~6之间的相关系数均值,除了Alpha4和Alpha5相关性较高外(因为它们的构造逻辑相似),其他因子的相关性都较低,说明遗传规划能从有限的量价数据中挖掘出具有增量信息的因子。
总结与思考
==本文经过原理分析和系统的测试,得出以下结论:==
\1. ==遗传规划是一种启发式的公式演化技术,通过模拟自然界中遗传进化的过程来逐渐生成契合特定目标的公式群体,适合进行特征工程。将遗传规划运用于选股因子挖掘时,可以充分利用计算机的强大算力进行启发式搜索,同时突破人类的思维局限,挖掘出某些隐藏的、难以通过人脑构建的因子,为因子研究提供更多的可能性==。
\2. 本文在遗传规划的应用中做出了以下贡献:(1)应用成熟的gplearn项目,对gplearn的关键参数进行了详细说明。(2)扩充了gplearn中的函数集,添加了一批适合于构造选股因子的函数。(3)将单因子测试过程引入gplearn,可以对待挖掘因子进行传统风格因子中性化。(4)使用了Python的并行运算技术,加快了因子矩阵的运算速度,缩短了因子挖掘时间。
\3. 在遗传规划框架中,我们设定预测目标为个股20个交易日后的收益率,初步挖掘出了6个选股因子。这些因子在剔除了行业、市值、过去20日收益率、过去20日平均换手率、过去20日波动率五个因子的影响后,依然具有较稳定的RankIC。6个因子都具有良好的可解释性,其中大部分因子的相关性不高,说明遗传规划能从有限的量价数据中挖掘出具有增量信息的因子。
\4. 本着“授人以鱼不如授人以渔”的想法,本文旨在为读者展示遗传规划在选股因子挖掘中的详细流程,流程中的各环节依然有较大的调整空间。在实际应用中,读者可以根据自己特定的数据源、股票池、调仓周期、函数集以及评价指标来构建遗传规划框架。作为一种“先有公式、后有逻辑”的因子研究方法,遗传规划或许能为选股因子研究提供更多的可能性。
风险提示
通过遗传规划挖掘的选股因子是历史经验的总结,存在失效的可能。遗传规划所得因子可能过于复杂,可解释性降低,使用需谨慎。本文仅对因子在全部A股内的选股效果进行测试,测试结果不能直接推广到其它股票池内。
\
正文
/wiki/static/upload/87/87588660-2a2d-4276-bdf0-a31797f7b161.pdf
\