因子收益的时序特征:均值回复性、趋势性、波动率聚集效应

聊因子收益的时序特征,其实就是在回答一个问题:因子赚的钱,到底有没有规律可循?

我做了这么多年量化,见过太多人把因子收益当成白噪声。觉得今天赚了明天可能亏,完全随机。但实际跑下来,你会发现因子收益的时序里藏着不少「脾气」。搞懂这些脾气,你才能知道什么时候该重仓,什么时候该收手。

今天咱们就拆开来看三个最核心的特征:均值回复性、趋势性、波动率聚集效应。

1. 均值回复性:因子收益的「弹簧」效应

什么叫均值回复?说白了就是:涨多了会跌,跌多了会涨

因子收益不是随机游走。它像一根弹簧,拉得太长,弹回去的力度就越大。我早期做多因子模型时,发现动量因子连续大涨三周后,第四周大概率会回吐一部分。当时我还以为是数据出错了,后来复盘才发现——这就是均值回复在起作用。

核心逻辑:因子收益在时间序列上呈现负自相关性。今天的收益高,明天的收益倾向于低一些。

为什么会这样?两个原因:

  • 拥挤交易:一个因子表现太好,资金会蜂拥而入,把收益空间迅速吃掉。我见过一个价值因子,连续两个月跑赢基准后,第三个月直接被打回原形。
  • 套利力量:当因子偏离长期均值太远,套利者就会进场。他们不是来抬轿子的,是来「纠偏」的。

嗯,这里要注意:均值回复的周期不是固定的。有的因子几天就回复,有的要几周。我个人习惯用自相关函数(ACF)来观察回复周期。代码很简单:

import statsmodels.api as sm
import pandas as pd

# 假设 factor_returns 是因子日度收益序列
acf_values = sm.tsa.stattools.acf(factor_returns, nlags=20)
# 看前几阶的负相关是否显著
print(acf_values[:5])

如果第一阶自相关系数显著为负(比如 -0.15 以下),那这个因子就有明显的均值回复倾向。这时候你再用它做趋势跟踪,大概率要吃亏。

避坑指南:我曾经犯过一个错——把均值回复性当成「一定会回复」。结果遇到市场风格切换,因子收益偏离均值后直接走了新趋势,我还在傻等回复。记住:均值回复是统计规律,不是数学定理。

2. 趋势性:因子收益的「惯性」效应

和均值回复相反,有些因子表现出明显的趋势性。今天涨了,明天继续涨。这就是我们常说的动量效应

趋势性在因子收益里很常见。比如低波动因子,在熊市里持续跑赢,在牛市里持续跑输。它不是来回震荡,而是沿着一个方向走很久。

我个人习惯用 Hurst 指数来判断一个因子是趋势性还是均值回复性:

  • Hurst > 0.5:趋势性,适合趋势跟踪
  • Hurst < 0.5:均值回复性,适合反转策略
  • Hurst = 0.5:随机游走,别折腾了

代码实现也不复杂:

import numpy as np

def hurst_exponent(ts):
    lags = range(2, 100)
    tau = [np.std(np.subtract(ts[lag:], ts[:-lag])) for lag in lags]
    poly = np.polyfit(np.log(lags), np.log(tau), 1)
    return poly[0] * 2.0

# 计算因子收益的 Hurst 指数
h = hurst_exponent(factor_returns.values)
print(f"Hurst指数: {h:.3f}")

你想想看,如果一个因子的 Hurst 指数是 0.65,那它连续上涨的概率就明显高于随机。这时候你去做均值回复策略,就是逆势操作,胜率自然低。

注意:趋势性不是永恒的。我见过一个因子,Hurst 指数连续三年在 0.6 以上,第四年突然掉到 0.4。原因很简单——市场微观结构变了。所以建议每季度重新计算一次 Hurst 指数,别偷懒。

3. 波动率聚集效应:风险是会「传染」的

这个特征你可能更熟悉。简单说就是:大波动之后跟着大波动,小波动之后跟着小波动

因子收益的波动率不是均匀的。它像天气一样,暴风雨往往是一阵一阵的。我做过一个统计:A股市场里,因子收益的波动率在 80% 的时间里处于「低波动」状态,但一旦进入「高波动」状态,通常会持续 5-10 个交易日。

为什么会聚集?三个原因:

  1. 信息流聚集:重大消息往往扎堆出现。比如财报季,因子收益的波动率会明显放大。
  2. 投资者情绪传染:恐慌和贪婪是会扩散的。一个因子暴跌,会引发连锁反应。
  3. 杠杆和止损:波动率上升 → 触发止损 → 强制平仓 → 波动率进一步上升。这是个正反馈循环。

检测波动率聚集效应,最常用的工具是ARCH 模型

from arch import arch_model

# 拟合 GARCH(1,1) 模型
model = arch_model(factor_returns * 100, vol='Garch', p=1, q=1)
res = model.fit(disp='off')
print(res.summary())

# 看 alpha 和 beta 系数
# alpha 显著:说明过去波动影响现在
# beta 显著:说明波动率有持续性

如果 alpha 和 beta 都显著,那这个因子的波动率就有明显的聚集效应。这时候你再用固定仓位去交易,风险会很大——因为高波动期你的实际风险敞口远高于预期。

我的做法:对于波动率聚集效应明显的因子,我会用「波动率目标化」来调整仓位。波动率高了就减仓,低了就加仓。这样能把风险控制在目标范围内。具体公式:目标仓位 = 基准仓位 × (目标波动率 / 当前波动率)

4. 三者如何协同?一张图说清楚

这三个特征不是孤立的。它们会同时出现在同一个因子上,只是在不同时间尺度上占主导。我画了一张图来展示它们的关系:

因子收益时序特征协同关系图 均值回复性 短期负自相关 趋势性 长期正自相关 波动率聚集 方差时变 时间尺度上的主导关系: • 短期(1-5天):均值回复性占主导,适合反转策略 • 中期(1-3个月):趋势性可能显现,适合动量策略 • 全周期:波动率聚集效应始终存在,影响风险控制 ⚠ 三者可能同时存在,需用多尺度方法分别建模 来源:因子择时模型实战指南

从这张图你可以看到:短期看均值回复,中期看趋势,全程盯波动率。三者结合,才能做出稳健的因子择时决策。

5. 实战中的处理思路

知道了这三个特征,怎么用到实际模型里?我分享几个经验:

  • 均值回复性强的因子:用反转信号做择时。比如因子收益偏离 2 倍标准差以上时,反向开仓。
  • 趋势性强的因子:用移动平均线或 MACD 跟踪趋势。别想着抄底,等趋势确认再进场。
  • 波动率聚集明显的因子:动态调整仓位。高波动期减仓,低波动期加仓。我一般用滚动 20 日波动率作为参考。

一个实用的组合策略:先用 Hurst 指数判断因子是趋势型还是均值回复型,然后用 GARCH 模型预测未来波动率,最后根据波动率调整仓位。这样就把三个特征都纳入了决策框架。

最后说一句:这些特征不是一成不变的。市场在变,因子的「性格」也会变。我每季度都会重新跑一遍这些统计量,看看有没有发生结构性变化。你最好也养成这个习惯。