市场状态感知因子:方法论与实现指南(以动量 & 波动率为例)
  长长的尾巴 6天前 220 1

市场状态感知因子:方法论与实现指南(以动量 & 波动率为例)

前言

  • 上一篇《自适应市场状态感知因子的构建》的文章中,我们提出了在因子层面构建市场状态感知因子的思路,不同于在模型层面对因子权重动态调整的因子择时方法,我们的设计思路希望在因子构建层面能够动态感知市场状态的变化。本篇研究继续上篇文章的思路,构建方法层面更加严谨,特别是动量因子及其线性组合形式的衍生因子,可以参照CAMP形式的构建方式构建具备市场动量感知的因子。虽然不是严格的数学推到,但是也尽量从逻辑层面尽量严谨。本篇主要以动量因子为例,并使用qlib的进行结果验证和分析,在进行不同股票池组合和参数(20日动量对未来5日收益,5日动量对未来1日收益)分析,结果显示,市场动量感知的因子相对于原始动量因子,RankIC,RankIC_IR及T检验结果都明显得到提升。

0. 摘要(TL;DR)

  • 目标:在截面上构建能感知市场状态(趋势、波动、流动性、广度等)的交易因子,兼顾区分度稳健性
  • 核心做法:将个股信号 Sᵢ,ₜ 与市场级状态信号 Sₘ,ₜ 建立耦合刻画(线性回归β或非线性互信息 MI),把信号拆为:
  • 残差分量(去市场化的纯个股成分)
  • 状态分量(耦合强度 × 市场状态)
    融合后得到最终的状态感知因子
  • 动量(线性):CAPM 形态线性结构可“传递”;强烈推荐用回归β + 残差化 + 状态项。
  • 波动(非线性):用 log σ 的弹性(γ)互信息刻画耦合;“低特异波 + 状态惩罚/门控”更稳。
  • 合成:最简单有效的基线是 等权合成z(残差) + z(状态分量),无需调参。

1. 基础原理与术语对齐


1.1 由 CAPM 推得的“线性动量—市场动量”关系

目标:用 CAPM 的原理解释——当“动量”被定义为对收益的同一线性滤波时,个股动量市场动量之间存在与 CAPM 同形(或严格一致)的线性关系;据此引入“市场动量 β”构建市场状态感知的动量因子在原理上与 CAPM 一致/相似

假设(A)
  • A1(CAPM 基式):对超额收益(省略 Rf)有

  • A2(线性滤波):定义线性动量为对收益的同一线性算子 L(固定权重,不依赖数据)

(例如“12–2”动量:𝒦=\2,dots,12\,wₖ=1;或 EMA‐mom 等。)

  • A3(稳定性):在用于估计的滚动窗口内,α_i,βᵢ 可视为常数(或缓慢变化)。
  • A4(弱条件独立):\ε_i,t\ 对市场收益 \Rₘ,ₜ\ 不相关;线性算子 L 与收益过程独立。
命题(P)

在(A1–A4)下,对任意确定性的线性算子 L,存在

其中

证明要点(略):线性算子可穿透到和式内:

即得 Sᵢ,ₜ=aᵢ+βᵢ Sₘ,ₜ+uᵢ,ₜ。由(A1,A4)有 Cov(uᵢ,ₜ,Sₘ,ₜ)=0。

推论(C1:回归等价)

用 OLS 在滚动窗内回归

得到的斜率估计 b̂_i 在大样本下一致收敛于 βᵢ;截距 â_i 收敛于 aᵢ。

注:若使用超额收益且 Σₖ w_k=0(零和权重,如差分型滤波),则 aᵢ=0。

推论(C2:与 CAPM 的一致/相似性)
  • CAPM 期望收益:E[Rᵢ]=α_i+βᵢ E[Rₘ]。
  • 线性动量的期望:E[Sᵢ]=aᵢ+βᵢ E[Sₘ]。
    两式形式一致:把“收益—市场收益”替换为“线性动量—市场线性动量”,斜率仍为 βᵢ。因此,以 βᵢ 刻画个股对市场动量的敏感度,在原理上与 CAPM 对收益的敏感度刻画一致/同形
在此基础上的状态感知动量因子
  • 残差动量(纯个股成分)

  • 状态分量(市场状态映射到截面):取市场动量的标准化值 Mₜ=z(Sₘ,ₜ),令

由于 b̂_i 在截面上异质,当 Mₜ 显著(强趋势/强反向)时,Cᵢ,ₜ 给予“顺/逆周期”个股差异化打分。

  • 合成(零参基线)

这与条件 CAPM/条件因子模型相似:在给定状态 Mₜ 下,暴露 βᵢ 把市场状态投射到个股层面;同时保留“与市场近似正交”的残差成分用于截面区分。

