因子:把「为什么涨」变成一个可以算出来的数
问一句「这只票为什么涨」,你会听到一堆回答。
「它业绩好啊。」「它是龙头。」「它前面跌太多了,反弹。」「机构在建仓。」
这些话你都听得懂,而且多半也不算错。但它们有个共同的毛病:没法算。你没办法把「业绩好」输进电脑,让它在五千只股票里给每一只打个分,然后按分数排个序。只要一个说法不能变成数字,它就永远停在饭桌上,永远只能事后拿来解释,没法事前拿来筛选。
量化系统解决这件事的方式很朴素——先承认自己听不懂人话,然后要求你把话改写成一个能算的规则。这个改写出来的规则,就叫因子。
先说人话:因子就是一把尺子
想象你要在一堆西瓜里挑一个。
老师傅的办法是「拍一下,听声音」。这个办法可能真的有用,但它不是因子——因为「声音闷不闷」没法变成一个数,也没法让一百个人拍出同一个结论。
换个办法:每个瓜都称重、量周长,然后算「重量除以周长的三次方」。这个数越大,说明瓜越瓷实。现在你得到了一列数字,一百个瓜就是一百个数,可以直接排序,谁在前谁在后一目了然,而且换个人来算,结果一模一样。
这就是因子的全部意思:一条规则,能给评价对象里的每一个,在同一时刻算出一个可比的分数。
注意这个定义里三个词,缺一不可——
- 每一个:不是只算你关注的那三只票,是把范围里的全部标的都算一遍;
- 同一时刻:所有分数是在同一天、用同一天能拿到的信息算出来的;
- 可比:一百块的股票和十块的股票,算出来的分数能放在一起排序,不会因为股价本身高低而失真。
体检报告也是同一个套路。医生不会跟你说「你看起来有点虚」,他给你一张表,每一项都有个数、都有个参考范围,然后跟同龄人分布比一比。因子做的就是这件事,只不过对象从人换成了股票。
投资层:因子和指标,到底差在哪
这是本篇最该讲透的一处。很多人第一次听到「因子」,第一反应是「这不就是指标换个说法吗」。确实长得像,公式甚至可以完全一样,但用法差出一个维度。
指标看的是「纵向」,因子看的是「横向」。
你打开一只票的日线图,挂上均线、MACD、RSI,你在做的事是:盯住这一只票,沿着时间轴往前看——它现在比它自己一周前如何,比它自己一个月前如何。得出的结论是「这只票现在该不该买」。这是一个时序问题,一次只处理一只标的,输出通常是个是非题:买,或者不买。
因子的姿势正好转九十度:冻结在某一天,把范围内所有票横着排一排。今天这五千只票,谁的这个数最大,谁最小。得出的结论不是「这只票该不该买」,而是「这五千只里,哪一百只相对更值得买」。这是一个横截面问题(横截面就是「同一时间点上的一排对象」,跟纵向的时间序列相对),一次处理全市场,输出是一列连续的分数而不是是非题。
同一个公式,换个用法就能在两边横跳。拿最简单的「过去二十天涨幅」:
- 当指标用:这只票二十日涨幅超过某个数,就发出买入信号——它和自己比;
- 当因子用:今天把所有票的二十日涨幅算出来排序,买排在最前面那一批——它和别人比。
第二种用法有个第一种没有的性质:它天然是相对的。熊市里所有票都在跌,因子照样能选出「跌得最少的那一批」,分数本身的正负不重要,排名才重要。这也解释了为什么因子那一套天然长在「同时持有一篮子股票」的语境里,而指标那一套天然长在「盯住一只票进进出出」的语境里。
由此推出一条对你的实际决策很有用的判断:当有人跟你说「我用了某某因子」,你应该立刻追问一句「你拿它排序了吗,选出来的那批一共多少只」。 如果答案是「我就用它看了一只票」,那他用的是指标,不是因子,两者的检验方法和失效方式完全不一样。
系统层:因子在真实系统里长什么样
上面那些说法在代码里是有形状的。看两个开源系统怎么摆这件事,比看十段定义都清楚。
一个因子,在代码里就是一行表达式
qlib 里有一组被叫作 Alpha158 的特征集合,本质是一大串预先写好的表达式。挑最简单的一条看:
"($close-$open)/$open" → 名字叫 KMID
拆开就是「(收盘价减开盘价)除以开盘价」,说人话是「今天这根 K 线,从开盘到收盘涨了百分之几」。就这么一行,它就是一个合格的因子——每只票每天都能算出一个数,而且这个数跨股票可比。
跨股票可比这件事,藏在那个除号里。如果只写 $close-$open,一只三百块的票涨 1% 是三块,一只五块的票涨 10% 才五毛,直接排序会把所有高价股排到前面去——排出来的不是「谁涨得多」,是「谁贵」。除以 $open 之后,量纲(也就是数字背后的单位,这里是「元」)被消掉了,剩下的是纯粹的百分比。
这个手法在那份文件里几乎无处不在。均线、标准差、区间最高价,写完都要再除一次收盘价,源码注释里对此写得很直白:这么做是为了去掉单位。你可以把这条当成因子构造的第一条工程纪律:任何带「元」「手」「股」的原始量,直接拿去横向排序都是错的。
同一份文件里还有些一眼能看懂意图的:
"Mean($close>Ref($close, 1), d)" → 过去 d 天里,上涨天数占比
"Corr($close, Log($volume+1), d)" → 过去 d 天里,价格和成交量的相关程度
"(IdxMax($high, d)-IdxMin($low, d))/d" → 最高点和最低点谁先出现,隔多远
第三条尤其有意思:它算的是「区间最高价出现的位置」减「区间最低价出现的位置」。如果高点在前、低点在后,这个数是负的,源码注释给它的解读是往下的动能。你看,一个模模糊糊的盘感(「它是先冲高再回落的」),被压成了一个能排序的数。这就是因子这件事的全部魅力,也是它全部的风险来源——压缩的过程一定丢东西。
至于滚动窗口取几天(那份配置里默认给的是 5、10、20、30、60 这一组),是可配置项,不是什么神圣常数。别把某个具体窗口当成结论。
有因子还不够,得配一个「要预测什么」
这是新手最容易漏的一环。因子算出来一列分数,然后呢?分数高就一定涨吗?——那得先定义清楚「涨」是指哪一段的涨。
同一份代码里,除了特征还定义了标签(label,就是「你希望模型学会预测的那个东西」):
"Ref($close, -2)/Ref($close, -1) - 1"
Ref(x, -1) 是「往后取一天」。所以这一行是:后天的收盘价,除以明天的收盘价,减一——明天收盘买、后天收盘卖,这一段的收益率。
为什么不是「明天除以今天」?因为因子是拿今天收盘的数据算出来的,你最快也只能明天才动手。今天收盘才知道的信息,不可能用今天的收盘价成交。 这一行代码里的 -1 和 -2,就是这条常识的工程写法。挪成 0 和 -1,回测曲线会立刻变好看,而且不报任何错——这正是前视偏差最典型的入口之一。
记住这个配对关系:因子和标签必须成对出现。 脱离了「预测哪一段收益」,谈一个因子有没有用是没有意义的。同一个因子,对预测隔日收益可能有效,对预测半年后收益可能完全无关。
换个系统,结构长得完全不一样
拿 freqtrade 对照着看,差别一下就出来了。它的策略类里,两个核心方法是这样的:
def populate_indicators(self, dataframe, metadata): ...
def populate_entry_trend(self, dataframe, metadata): ...
第一个函数往数据表里填指标,第二个函数根据这些指标填出「要不要进场」的信号列。注意那个参数 metadata——文档串里说明它携带的是「当前交易的这个品种」的信息。也就是说,这套接口一次只看一个品种,横向比较在结构上压根没有位置。
这不是谁做得好谁做得差,是两种问题的形状不同。加密货币或期货这类语境下,可选标的就那么些,核心难题是「什么时候进出」;A 股这类几千只标的的语境下,核心难题变成「同一时刻挑哪一批」。前者天然长成指标+信号,后者天然长成因子+排序。你在选工具之前,得先搞清楚自己的问题是哪一种。
还有一派:干脆不构造因子
同一个库里还有另一组特征,叫 Alpha360,做法完全相反——它不构造任何有含义的表达式,只是把每只票过去六十天的开高低收、成交量、均价原样铺开,每个都除以最新收盘价做归一化,凑成一大列数字直接喂给模型。
两种哲学的分歧点很清楚:Alpha158 那一派认为「人应该先把领域知识压成有含义的量」,Alpha360 那一派认为「人压缩的时候会丢信息,不如把原始数据交给模型自己找规律」。哪种更好没有定论,但对你理解「因子」这个概念很有帮助——因子是人对市场的一种假设,不是数据本身。 它是人加进去的东西,所以它可能加错。
一个因子要满足什么,才算「有效」
网上随手能搜到几百个因子公式。绝大多数拿来就用会亏钱。下面这几条是筛掉大部分垃圾的最低门槛,按重要性排:
一、它在那一刻真的算得出来。 这一条排第一,因为它是唯一一条「不满足就全盘皆输、且不会报错」的。财报数据的公布日晚于报告期、指数成分名单是今天这一版、停牌期间的价格是补的——任何一处对不齐,这个因子的历史表现都是假的。相关的坑可以看 Point-in-Time 数据 那篇。
二、它跨标的可比。 前面说的量纲问题。带单位的量、受股价绝对水平影响的量、受股本规模影响的量,直接排序都会排出你没想要的东西。
三、它和未来收益的关系是稳定的,而不是碰巧的。 注意「稳定」两个字。一个因子在某三个月里排前面的确实涨得好,这可能纯粹是运气。你需要看的是:换一段时间还成不成立,换一批股票还成不成立,方向会不会翻来覆去。 衡量这件事的常用工具是 IC(因子值和后续收益的相关程度),单独一篇讲,见 IC 与 IR。
四、它得有增量。 你新挖的因子如果和已经在用的某个因子高度相似,那它只是个马甲——加进去不会带来新信息,只会让你误以为多了一重验证。判断方法是看它和现有因子的相关性,而不是看它单独的表现有多好。
五、扣掉交易成本还剩得下。 一个因子如果每天都在大幅变动,意味着持仓天天换,手续费和冲击成本会把收益磨掉。因子的「换手率」和它的收益必须放在一起看,只看收益是自欺欺人。
六、它背后有个说得通的道理。 这一条最软,也最容易被跳过,但它是长期唯一靠得住的护栏。有效因子的理由通常落在三类里:它承担了某种风险所以得到补偿(比如小公司更容易出事,所以要求更高回报);它利用了人的行为偏差(比如人对坏消息反应过慢);它踩住了某种结构性限制(比如某类资金被规则禁止买某类标的)。如果三类都套不上,你手上多半是一个从历史数据里挖出来的巧合。前两类各自有一个被研究得最透的代表:价值因子走的是第一类的补偿逻辑,动量因子则常被归到第二类的行为解释上,想看这套道理具体怎么落到一条公式上,从这两篇入手最省力。
关于「市场到底允不允许存在有效因子」这个更根本的争论,有效市场假说 那篇讲得更细,这里不重复。
「因子」这个词,为什么听起来总是两个意思
如果你查资料时觉得混乱,多半是因为撞上了这个词的两副面孔。它是从学术界跑出来的,跑到实战里的时候意思悄悄变了。
学术那一头,因子最初是用来「解释」的。
早期的资产定价框架只承认一个共同来源:整个市场的涨跌。一只股票的回报,被拆成「跟着大盘的那部分」加「不跟大盘的那部分」。后来研究者发现这个拆法不够用——按公司规模分组、按估值高低分组,各组的长期回报有系统性差异,而单一的市场因素解释不了。于是被拆出来的共同来源多了几个:规模、估值这类维度陆续进场。
请注意这个语境下因子的角色:它是一个用来解释「一群股票为什么一起动」的共同风险来源。 关键词是解释、是风险、是一群。它回答的是「你赚的这些钱,有多少其实只是承担了某种已知风险的报酬」。
实战那一头,因子是用来「预测」的。
到了投资机构手里,这个词被拿去干另一件事:给股票打分排序,选出未来可能涨得好的那一批。关键词变成了预测、是信号、是排序。至于它背后对应哪种风险,很多时候没人深究——好用就行。
这两个用法长期共用一个词,后果是这个池子越来越浑。学术界这些年被批评为「因子动物园」:陆续发表的因子数以百计,其中很大一部分在后来的检验里站不住,被认为是反复筛选历史数据筛出来的产物。而实战这一侧同样的问题只会更严重,因为没有同行评议这道关。
对你的实际意义是:听到「某某因子」时,先分清对方在说哪一种。 如果是解释性的,它在告诉你「你的收益成分是什么」,这是归因问题;如果是预测性的,它在承诺「按这个选能赚钱」,这是需要严格检验的主张。把前者当后者用,是很多人对因子投资失望的起点——一个能很好解释历史回报构成的因子,完全可以对未来没有任何预测力。
「这个因子历史上很有效」这句话,信息量比你以为的低得多。 因子的公式是人从历史数据里挑出来的,挑的过程本身就带着后见之明——试了一百个留下最好的那个,它的历史表现必然好看。真正该问的是三件事:这一百个里落选的那些去哪了、换一段完全没参与筛选的时间它还行不行、它背后那个道理在未来还成不成立。
常见误用
把带单位的指标直接拿去排序。 用成交量排序,选出来的是大盘股;用股价排序,选出来的是高价股。这不是因子在选股,是量纲在选股。
拿因子去解释单只股票。 因子说的是「统计上,这一批相对那一批平均如何」。它对任何一只具体的票都没有承诺。你按因子选出一百只,其中三四十只跌是完全正常的,这不构成因子失效的证据——但很多人会因为其中一只跌了就推翻整套逻辑。
把因子值的绝对大小当成信心强弱。 因子分数是相对的,不是概率。分数是别人两倍,不意味着涨的把握是别人两倍,更不意味着该买两倍的量。仓位是另一个独立问题。
一个因子当一套策略用。 因子只回答「买哪些」,剩下的问题——买多少、什么时候卖、组合整体的风险敞口在哪、成本怎么控——它一个都不回答。把一个因子直接接上下单接口,是新手最常见的翻车方式。
在同一批数据上反复挖到满意为止。 这是所有因子研究的最大陷阱,也是那个「动物园」的成因。你在一段历史上试的次数越多,最后留下的那个越可能只是噪音。防它的办法不在因子本身,在于验证流程——留出完全没碰过的时间段、按时间顺序而不是随机切分数据。
小结
- 因子 = 一条能给范围内每个标的、在同一时刻、算出一个可比分数的规则。它的价值在于把「业绩好」「太贵了」这类没法计算的说法,变成能排序的数。
- 因子和指标的分水岭是方向:指标纵向比(这只票和它自己的过去),因子横向比(同一天所有票之间)。同一个公式换用法就能横跳,问清「你拿它排序了吗」就能分辨。
- 在真实系统里,一个因子就是一行表达式,而且几乎总要除掉某个价格量来消掉单位——带「元」的量不能直接排序。因子必须配一个明确的标签(预测哪一段收益),而且这一段必须严格在未来、且是你真能交易到的那一段。
- 有效的门槛按顺序是:当时算得出来、跨标的可比、关系稳定而非碰巧、相对已有因子有增量、扣掉成本还剩、背后有说得通的道理。第一条不满足,后面全是假的。
- 这个词有两副面孔:学术上它解释「一群股票为什么一起动」,实战里它预测「哪批票更值得买」。解释力强不等于预测力强,混用这两层是失望的主要来源。
一句话记住这篇:因子不是什么高级东西,它就是把你说股票的那句话,改写成一个所有股票都能算出来、还能放在一起比大小的数——改写的时候丢掉了什么,才是真正要小心的地方。
本文所引源码与文档均来自上述快照版本,是阅读代码得出的机制说明,不是运行结果;具体行为请以你手上那个版本为准。回 量化与 AI 投研概念库 看其它概念各自在说什么;本站内容为投资教育,不构成任何投资建议,边界见 免责声明。
本文为投资教育整理,关键数据与结论请结合下列权威来源验证。
- qlib 源码快照 79633dd(2026-07-23):qlib/contrib/data/loader.py(Alpha158DL、Alpha360DL 的因子表达式与注释)、qlib/contrib/data/handler.py(Alpha158 的特征配置与标签定义) ↗
- freqtrade 源码快照 b3404c9(2026-08-18):freqtrade/strategy/interface.py(populate_indicators / populate_entry_trend 接口签名与文档串) ↗
- 资产定价文献通识:CAPM、Fama-French 多因子框架、因子动物园(factor zoo)之争 ↗