拓冰建站拓冰建站
首页 / 资讯中心 / 正文

101 Formulaic Alphas量化因子公式全解析:从原理到实战

1. 这本书到底在讲什么这两年只要进入量化研究这个圈子无论你是做股票、期货还是加密货币几乎绕不开一份材料——《101 Formulaic Alphas》。我第一次看到这本书的PDF时心里想的是“又是一本凑数的公式合集吧”结果翻开目录就愣住了整整101条带详细伪代码的因子公式每条都有明确的信号计算逻辑、数据窗口、行业处理方式甚至每条后面还标注了对应的学术论文或数据来源。后来WorldQuant的研究员Zura Kakushadze用论文形式把它发表在arXiv上马上成了整个量化圈人手一份的“操典”。它的定位很清晰不是讲“如何用机器学习挖因子”也不是“如何搭建回测平台”而是给出一批已经被验证有研究价值的、可解释的、线性的价格与成交量因子公式。这些公式覆盖了均值回归、动量、突破、量价配合、波动率调节等几乎所有主流交易逻辑而且每条都有明确的资金中性、行业中性、市场中性处理方式。对新手来说它是从“零散理解技术指标”走向“系统性理解alpha生成逻辑”的一座桥对有经验的研究员来说它又像一本“字典”——当你临时需要某个风格的信号直接翻到对应公式改一改就能用。什么人适合读这本书我的建议是已经会写Python或R、懂一点股票交易基本概念比如收盘价、成交量、涨停跌停、但对“因子”“Alpha”还是很懵的研究者在读这本书之前最好先有一个认知框架——本书的每一条公式本质上都是在回答一个共同问题过去一段时间里的价格和成交量数据能否预测未来的收益方向。2. 全书核心框架数据、公式、持仓2.1 数据格式约定统一一切的基础这本书开头就用一个非常工程化的方式定义了自己的世界所有公式都用列向量表示每日每只股票的观测值比如 open、high、low、close、volume、returns、vwap每个都是按日期和股票ID对齐的大矩阵/DataFrame。这样设计的好处在于101个公式可以互相拼接、横向比较不必每个公式都重新定义数据口径。我强烈建议你在做自己的研究时也沿用这套约定把原始行情数据统一清洗成DataFrame列为股票代码行为日期值按变量名存好。宁可前期多花两天整理数据也不要在写公式时反复处理缺失值、复权因子和停牌标记。很多初学者拿到这本书后第一反应是“这么简单的公式能赚钱吗”实际上恰恰相反。书里的公式在数据上做了大量隐含的工程处理比如没有直接使用“收盘价”而是用adv{d}表示过去d日的平均成交额用cap表示总市值用IndClass表示行业分类。如果你不考虑这些细节直接照抄公式回测很容易得到一堆看似无意义的结果。2.2 公式的统一结构信号、权重、窗口如果只用一个公式来概括全书的套路那就是信号 某种基于历史和横截面的统计量组合权重 信号经过行业中性化、市值中性化、缩尾、标准化后的结果预测收益 组合权重乘以未来N日收益率。每一条公式的差异基本体现在三个维度用什么数据是只用close还是closeopen还是closevwap还是加上了成交量用什么算子是否做rank、是否做ts_mean、是否做ts_min_max、是否做correlation用什么窗口5日、10日、20日、60日还是动态的这三个维度组合起来理论上可以生成无数条公式书里的101条更像是一个“最优筛选”的结果。这也解释了为什么书名叫“Formulaic Alphas”——它强调“公式化”意味着每一条都是可复现、可审计、可参数化的而不是一个黑箱神经网络。2.3 三条公式为例先建立一个直观感受为了让你对后面几个大章节更有掌握感我先挑三条非常典型的公式做个初步索引式解读。第1条是(rank(ts_argmax(signedpower(returns, 1), 5)) - 0.5)。这个公式的逻辑是过去5天里哪一天的单日收益在符号方向同时“最极端”如果在最近这几天出现就对未来有某种短期反转的预测力。这里用了两个关键算子signedpower是为了加大极端收益的权重ts_argmax是找过去5天窗口内最大值所在的位置。它的信号值始终在0到1之间最后减0.5让信号围绕0波动方便后面的中性化处理。第27条是(-1 * rank(ts_delta(close, 5)) * correlation(vwap, close, 10))。这条的核心是用“近5日收盘价变化方向”和“量价相关性”的乘积来做空/做多。简单理解如果收盘价刚涨了5天同时vwap和close的相关性很高说明这次上涨量价配合良好反而预示着短期要回调取负号做空。第101条是(close - open) / ((high - low) 0.001)。这个公式最简单却非常经典它本质上就是K线实体相对振幅的占比。实体部分越大说明多空力量在某一个方向上的确占了绝对优势但这又不是单纯追涨因为后面还隐含了一个“如果已经涨太多实体再大也容易反转”的博弈逻辑。这三条公式分别代表了时间序列类、截面相关类、价差结构类三种基本范式后面你会在几乎所有复杂公式里看到这三种基本功的组合。3. 因子逻辑分类从101条公式里提炼规律3.1 按公式结构维度拆解把101条公式全部看完后我建议你不要按顺序背公式而是按结构做一次聚类。拆解下来主要就是以下几类均值回归类典型特征是信号和近期收益负相关。例如直接用排名后的负收益、用ts_rank之后取负、用价格偏离移动平均的程度。这类因子在小市值、高波动标的上表现往往更好因为行为金融学里的过度反应在这些标的上更明显。动量/趋势类典型特征是信号和过去一段时间的收益正相关比如ts_rank(close, 20)、ts_delta(close, 20)之类的变形。这类因子逻辑上是追涨杀跌但实盘中必须小心“拥挤”——当一个因子被太多人使用它的收益来源会被拿走甚至变成负贡献。量价协同类核心是成交量和价格变化之间的关系比如用volume和returns的相关系数、用vwap和close的差值方向。这类因子往往比单纯价格因子更稳健因为它隐含了参与者的成交意愿。波动率调节类先是计算某种波动率指标然后对原始信号做除法或乘法调整。比如第5条就是用stddev(returns, d)做分母让高波动股票的仓位自动下降本质上是一种简化版的风险评价。日内结构类使用open、high、low、close四价的结构差异比如此前说的第101条以及基于上影线、下影线方向的若干公式。这类因子高频属性更强在日线、小时线数据上效果更明显。3.2 按交易逻辑维度拆解如果我们换一个维度站在交易逻辑的角度来看这101条公式会发现它们背后的经济学解释也非常清晰短期反转基于过去1~10天的收益做反向操作背后是流动性提供者的补偿逻辑。散户的过度申赎、机构调仓的冲击成本都会在短期价格上留下可以捕获的偏差。中期动量基于过去20~60天的收益做同向操作背后是信息扩散的缓慢过程。当一个利好出现分析师和资金不可能一天内完全消化价格会在一段时间内持续调整。波动率异象低波动股票的未来收益往往高于高波动股票这个现象很明显书里不少公式直接或间接地对波动率做了反向处理。价格位置股票当前价格在过去N天区间中的位置隐含了支撑位和压力的博弈。这个逻辑更像技术分析里“突破”或“超买超卖”的量化表达。3.3 怎样用一套代码快速“读完”101条公式如果你不想一条一条手写公式建议用一个循坏脚本读入每条公式的伪代码再把伪代码转换成Python函数。具体步骤是先做一张“公式元信息表”每行记录公式编号、主要算子、窗口、是否需要行业中性化、是否用市值加权。然后写一个通用执行器用pd.DataFrame和numpy实现核心算子rank、ts_rank、decay_linear、ts_sum、correlation等。我的经验是先把这十几个算子写出来再去看公式效率会高得多。否则每条公式都要从0开始造轮子很容易在情绪上被劝退。4. 从“伪代码”到“可回测的策略”核心实操环节4.1 数据准备和算子库搭建这本书里的伪代码虽然已经是“公式化”的但离直接能回测还差一层工程化。你需要先把数据对齐到“日期 × 股票”的矩阵再把每个公式翻译成一段函数。以下是我建议的环境配置Python 3.9用pandas、numpy、scipy即可暂时不需要深度学习的库股票池建议从沪深300或中证500成分股开始容量适中流动性足够复权方式统一用后复权价格避免分红送转造成的价格跳变交易成本单边手续费和滑点合计至少按0.1%估算否则回测收益会严重虚高。算子实现有一个非常容易出错的地方——rank到底是在横截面同一天不同股票上做还是在时间序列同一只股票不同日期上做书里的算子定义写得很清楚rank默认是横截面排名ts_rank则是时间序列排名。如果你搞混了结果会完全不一样。我当初在实现第15条公式时把rank和ts_rank弄反回测出的年化收益直接从正15%变成了负20%排查了很久才发现是算子语义问题。4.2 从公式到每日持仓中性化与标准化流程光算出一个信号值还不够真正决定组合表现的是“如何把信号变成持仓”。书中每条alpha公式后面几乎都附带了“正规化”和“中性化”步骤。我在这里把标准流程拆开方便你直接抄作业。第一步是缺失值处理。停牌或上市不满N天的股票会被标记为NaN在横截面计算之前最简单的方式是直接剔除或者在标准化时跳过NaNs。第二步是去极值。常用方法是MAD缩尾中位数加减n倍绝对中位差或分位数截断。比如对信号值做1%和99%分位的截断可以避免极端值对标准化结果的干扰。第三步是中性化。金融里最常见的是市值中性化和行业中性化。做法是把信号值作为因变量把对数市值和行业哑变量作为自变量做一次线性回归然后取残差作为新的信号。这就等于“扣掉”了由市值和行业带来的共同成分让组合在不同风格下都能相对“干净”地暴露在纯粹alpha上。第四步是标准化。把残差减去均值后除以标准差得到z-score。最后在z-score上做上下限截断比如正负3形成最终的组合权重。这套流程并不只在复现《101 Formulaic Alphas》时需要你自己的任何高频或低频因子研究大概率都会用到同一套中性化-标准化的技术栈。我把它视为量化研究的基本功。4.3 一个最小可运行的复现案例以第3条公式为例第3条公式的伪代码是(-1 * correlation(rank(open), rank(volume), 10))。翻译成人话就是过去10天里开盘价排名和成交量排名之间的相关系数是负的说明“低开放量”这是一种偏反转的信号。用Python实现的核心代码大致如下import pandas as pd import numpy as np def alpha003(open_price, volume, window10): # open_price: DataFrame, index为时间, columns为股票代码 # 横截面排名 rank_open open_price.rank(axis1) rank_volume volume.rank(axis1) # 10日滚动相关按列循环处理或用rolling corr corr rank_open.rolling(window).corr(rank_volume) signal -corr return signal你可能已经发现了rank操作是在每一天的横截面上按股票排序然后用这个排序值进一步做时间序列相关。如果你的数据不是“日期×股票”的宽表而是“日期×股票”的长表那么需要先用pivot转成宽表再操作。另外rolling.corr在 pandas 里的默认是按列匹配的所以需要确保两张DataFrame的列顺序一致。回测时可以这样简单处理每天收盘时把alpha信号按前文提到的流程做中性化和标准化然后按权重买入排名前N的股票做空排名后N的股票持有1天或5天计算组合收益。这里我补充一点实际经验不要一上来就追求“101条全部分批跑完”一次跑3~5条把算子、中性化、成本模型全部打通后面就只是体力活了。4.4 回测评估指标不要只看年化收益率很多刚入门的朋友复现出一条公式看到年化30%就很兴奋其实这是非常危险的。评估因子至少要关注以下几个维度IC信息系数每日信号值与未来N日真实收益的截面相关系数通常取IC均值、ICIR。IC均值在0.02以上就算有研究价值的因子。换手率信号每天变化多少。换手率越高交易成本吞噬的收益就越多。书里部分公式天然是高换手的例如基于5日窗口的均值回归实盘前一定要做衰减处理。分年度/分市场表现一个因子不能只在2019年有效在2021年失效就说明它可能被“拟合”了。要用不同年份、不同市场状态的数据做稳健性测试。最大回撤一个年化30%但最大回撤50%的策略实盘里很难拿住。因子层面最好也观察多头组合和空头组合分别的回撤情况。我曾经完整复现过第4条公式(-1 * ts_rank(rank(low), 9))单看全样本IC均值在0.03左右但分年看2015年IC高达0.082017年却只有0.01基本失效。如果不看分年统计数据很容易误判。5. 容易踩的坑十个常见问题与排查心得5.1 算子语义错误这是我在新手阶段踩得最狠的一个坑。rank是对横截面同一天的所有股票做排名ts_rank是对时间序列同一只股票过去N日做排名两者逻辑上差别巨大。很多时候你会发现某条公式“看起来很简单”但跑出来结果总是和对不上十有八九是这里出了问题。遇到公式异常时先打印中间结果的shape和sample用一个小数据集手工推演一遍再跑全量数据。5.2 未来函数与滑点预估不足这本书的公式本身都是用的当前和历史数据理论上是没有未来函数的。但实际工程中你计算vwap、adv等指标时如果不小心用了当日收盘后才知道的数据就会引入“偷看未来”。我的习惯是所有因子生成时只能使用t-1及更早的数据当日信号最早只能在第二天的开盘或收盘去交易。滑点方面A股小市值股票的冲击成本远比想象中大回测时至少按单边0.1%~0.2%估算否则换手率高的因子会直接把收益亏光。5.3 市值暴露没有处理干净部分公式天然带着小市值偏好比如基于past N日成交额的指标天然会给低流动性股票更高权重。如果中性化流程里漏掉了市值项回测收益看着很高其实全是小市值风格贡献的。区分alpha和风格暴露的办法是看空头组合的表现——如果多头组合是涨的空头组合也是涨的说明这不是选股alpha而是纯粹的做多beta或市值因子。5.4 交易成本与换手率失控我用一个实际例子说明问题某条基于5日反转的公式日均双边换手率高达80%名义年化收益30%但考虑单边0.1%成本后年化收益只剩5%再扣掉打新和保证金占用基本不值当。对这类因子一个常见做法是加上衰减权重例如decay_linear让旧信号保留一部分新信号只替换一小部分或者干脆用周频调仓像一个低频因子去做。5.5 行业中性化方式的细节行业中性化的标准做法是构建行业哑变量做线性回归取残差。但行业分类本身有不同口径申万、中信、GICS用不同的行业分类中性化结果差异很大。我的建议是做A股研究时同步用申万一级行业做哑变量同时在低一级行业二级行业也做一次稳健性测试。如果两个口径下的IC差异特别大说明因子可能对行业划分高度敏感实盘时要先明确采用哪种分类口径。5.6 打印公式中间结果逐级验证很多公式看起来只有一行代码中间却有嵌套。我复现第59条公式时怎么调IC都不稳定后来把每一步中间结果都画出来才发现是ts_min对应的窗口取错了导致信号整体滞后了一天。检查方法很简单把公式拆成4~5个中间变量每个变量都保存下来分别和原始论文的样例对比。如果你能找到作者公开的因子值文件那就直接对拍。6. 从复现到创新如何用“101阿尔法”构建自己的因子库6.1 杂交和变形把书里的公式当积木拆开你可以自由组合出数量级更多的因子。比如第1条用到了signedpower第101条用到了(close-open)/(high-low)如果把signedpower作用在第101条的分子上就得到一个“对实体长度做非线性放大”的新信号。这种杂交方式没有标准答案但建议每次杂交后都回到因子评估框架去看IC、换手率、相关性别为了让曲线好看而盲目堆叠。6.2 正交化和合成101条公式之间的相关性其实很高尤其是都基于价格区间的公式。当成百上千个因子同时放在多因子模型里需要做因子正交化常见的做法是PCA或对称正交化。每轮正交化后观察每个因子对整体IC的边际贡献剔除掉那些被其他因子解释掉的“冗余因子”。我用这套思路从书里的101条公式出发扩展到600多个派生因子最后留下来进入模型的只有30个左右但实盘稳定度显著提升了。6.3 结合机器学习做非线性集成线性因子组合的收益来源相对透明但很难捕捉交互效应。一个比较稳妥的思路是先用101条公式生成因子矩阵再做标准化和中性化然后丢给LightGBM或XGBoost做非线性集成。注意一定要做严格的时间序列交叉验证防止数据泄露。我自己在实践中发现树模型对量价因子做集成在A股中证500上能比简单的线性加权多出20%~30%的信息比率但随之而来的是过拟合和因子失效速度变快的问题。所以模型越复杂越要频繁监控因子衰减情况建议每个月重算一次因子IC。6.4 用在小市值还是大市值101条公式的特点是大部分是基于日频价格和成交量的短周期因子在小市值、高换手、散户占比高的市场上效果更好。如果你把它用在沪深300或港股大盘股上需要先做换手率和容量适配。比如把5日窗口改成20日窗口把单日信号改成周频信号通过这种参数调整原本只适合小票的策略也能在大票上获得不错的稳健性。当然参数调整要建立在逻辑合理的前提上不能为了回测曲线好看而任意调参那样就是典型的过拟合。7. 学习路径建议给不同基础的读者7.1 零基础入门路径如果你刚从传统技术分析或基本面研究转过来第一步不是急着读完全书而是先做这样几件事熟悉Python的基本数据操作把pandas的groupby、pivot、rolling、rank用熟找到任意一套日线数据免费的tushare、baostock都可完成数据清洗、对齐、复权用书里最简单的一条公式比如第101条跑通整条研究链路数据读取、信号计算、中性化、回测、看绩效。这个过程通常在2~4周内完成一旦链路通了后面99条公式只是换汤不换药。7.2 有经验研究员的进阶路径如果你已经会写因子想用这本书做系统化升级建议直接按“算子库搭建——公式批量翻译——因子正交化——组合构建”四步走。前两步属于体力活真正有价值的是后两步。批量生成出来的几百个因子如果不做正交化相关性会高到让你怀疑人生。正交化之后你看到的因子库才是真正“分散化”的。7.3 实盘前的最后十道检查清单我把自己的实盘前检查习惯列成了一份清单每次新因子入职前都会逐条过一遍因子计算数据是否只用了t-1及之前的信息行业和市值中性化是否做了双重检查回测交易成本是否足够保守分年度IC是否稳定因子与已知持仓风格的相关性是否过高多头组合和空头组合是否同时有贡献换手率是否在可承受成本范围内极端行情如2015年、2024年初流动性危机下因子是否失效参数稍微变动结果是否依然稳健策略容量测算是否符合资金规模这套清单救过我很多次因为很多因子在样本内表现完美实盘却亏得一塌糊涂回溯原因基本都是“成本估计不足”或“市值暴露没处理干净”这两个老问题。8. 关于这本书的“版本”和“周边资源”《101 Formulaic Alphas》有两个流传比较广的版本一个是作者在arXiv上发布的学术论文版里面有完整的伪代码定义和数学符号说明另一个是社区根据伪代码实现的Python/R版本散见于GitHub。我的建议是以arXiv论文为主GitHub实现为辅。因为社区版本往往会在翻译过程中引入算子语气的偏差尤其是rank和ts_rank的差别有时候不仔细看根本发现不了。书里的所有公式都定义为“在给定日期对股票池做截面计算”这一点在任何复现中都要保持一致。另外WorldQuant官方后来也发布过alpha101的模拟实现和数据集老版本的qlib、alphalens也能兼容这套因子框架。如果你想做更正式的因子研究建议直接把因子计算封装成alphalens的factor接口这样可以方便地复用IC分析、分层回测、换手率统计等功能。我个人在实际操作中的一个小建议是不要试图一天吃掉101条公式而是每周精读10条、亲手复现8条、用1条做二次改造。这样的节奏坚持十周你对“什么是alpha”“因子之间如何协同”的理解会有质的飞跃。今天就把数据准备好用第101条公式跑通你的第一个回测吧后面的事情会顺利很多。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门