halo 的技术博客

返回

多因子投资有个隐藏前提:你决定持有哪几个因子(价值、动量、质量……),永远等权持有它们。但因子不是静止的——价值会沉寂三年、动量会接力领涨、低波会在泡沫里失效。如果「因子」和「股票」一样是一种资产,那它也应该有自己的择时信号

本文的论点:把因子当成可交易的资产,用**因子动量(Factor Momentum)**去配置它们——哪类因子过去走强,就超配以它;走弱就减配。在 25 年(300 个月)合成的 5 个风格因子上,静态等权持有全部因子的 Sharpe 是 0.94;而用过去 12 个月收益做信号的因子动量组合,Sharpe 冲到 2.27、回撤 −17.3%(比静态 −21.2% 还小)。更关键的是,它和共同市场的相关只有 0.18——它赚的是「因子之间轮动」的钱,不是市场方向的钱。

这听起来像把「股票动量」简单搬了一层,但二者有本质区别:股票动量赚的是「别的股票比你还惨/更强」的横截面相对收益;因子动量赚的是「这类风险溢价自身正处在强势 regime」的时间序列状态切换。后者要求因子的风险溢价本身具有可预期的持续性,而不是靠和其他因子比谁更弱。正因如此,因子动量不是截面多空的替代品,而是架在「因子选择」之上的一层独立择时——它和底层因子收益相关却不等于它们,这正是下文 0.72 相关的来源。

五个风格因子的累计净值:轮动明显,有的领涨、有的沉寂

一、为什么因子会有动量#

因子动量成立的前提只有一个:因子的收益是可预测的、且有持续性。这和我们做股票截面动量是一个道理,只是把对象从「股票」换成了「因子」。

我们构造 5 个风格因子的月度收益,每个因子的收益由三部分组成:

  • μ_i:因子的长期漂移(价值、动量各自有不同的正溢价);
  • s_{i,t}:一个 AR(1) 慢变状态(持续性 φ=0.85)——这是因子「时好时坏」的来源,也是动量能捕捉的对象;
  • β_i·M_t + 特异噪声:共同市场暴露与特异冲击。

φ=0.85 意味着因子的「好状态」会持续好几个月——过去 12 个月走强的因子,未来一两个月往往还行。这就是因子动量的燃料。

二、把因子当资产:因子动量组合怎么建#

逻辑和「用过去收益排序选股票」完全对称,只是排序对象是因子自身。每月:

  1. 算每个因子过去 12 个月累计收益,作为信号;
  2. 信号为正的因子纳入多头、等权持有,信号为负的剔除;
  3. 持有 1 个月,下月重算。
LOOK, REB = 12, 1
fm_w = np.zeros((NF, T))
fm_ret = np.zeros(T)
for t in range(LOOK, T):
    sig12 = ret[:, t - LOOK:t].sum(axis=1)        # 过去 12 月累计 = 信号
    longs = sig12 > 0
    w = longs.astype(float) / longs.sum() if longs.sum() else np.ones(NF) / NF
    fm_w[:, t] = w
    fm_ret[t] = float(np.dot(w, ret[:, t]))
fm_ret = fm_ret[LOOK:]
ew_ret = ret.mean(axis=0)[LOOK:]                  # 对照: 静态等权全部因子
python

这里没有任何未来函数:信号只用 t 之前的数据,持仓在 t 月内不变。阈值用「>0」而非「排行前几」,避免人为挑断点——本质是「顺因子的势」。

三、结果:因子动量把 Sharpe 翻了一倍多#

把单因子、静态等权组合、因子动量组合摆在一起:

标的年化波动Sharpe最大回撤
价值 / 动量 / 规模 / 质量 / 低波(单因子)3.7~9.2%13~21%0.22~0.61−55~−87%
静态等权全部因子7.0%7.4%0.94−21.2%
因子动量组合22.0%9.7%2.27−17.3%
50% 动量 + 50% 静态14.3%8.0%1.79−15.5%

