因子可以自动挖吗——从遗传规划到大语言模型
第 11 章的多因子是你手工想出来的:估值、动量、换手……每一个背后都有一句你能说出口的经济学理由。但一个自然的问题是:既然因子就是「用价量数据写出的一个公式」,能不能让机器在公式的空间里自己找?
这不是空想,这是过去十几年量化研究里最活跃的公开方向之一,也是你今后读论文、用工具时一定会撞见的物种。这一章讲两件事:机器挖因子的四条主流路线,以及比路线重要十倍的一课——机器挖出来的冠军,为什么必然「看起来有效」。
搜索空间:因子是一棵表达式树
Section titled “搜索空间:因子是一棵表达式树”先把「因子」写成机器能操作的形式。一个公式化因子就是一棵表达式树:叶子是原始数据(开盘价、收盘价、成交量、市值……),中间节点是算子:
- 截面算子:
rank(排名)、zscore(标准化)、group_neutralize(分组中性化); - 时序算子:
delay(x, 5)(5 天前的值)、delta(x, 10)(10 天变化)、ts_mean(x, 20)(20 日均值)、corr(x, y, 20)(20 日滚动相关); - 算术算子:加减乘除、对数、绝对值、条件。
举个例子,rank(-corr(rank(close), rank(volume), 10)) 读作「价格排名与成交量排名近期背离」——这是一个完全合法的因子,机器生成它只需要在树上做七八次选择。
问题在于空间的大小。叶子有几十个、算子有几十种、树可以有十几层——粗算合法表达式的数量在 量级往上。手工枚举无望,于是有了四条搜索路线。
四条路线:同一个空间的四种逛法
Section titled “四条路线:同一个空间的四种逛法”公开文献里的自动因子挖掘,按「怎么逛这个空间」分成四派:
| 路线 | 代表工作 | 核心思想 | 特点 |
|---|---|---|---|
| 遗传规划(GP) | AutoAlpha(2020) | 表达式像生物一样变异、交叉、优胜劣汰;用层级结构与多样性维持避免近亲繁殖 | 最老牌,可解释,易陷入局部最优 |
| 强化学习(RL) | AlphaGen(2023) | 把「逐个写出算子」当成序列决策游戏,奖励 = 样本内表现 | 有官方开源代码,社区复现最多 |
| 蒙特卡洛树搜索 | RiskMiner(2024) | 像 AlphaGo 下棋一样在表达式树上做模拟推演 | 搜索效率高,实现复杂 |
| 大语言模型(LLM) | 2024 年后大量工作 | LLM 先写「机制叙述」(为什么会有 alpha),再把叙述编译成表达式 | 当前最活跃;因子自带人话解释 |
人话总结:前三条路线是「在黑暗里摸索」,第四条是「让读过几千篇研报的机器先猜个方向再摸」。它们的差异在搜索效率与可解释性上,而在接下来要讲的致命问题上,四者完全同构。
核心一课:零因子世界的冠军
Section titled “核心一课:零因子世界的冠军”现在做本教程最擅长的事——造一个平行世界。
在这个世界里,我生成 10,000 个「因子」,每一个都是纯噪声:它们与次日收益的真实相关精确等于 0。然后模仿挖掘器的动作:把每个因子放到同一个 500 日样本里评估,记下各自的样本内 z 分数,最后把分数最高的那个「冠军」挑出来。
理论上一个都没用的世界里,冠军的分数长这样:
单个因子大多落在 的「不显著」区间里,但最大值是 z = 3.64——如果把它单独拿给你看,配上一句「我们发现了显著因子」,这就是一份漂亮的报告。而它生来的方式只是:被从一万个里挑了出来。
这不是新现象,是第 17 章夏普折减的同一个数学事实换了场景: 次纯随机尝试里,最高分的期望约为 个标准差。手算一遍:扫 10,000 个表达式,——冠军期望高度 z ≈ 4.29,和模拟实测几乎重合:
两条曲线一起单调上升——这就是全部要害:扫描越多,运气冠军越高,而它依然一文不值。你的「挖掘器越努力」,冠军的样本内分数越漂亮,它里面装着真 alpha 的证据反而越稀薄。
冠军的三个结构性死因
Section titled “冠军的三个结构性死因”除了「纯粹是运气」,挖出来的冠军还有三种更体面的死法——它们真的含信号,只是信号不是你以为的那个:
- 好天气代理。冠军因子的收益其实来自 beta 或风格暴露(小市值、高波动),行情好时它「有效」,本质是装扮成 alpha 的市场风险。判据:把因子对常见风格暴露回归后,残差里还剩多少预测力。
- 单块承载。全部超额来自某一段行情(比如一轮小盘股牛市),把那一块剔掉就平平无奇。判据:分时间块各算一次,看贡献是否集中。
- 成本墙。冠军依赖高频调仓,毛 IC 是真的,扣完双边费用与滑点后净值为负——第 4 章的成本模块在这种因子上最忙。
这三条加上「纯运气」,构成自动挖掘产出物的标准尸检报告。它们的共同含义是:挖掘器的产出只能叫「候选假设」,不能叫「发现」——从候选到结论,中间隔着第 6 章的封条、第 17 章的折减,和这一章的运气数学。
伪代码:遗传规划挖掘一轮
Section titled “伪代码:遗传规划挖掘一轮”输入:原始数据表(价、量、市值)、算子集、种群大小 P、迭代代数 G输出:候选因子清单(按样本内适应度排序)
第一步:初始化 随机生成 P 棵表达式树(限制深度与合法性)
第二步:进化 G 代 对每棵树: 计算因子值 → 截面评估(如样本内 IC 序列)→ 适应度 按适应度选择亲本(适应度越高越容易被选中) 交叉:交换两棵树的子树;变异:随机替换一个节点 保留多样性:过度相似的个体降权(防止全种群收敛到同一个公式)
第三步:冻结与移交【纪律,不是算法的一部分】 输出冠军清单并冻结(记录哈希与评估口径) 移交独立检验:样本外只烧一次、报告累计尝试次数 m 【挖掘过程的每一次适应度评估,消耗的都是样本内数据】注意第三步的位置:它在算法之外。四条路线的论文都把前两步写得精彩,而你的生死在第三步。
- 把挖掘期的分数当证据。挖掘器对样本内数据做了上万次评估,这份数据已经被「看」穿了——冠军清单上的分数全部只能算样本内,必须留一份没参与挖掘的数据做最终检验,且只用一次。
- 未来函数混进算子。
ts_mean(close, 20)的窗口含不含当日、因子用 T 日收盘算出却在 T 日收盘成交——挖掘框架的工程默认值往往对这些问题语焉不详,接入前逐条核对(第 1、4 章的纪律)。 - 冠军是 beta 代理。样本内 IC 最高的因子,十有八九和市场 exposure 高度相关——先过风格中性化再谈 alpha。
- 衰减了就换一批再挖。第一批挖出来的失效了,就在同一份数据上再挖一批——每挖一轮,尝试次数 m 就累加一轮,第 17 章的账本只增不减。挖掘是连续消费,不是免费重开。
- 把可解释性当免死金牌。LLM 路线给的机制叙述读起来非常合理——但「故事好听」与「数字成立」是两件独立的事,第 3 章的可检验假设标准一个也不能少。
机器在固定空间里搜表达式,还只是一个勤奋的搜索引擎。2024 年之后出现了更像「研究员」的新物种:它读数据、提假设、写代码、跑回测、读报告、再提假设——全自动的研发循环。下一章讲这个新物种的两个代表,和它上岗之后研究纪律为什么反而更重要了。