2123 字
11 分钟

多因子组合:打分、中性化与权重分配

本课目标:学会把多个单因子加工成一个组合信号——包括去极值与标准化、行业/市值中性化、因子合成方法的选择,以及从因子分走到组合权重。

前几课我们逐个检验了单因子。实盘中几乎没有人只用一个因子——单因子波动大、有明显的失效期,多因子组合的意义在于让互相不太相关的信号互补:估值因子失灵的年份,动量或质量可能正好接力,组合层面的体验远好于任何单因子。把散装因子组装成组合,有一条标准流水线:预处理、中性化、合成、落地成权重。本课按顺序过一遍,每一步都说明”为什么要做”和”怎么做”。本文不构成投资建议。

第一步:去极值与标准化#

不同因子量纲完全不同(EP 在 0.05 上下,动量可能是 ±80%),直接相加没有意义,必须先统一到可比的尺度。

去极值(winsorize):截面上少数极端值会主导后续的 z-score,比如一只股票的市盈率因为利润接近零而飙到几千倍,标准化后它一家就能扭曲整个截面的分布。常用中位数绝对偏差法(MAD)设定上下边界并截断,它比”均值 ± 3 倍标准差”更稳健,因为均值和标准差本身就会被极端值污染:

import numpy as np
def winsorize_mad(s: pd.Series, k: float = 5.0) -> pd.Series:
med = s.median()
mad = (s - med).abs().median()
upper, lower = med + k * 1.4826 * mad, med - k * 1.4826 * mad
return s.clip(lower, upper)

标准化(z-score):去极值后,截面上减均值、除标准差,让每个因子都变成均值 0、方差 1 的分布:

def zscore(s: pd.Series) -> pd.Series:
return (s - s.mean()) / s.std()

顺序不能反:先去极值再标准化。缺失值的处理也要定规则——常见做法是行业内中位数填充,或直接不给该股票此因子的打分。两种做法各有代价:中位数填充相当于假设”缺数据的股票是行业平均水平”,会稀释因子区分度;直接不打分则会让不同因子的覆盖股票池不一致,合成时需要额外对齐。无论选哪种,规则要全程统一并写进文档。

对分布严重偏斜的因子(如市值、成交额),还有一个常用变体是排名标准化:先转成截面排名百分位,再映射到正态分布分位数。它完全抹掉了原始分布形态,只保留排序信息,稳健性最好,代价是丢失了”因子值差多少”的强度信息。

第二步:行业中性与市值中性#

动机:很多因子的原始得分里混着行业和市值的”顺风车”。比如低波动因子天然偏好银行、公用事业;很多因子在小盘股上得分极端。如果不处理,你的”多因子组合”实际上是一个行业和市值的押注组合——风险集中,而且你并不知道自己在押。

做法:把因子值对行业哑变量和对数市值做截面回归,取残差作为中性化后的因子:

import statsmodels.api as sm
def neutralize(factor, industry_dummies, log_mktcap):
X = pd.concat([industry_dummies, log_mktcap], axis=1)
X = sm.add_constant(X)
model = sm.OLS(factor, X, missing="drop").fit()
return model.resid # 残差 = 剔除行业与市值后的纯因子

残差的含义是:同行业、同市值水平下,这只股票的因子得分还有多少超额信息。中性化后记得再做一次标准化,让残差回到均值 0、方差 1 的尺度,才能与其他因子合成。

中性化不是免费午餐——它会剔除因子里真实存在的行业选择能力,是否中性化取决于你想不想承担对应的风险敞口。一个实用的判断方法:分别检验中性化前后的因子。如果中性化后 RankIC 大幅下降,说明这个因子的预测力主要来自行业或市值押注,“选股能力”其实很薄;如果基本不变,说明它有独立于风格的增量信息,是更值得保留的因子。

第三步:因子合成——打分法 vs 回归法#

多个标准化后的因子怎么合成一个总分?两条主流路线:

维度打分法(加权求和)回归法(截面回归)
做法总分 = Σ 权重 × 因子 z-score每期用因子暴露回归收益,估出因子收益率,再用其预测
权重来源等权、ICIR 加权、人工设定由回归系数内生决定
优点简单透明、稳健、好调试理论完整,自动处理因子间相关性
缺点忽略因子相关性,权重带主观性对共线性和异常值敏感,估计噪声大

对进阶阶段的建议是从打分法起步:等权合成是极难被打败的基准。ICIR 加权(用各因子历史 ICIR 作为权重)是常见的第一个改进,但要警惕用了太短的窗口去追逐因子的近期表现——因子权重本身也会过拟合,窗口越短、调整越频繁,样本外掉链子的概率越大。

因子相关性与冗余#

合成前必须检查因子间的截面相关性。两个相关系数很高的因子(比如低波动与低换手)同时等权放入,等于给同一个信号加了双倍权重,组合的分散化是虚假的。

实用检查清单:

  • 计算因子两两的截面 RankIC 式相关(每期截面相关取时序均值);
  • 相关系数明显偏高的因子对,考虑只保留检验表现更好的一个,或先合并成一个”家族因子”再参与总合成;
  • 新因子入库前,对存量因子做正交化检验:把新因子对老因子回归,看残差是否还有 IC。残差没有预测力,说明新因子只是老因子的换皮。

从因子分到组合权重#

总分只是排序,还要落地成”每只股票买多少”。由简到繁的三种方案:

  1. 分位数等权:取总分最高的前 10% 或前 N 只,等权持有,定期调仓。最简单,也是检验因子分质量的基准做法;
  2. 打分加权:权重正比于总分(或总分的秩),分数越高买越多,注意设置单票权重上限;
  3. 优化器方案:把因子分作为预期收益输入组合优化器,同时施加风险和交易约束——这是下一课的主题。

无论哪种方案,都要在回测里叠加换手率统计和交易成本假设。多因子组合的换手率由变化最快的那个因子主导,合成时给高换手因子降权是控制成本的常用手段。另一个降换手的技巧是设置缓冲区:股票掉出前 10% 但仍在前 15% 时暂不卖出,只有跌出缓冲带才调仓。排序边缘的小幅抖动是换手的主要来源,缓冲区能以很小的信号损失换来可观的成本节约。

本课小结#

  • 流水线顺序:去极值 → 标准化 → 中性化 → 合成 → 落地权重,每一步都有明确动机;
  • 行业与市值中性化的本质是剥离你不想押注的风险敞口,剥不剥取决于你想承担什么;
  • 等权打分是极强的合成基准,任何花哨的加权方法都应先证明能稳定胜过它;
  • 高相关因子共同入选会造成虚假分散,新因子必须通过对老因子的正交化检验;
  • 从因子分到权重,从分位数等权起步,成本与换手要纳入评价。

动手练习:选两个前几课检验过的因子(如 20 日反转 + EP),完成整条流水线:MAD 去极值、z-score、行业市值中性化、等权合成,然后做 5 组分层回测,对比合成因子与两个单因子的 RankIC 与单调性,观察合成是否带来了改进。