因子动量组合 Sharpe 2.27,几乎是无脑等权的 2.4 倍,且回撤更小。这说明「在哪个因子上多下注」这件事,本身就藏着大量未被静态配置利用的 alpha。

Sharpe 对比:因子动量组合高于任一单因子与静态等权

四、它赚的是什么钱:相关结构#

因子动量最妙的地方,是它和市场的低相关。在我们的样本里:

  • 因子动量 vs 静态等权因子组合:0.72(不是 1,说明它不是简单复制底层因子,而是加了「择时」这一层);
  • 因子动量 vs 共同市场:0.18(几乎中性——它赚的是因子之间的轮动,不是市场方向)。

信号本身也站得住脚:12 个月累计收益与下月因子收益的截面相关(IC)均值 0.327,且约 59.7% 的月份信号为正——也就是说,「因子过去强、未来还强一阵」是一个稳定存在的现象,不是噪声。

因子动量组合 vs 静态等权因子组合的净值与滚动相关

权重热力图更直观地展示了「轮动」:每个月被做多的因子在变,没有哪个因子被永久超配——因子动量做的是动态再平衡,而非押注单一风格。

因子动量权重热力图:每月只做多过去 12 月收益为正的因子

五、真实陷阱(诚实版)#

1. 数据是合成的、且校准偏乐观:单因子 Sharpe 0.22~0.61、因子动量 2.27,都是为演示机制选的友好参数。真实因子动量(Ehsani-Linnainmaa-Reibstein 等文献)效应存在,但净 Sharpe 通常更温和,且高度依赖样本期。

2. 过拟合信号窗:本文用 12 个月回望,是「已知答案后选的」。实盘必须样本外确定回望窗,或用多个窗平均,否则会挑出看起来最漂亮、其实过拟合的那个。

3. 因子数量太少会过机动:只用 5 个因子,任何一个月「信号为正的因子」可能只有 1~2 个,集中度高、路径依赖强。真实应用应在几十个因子上做,分散单一因子的 regime 风险。

4. 它是市场状态的影子:因子动量在「因子轮动清晰」的 regime 里赚钱,在「所有因子一起失效」的危机里会同时亏(价值沉、动量破、质量也破)。它不是市场中性,只是低相关。

5. 交易成本与换手:每月调仓、且权重在 0/正之间跳变,换手不低。上面的数字没有扣交易费——实盘要把bid-ask、冲击成本、短期资本利得税算进去,Sharpe 会打折。

6. 与截面动量的混淆:因子动量(对因子收益做时序动量)和「在因子内做截面动量」是两件事。前者配置因子、后者选股,别混为一谈;混了容易把同一份溢价重复计数。

结语#

「把因子本身当成可交易的资产」,听起来只是视角的转换,但落地后收益结构完全不同:静态持有因子,是把因子当常量;因子动量,是把因子当有时好有时坏、且好坏会持续的状态变量。本文用 5 个合成因子证明,仅仅是「顺因子的势」这一层,就能把组合 Sharpe 从 0.94 拉到 2.27,且与市场几乎脱钩。真正的功课不在模型,而在样本外验证信号窗、控制换手、并在多因子维度上分散——否则你只是把「因子择时」这层新的自由度,又过拟合了一遍。一个稳妥的落地起点,是先在大类因子(价值/动量/质量/低波/规模)层面跑通因子动量,确认 IC 稳定为正后,再逐步下沉到更细的子因子,而不是一上来就对着几十个相关性混乱的因子做月度再平衡。

本文图表与全部数字均由 generate_factor_momentum_images.py 用 numpy 从零计算生成(AR(1) 因子状态 + 因子动量组合 + 相关/IC 统计),非占位图。把 ret 换成你真实的因子收益序列,整套代码可直接复用。

因子动量:把因子本身当成可交易的资产
https://blog.halo26812.eu.org/blog/factor-momentum-trading
Author halo
Published at 2026年7月12日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