边界与注意
  • βᵢ 时变:若 βᵢ(t) 在窗内快速变动,则 b̂_i 估计的是“加权平均 β”;可用短窗+收缩/Kalman 滤波平滑。
  • 非线性信号(如 RSI、波动率):不满足线性算子条件,上述同构不再成立;此时宜用“因子收益回归”或“互信息/非参条件期望”刻画耦合。
  • 指数由成分构成:为防机械相关,构造 Sₘ,ₜ 时对每只股票使用 leave-one-out 版本。
  • 截距项:除非在窗内去均值或选 Σ wₖ=0 的滤波,否则必须保留截距,避免把均值差错压进斜率。
  • 统计推断:动量窗重叠带来自相关,标准误宜用 HAC/Newey–West

小结
当动量被定义为对收益的同一线性滤波时,个股动量—市场动量满足与 CAPM 同形的线性关系,其斜率即个股的市场动量 β。据此构造的“残差动量 + β×市场状态”的状态感知动量因子,在原理层面与(条件)CAPM 的敏感度—溢价刻画保持一致/相似的逻辑结构。

1.2 非线性信号

  • RSI、波动率(涉及平方/开方/比值)、ATR 等属于非线性不保留上述线性同构。
  • 可改用:
    • 因子收益回归(收益对“可交易因子收益”的回归);
    • 互信息/非参条件期望刻画耦合强度与去市场化。

1.3 β、相关系数 ρ、互信息 MI

  • βᵢ=Cov(Sᵢ,S_m)/Var(Sₘ)(含截距);边际敏感度,有方向与尺度
  • ρᵢ=Cov(Sᵢ,S_m)/(σᵢσₘ);无量纲依赖强度,难以残差化。
  • 互信息 I(Sᵢ;Sₘ)≥ 0;连续情形无固定上界,常用归一化 NMI ∈[0,1]

2. 状态感知因子的统一构造框架

输入:个股信号 Sᵢ,ₜ、市场状态信号 Sₘ,ₜ(同频率/同口径;指数建议用 leave-one-out 版本)。

  1. 耦合估计(滚动,仅用历史样本)

    • 线性:Sᵢ,τ=aᵢ+bᵢ Sₘ,τ+uᵢ,τ⇒ â_i,b̂_i。
    • 非线性:估计 NMIᵢ;或非参回归得 Ŝ_i|m,t=E[Sᵢ|Sₘ]。
  2. 两路分量(当期 t)

    • 残差分量:线性 Uᵢ,ₜ=Sᵢ,ₜ-â_i-b̂_i Sₘ,ₜ;非线性 Uᵢ,ₜ=Sᵢ,ₜ-Ŝ_i|m,t。
    • 状态分量:Cᵢ,ₜ=b̂_i(t)· Mₜ;或 (1-lambda NMIᵢ)· Sᵢ,ₜ· g(Mₜ)。
  3. 融合与后处理

    • 零参基线(推荐)F = z(U) + z(C)(等权);或门控 z(U) + min(1, |z(M)|)*z(C)
    • Winsorize(截面 1%/99%)→ z-score(逐日)→ 行业中性(逐日哑元回归)。

评估:整体与分状态桶的 IC/RankIC、滚动稳定性、与基准/FF 因子正交性、交易可实现性(T+1、涨跌停、冲击成本)。


3. 动量因子:线性模型的状态感知实现(示范)

3.1 信号定义(线性动量)

  • 个股:Sᵢ,ₜ=Σₖ=₂₂^252 Rᵢ,ₜ-ₖ(近似 12–2,跳过最近 1 个月)。
  • 市场:同窗同权重构造指数信号 Sₘ,ₜ。

3.2 耦合估计(含截距)

  • 窗口:日频 252 天 / 月频 36–60 月。
  • 推断:重叠窗 → HAC/Newey–West。
  • 截距项必要:避免 β 偏误。

3.3 残差与状态分量

  • 残差动量:Uᵢ,ₜ=Sᵢ,ₜ-â_i-b̂_i Sₘ,ₜ。
  • 市场状态:Mₜ=z(Sₘ,ₜ)(或其他维度的综合状态)。
  • 状态分量:Cᵢ,ₜ=b̂_i(t)· Mₜ。

3.4 融合与后处理(零参基线)

3.5 参考实现

  • 脚本:state_aware_momentum_demo.py state_aware_momentum_20d_csi300.ipynb
  • 产出:使用qlib框架分析
universe mode factor RankIC_mean RankIC_std RankIC_IR NW_t
csi300 W20_H5 Raw -0.0139653977976278 0.2068022966771483 -0.067530187149856 -1.356607554290438
csi300 W20_H5 State -0.0203683130708901 0.217624600937486 -0.0935937986015701 -1.747277870589656
csi300 W5_H1 Raw -0.0123293163115737 0.2067349330720816 -0.0596382823568327 -2.271284119850466
csi300 W5_H1 State -0.0146931821223685 0.2257955564110997 -0.065072946323253 -2.3597968703572527
csi500 W20_H5 Raw -0.0223919813592998 0.1835834587540075 -0.1219716716924042 -2.3911226262704286
csi500 W20_H5 State -0.0294257836685261 0.1973470005486626 -0.1491068198995516 -2.722705323714508
csi500 W5_H1 Raw -0.0152123269165847 0.1799970316763168 -0.0845143210135853 -3.1243417967709197
csi500 W5_H1 State -0.0194024112111173 0.2045190746849085 -0.0948684676038632 -3.224777842358672
csi1000 W20_H5 Raw -0.0392538908078415 0.1615883415025022 -0.242925265788644 -4.863811863661362
csi1000 W20_H5 State -0.0391027833587333 0.1795817536498932 -0.2177436324347677 -3.96008297408208
csi1000 W5_H1 Raw -0.022638661810779 0.1682451559729561 -0.1345575846143112 -5.167444084613214
csi1000 W5_H1 State -0.0241283614337777 0.2015436883807983 -0.1197177724969955 -4.063402400113424

-结果分析:对比各分组测试结果,使用市场状态感知的动量因子相对于原始动量因子,器RankIC_mean明显提升,RankIC_IR同样有明显提升,且统计有效性NW_t检验的结果保持稳定,部分分组结果也有提升。市场状态感知的动量因子相对于原始动量因子有更好的表现。


4. 波动率因子:非线性场景的状态感知

4.1 信号定义(建议 log 变换)

  • 个股波动:实现方差/标准差、GK/Parkinson 等;令 Sᵢ,ₜ=log σᵢ,ₜ。
  • 市场波动:同口径 Sₘ,ₜ=log σₘ,ₜ。

4.2 耦合刻画

  • 弹性(波动β):Sᵢ,τ=cᵢ+γ_i Sₘ,τ+uᵢ,τ⇒ γ̂_i。
  • 互信息:NMIᵢ(Sᵢ,S_m) 捕捉非线性耦合。

4.3 构造与方向

  • 残差波动:Uᵢ,ₜ=Sᵢ,ₜ-ĉ_i-γ̂_i Sₘ,ₜ。
  • 状态变量:Vₜ=z(Sₘ,ₜ) 或高/低波档位。
  • 交易倾向:常用偏好低特异波高波期惩罚高耦合


5. 市场状态变量库(选哪个,就感知哪个)

  • 趋势:指数动量 z-score、TSMOM 收益。
  • 波动:log σₘ、VIX/中证波动率的 z-score。
  • 流动性:换手率/成交额 z-score、Amihud(取负)。
  • 广度:上涨家数占比、%成份股站上 MA、AD Line。
  • 相关性/单因子主导:平均两两相关、PCA 第一主成分解释度。
  • 合成状态:对以上标准化后做 PCA/加权得 Mₜ。

注意:指数由成分构成时,个股耦合估计应使用 leave-one-out 的 Sₘ,ₜ^(-i)。


6. 合成权重:不调参也能稳的三种方式

  1. 等权(零参基线,推荐)
    F=z(U)+z©。

  2. 状态强度门控
    F=z(U)+min(1,|z(M)|) z©。

  3. 表现驱动(轻量自适应)
    用过去 W 期各自的 RankIC 或反波动做权重:
    F=wU z(U)+wC z©,其中 wU,w_C 由历史窗归一化。


7. 评估与回测清单

  • IC/RankIC:整体与“高/低趋势、高/低波”状态桶。
  • 分组单调性:按分位构组合,观察收益曲线与换手。
  • 稳定性:滚动 12M IC、状态切换鲁棒性。
  • 正交性:对 MKT、SMB/HML/行业做回归,关注 α 与系数显著性。
  • 可实现性:T+1、涨跌停、调仓频次/滞后、冲击成本,设置换手上限。

8. 实操细节与常见坑

  • 截距项要保留(或在窗内先去均值再过原点,等价)。
  • 仅用历史数据估计(滚动窗截断到 t-1),避免泄露。
  • 重叠窗口 → 显著性用 HAC/Newey–West;MI 用 block-permutation 做显著性。
  • 收缩与平滑:对 b̂_i,γ̂_i 做行业层面 James–Stein 收缩或指数平滑。
  • 极端市场日:限制 |z(M)| 或剪裁状态项,防过度放大。
  • 数据处理:缺失值/停牌填充、涨跌停对收益与可交易性的影响。

9. 极简伪代码(动量线性版)

# 构造线性动量(12–2 近似) S_i = rolling_sum(returns_i.shift(21+1), window=252-21) S_m = rolling_sum(index_ret.shift(21+1), window=252-21) # 滚动β与截距(协方差/方差闭式) beta_i, intercept_i = rolling_ols_via_covvar(S_i, S_m, window=252) # 残差与状态分量 U = S_i - intercept_i - beta_i * S_m M = zscore_over_time(S_m) # 市场趋势状态 C = beta_i * M # 等权合成 + 行业中性 F = zscore_xs(winsorize_xs(U)) + zscore_xs(winsorize_xs(C)) F = industry_neutralize_xs(F, industry_labels)
最后一次编辑于 6天前 1

13917126236

非常好的思路,我想跟你讨论一下,微信号:SBQuant,我研究状态模型很多年了。

2025-09-14 09:20:30      回复

推荐阅读