跳转至

M06 因子研究方法论

层级:L2 因子投资 | 优先级:★★★ | 预计学时:14 小时 对应原书:因子 第 2 章;陈 7.4 前置知识:M01 的回归与 Newey–West;M05 的 α = β′λ 残差。 读书笔记:因子第 2 章的排序与 IC · 陈 7.4 状态:reviewed 数据截至:2026-08|最近复核:2026-10-22


学习目标

  1. 用排序法说明一个特征有没有单调的下期收益差,并同时报告市值加权和等权。
  2. 分清时序回归估计的是暴露和截距,Fama–MacBeth 估计的是特征的溢价序列。
  3. 手算一个月的 Spearman 秩相关,以及 IC 均值 0.03、标准差 0.12、120 个月时的 t 值。
  4. 把 French 动量十分位的多空、三因子截距和 1932、2009 的单月跌幅算在同一份 202608 文件上。
  5. 知道全样本 t = 4.92 和 1991–2025 的 t = 1.75 可以同时为真。检验工具服务 M14 的归因,不直接变成下单清单。

本章知识拓扑图

flowchart TB
    CHAR["月末已知道的特征"] --> SORT["分组,下一月才计收益"]
    CHAR --> FM["每月截面斜率"]
    CHAR --> IC["与下一月收益的秩相关"]
    SORT --> LS["高减低,等权和市值加权各一条"]
    LS --> TS["对已知因子做时序回归,读截距"]
    FM --> PREM["斜率的时间序列均值和 t 值"]
    IC --> IR["基本定律里的 IC,还要乘广度"]
    TS --> DECIDE["截距离开 0,仍可能是成本、借券或又一个风险"]

特征的日期必须早于收益的日期。排序、截面斜率和秩相关是三种读法,不是三个可以挑最好看的那一个再发表。


🟢 入门层:三种问法

1. 有效指的是哪一个差

一个特征值得继续看,是指:按当时已经知道的值排序,未来一段时间的平均收益随组别变化,这个差不会被换一种加权或换一段窗口轻易抹掉,而且对已经用上的因子做回归之后截距仍离开 0。三条都要写。只满足第一条的,常常是小盘股或一段行情。

方法 问题 它不回答的事
排序 高组比低组多多少收益,组别是否单调 同时控制好几个特征
Fama–MacBeth 控制其他特征后,这个特征每增加 1,下期收益增加多少 关系若不是线性,斜率会失真
秩相关 IC 排序和未来收益的相关性有多稳 不直接等于组合收益

2. 排序的七步

以「低市盈率」为例,动量只是把第 2 步换成过去收益。

  1. 股票池用形成日当时的名单。今天的指数成分会丢掉后来退市的公司(M03)。
  2. 特征只用形成日已经披露的数据。市盈率用当时可见的利润,不用后来修订的利润。
  3. 按特征值分组。股票少于大约 300 只时,五组比十组稳。Fama–French 用 NYSE 的分位数做断点,避免微小市值占满极端组。
  4. 组内收益用下一期,不用当期。等权和市值加权都算。
  5. 多空是最高组减最低组。哪一边做多要事先按经济含义定,不能看完收益再决定。
  6. 多空月均的 t 值用 Newey–West 再报一次。从低到高看平均收益是否单调。
  7. 多空对已经承认的因子做时序回归。截距仍离开 0,才谈得上这个模型里的增量。

Jegadeesh & Titman (1993, JF 48(1)) 用过去收益排序。Kenneth French 库把排序变量写成形成月之前的第 12 个月到第 2 个月,最近一个月不进排序,用来躲开短期反转。本章第 9 节的数字是这套定义。


🟡 进阶层:公式、手算和预处理

3. 断点、加权和双重排序

选择 本章采用的报告方式
组数 French 动量文件是 10 组。小股票池改用 5 组,并写明
断点 研究组合常用 NYSE 分位数。全样本分位数会让微小市值挤进两端
加权 市值加权和等权并列。只在等权下出现的差,先怀疑小盘
频率 月频排序配月频持有。持有期长于调仓期间隔时,收益重叠,iid t 偏大
时点 特征滞后到披露之后。不知道披露日,就整季后移

独立双重排序是 Fama & French (1993, JFE 33(1)) 构造 HML 的办法:先按市值分两档,再按账面市值比分三档,断点用 NYSE。它回答的是「这个特征在大盘和小盘里是否都在」。先按市值分组再在组内排序,是条件排序,两种不要混名。

4. 时序回归读截距

时序回归是给单个组合连续拍十年纪录片:每月一个点,斜率是 β,截距是这组因子没解释的月均 α。 它回答的是这一条净值,不是全市场每个特征当月值多少钱。 横排对比照和十档会审留在下一节:一个是特征溢价 γ,一个是截距是否同时为零。 三句不要合成一个折扣。

R_(p,t) − R_(f,t) = α + β₁ Mktₜ + β₂ SMBₜ + β₃ HMLₜ + εₜ.

左边是组合的超额,不是原始收益。右边的因子在 French 文件里,Mkt 已经是超额,SMB 和 HML 是多空,不再减 R_f。α 是这组因子没解释的月均。β 是暴露。

多个组合的截距是否同时为 0,用 Gibbons, Ross & Shanken (1989, Econometrica 57(5)) 的统计量。T 个月、N 个组合、K 个因子,ˆα 是截距向量,ˆΣ 是残差协方差除以 T − K − 1,ˆμ 和 ˆΩ 是因子均值和协方差(协方差分母 T − 1):

GRS = (T − N − K) / N ˆα′ˆΣ⁻¹ˆα / (1 + ˆμ′ˆΩ⁻¹ˆμ).

零假设下它服从 F(N, T − N − K)。一个多空的 t 值显著,不代替这一个联合检验。十个十分位可以只有两端有差,中间组别的截距仍会把 GRS 推高。

5. Fama–MacBeth 的两步

Fama–MacBeth 是每月给全市场拍一张横排对比照,先读出这一期的特征溢价 γ,再把各期 γ 求平均。 GRS 是把十档组合的残差放在一锅里会审:单个 t 值过线,不代替截距是否同时为零。 纪录片、横排照和会审问的是三句不同的话,系数不能互相填。 时序回归的 α 是一条组合的月均残差。这里的 γ 是全市场特征在各期的平均价格。

Fama & MacBeth (1973, JPE 81(3)):

每个月用当天已知的特征解释下一月收益,得到一条斜率。斜率的时间序列均值是溢价估计。T 个月、斜率样本标准差用 T − 1 时,

t = ¯γ / (s_γ/√T).

斜率若自相关,再把分母换成 Newey–West 标准误。点估计仍然是 ¯γ。

两期手算。 三只股票,特征 x = (1, 2, 3),两期的下月收益分别是 (0.01, 0.02, 0.06) 和 (0.03, 0.03, 0.00)。

第一期 ¯x = 2,¯y = 0.03。离差乘积 0.02 + 0 + 0.03 = 0.05,Σ(x − ¯x)² = 2,斜率 0.05/2 = 0.025。

第二期 ¯y = 0.02。离差乘积 −0.01 + 0 − 0.02 = −0.03,斜率 −0.015。

¯γ = 0.005, s = √0.0008 = 0.02828, t = 0.005 / (0.02828/√2) = 0.25.

均值是正的,t 只有 0.25。两期截面回归说明步骤,不说明特征有价格。

时序回归 截面回归
已知的自变量 因子组合的收益 个股特征或暴露
估计出来的 这只组合的 β 和 α 每个月的溢价 γₜ
用来做 策略或新多空还剩多少截距 这个特征在控制其他变量后还有没有斜率

6. 秩相关

Spearman 秩相关是把两边换成秩之后的 Pearson。默认环境没有 scipy,所以不要调用 method="spearman"。

五只股票,一个月。 特征 1, 2, 3, 4, 5,下月收益 0.01, −0.02, 0.03, 0, 0.04。特征的秩就是 1 到 5。收益从小到大的秩是 3, 1, 4, 2, 5。两边秩的均值都是 3。离差乘积 0 + 2 + 0 − 1 + 4 = 5,离差平方和都是 10。

Rank IC = 5/10 = 0.5.

一个月的 0.5 不是因子质量。质量看一整条 IC 序列。

月度 IC 均值 0.03、标准差 0.12、T = 120:

ICIR_月 = 0.03/0.12 = 0.25,

ICIR_年 = 0.25 √12 = 0.866,

t = 0.25 √120 = 2.74.

年化 ICIR 把月度比值乘 √12,假定 IC 在月份之间独立。信号窗口重叠时这条假定偏松,收益序列上的 Newey–West 就是在处理这件事。t = 2.74 使用的是 IC 的样本标准差,分母已经是 T − 1 那种样本标准差再除以 √T。

Grinold (1989, Journal of Portfolio Management 15(3)) 的基本定律把信息比写成 IC 乘广度的平方根。M00 里还有换手系数 TC,个人账户做不了空头时 TC 小于 1:

IR ≈ TC × IC × √BR.

IC = 0.03、TC = 1 时,若把 500 只股票每个月都当成独立赌注,BR = 6000,IR ≈ 2.32。若一年只有 500 个独立赌注,IR ≈ 0.67。50 只股票、每月独立,是 0.73。2.32 使用了「月份之间独立」和「TC = 1」。重叠信号、印花税和借不到券把实际信息比压到这条上界下面。低 IC 仍然可以有用,前提是广度是真的独立赌注,而且成本盖得住。

动量 Plus 实验室在 47 只全程都在的大盘股上,45 个季频持有期的 12-1 秩相关均值是 0.0086,t = 0.21(rank_ic_summary.csv)。这是事后存活的小股票池,不是 French 的十分位。t = 0.21 说明这张池子里的季频排序没有稳定的秩相关。

7. 去极值、标准化、中性化

步骤 做法 为什么
缺失 形成日没有披露的股票不进当月排序 用行业中位数填利润,会把没披露写成已披露
去极值 本节用中位数 ± 5 × MAD,MAD 是离差绝对值的中位数 一只极端值会主导 Pearson 和最小二乘
标准化 当月截面 z 分数或秩 不同特征才能相加
中性化 对行业哑变量和对数市值做截面回归,留下残差 低市盈率若集中在银行,多头就是行业仓

五数手算。 特征 1, 2, 3, 4, 100。中位数 3。绝对离差 2, 1, 0, 1, 97,其中位数是 1。界限是 3 ± 5,即 [−2, 8]。100 被截成 8。有的库先把 MAD 乘 1.4826,让它在正态分布下接近标准差,再取 3 倍或 5 倍。那种界限和这里的 5 × MAD 不是同一个数。本章的例子用未放缩的 MAD。

中性化是当月截面上的正交投影,残差和行业哑变量、对数市值的点积为 0。它不使用下月收益,所以不是前视。它会把「通过行业赚钱」从特征里拿掉。若你的经济故事本来就是行业配置,不要做这一步,然后把变弱的 IC 解释成因子失效。

8. 正交化

新特征 z = (1, 2, 3, 4),已有特征 x = (1, 1, 2, 2)。¯x = 1.5,¯z = 2.5。斜率 2/1 = 2,截距 2.5 − 3 = −0.5。拟合值 1.5, 1.5, 3.5, 3.5。残差

−0.5, 0.5, −0.5, 0.5.

残差和 x 的样本相关为 0。再用残差做第 2 节的排序或第 6 节的秩相关,问的是增量而不是重复。四点残差的相关为 0 只说明投影做对了,不说明增量有经济价值。

时序上的对应物是第 4 节:新多空对旧因子回归,看截距。Novy-Marx (2013, JFE 108(1)) 的毛利资产比与账面市值比负相关,两套特征一起用时投资机会集变宽。那是论文里的组合结果。本章不另报一个未从原文表抄出的相关系数。

陈 7.4 用主成分把收益拆成共同部分和残差,服务的是风险和均值回复的风险模型(M11)。主成分因子没有公司特征的名字。它不能代替「这个特征有没有下期溢价」的排序检验。


🔴 深入层:French 动量十分位

9. 同一份文件上的十组

数据是 Kenneth French 库的 10_Portfolios_Prior_12_2 和 F-F_Momentum_Factor,文件头写明 202608 版 CRSP。月频 1927-01 至 2026-08,1196 个月。排序变量是形成月之前第 12 个月到第 2 个月。只读月频块。算术年化是月均乘 12,不是 CAGR。t 值的标准差分母是 T − 1。Newey–West 滞后 L = ⌊4(T/100)^(2/9)⌋,全样本 L = 6。脚本是 plot_momentum_sorts.py。

市值加权十组的算术年化,从低到高:

1 2 3 4 5 6 7 8 9 10
4.63% 8.97% 9.62% 10.86% 11.36% 11.80% 12.32% 13.47% 14.05% 18.24%

等权十组:10.67%、13.33%、13.40%、14.49%、14.57%、15.68%、16.00%、17.14%、18.38%、20.79%。两组都单调。等权的两端都更高,多空更窄。

组合 算术年化 iid t NW t 一阶自相关
市值加权,高减低 13.62% 4.92 5.14 0.062
等权,高减低 10.12% 3.85 3.97 0.013
Mom(NYSE 30/70,大小市值各半) 7.35% 4.51 4.64 0.0699

十分位高减低比 Mom 更极端,所以年化更高。Mom 才是很多回归里用的那个动量因子。把 13.62% 说成「动量因子的溢价」会和 7.35% 的文献序列对不上。

这一张表里,等权多空比市值加权更窄,两条 t 值都离开 0。不能用它证明「异象只活在等权里」,也不能用它否定 Hou, Xue & Zhang 对其他异象的微盘警告。那是另一组 452 个变量上的结论,见第 10 节。

市值加权高减低对 Mkt-RF、SMB、HML 回归:月截距 1.697%,经典 t = 8.36,HAC t = 9.11。斜率是 −0.37、−0.27、−0.738。三个斜率都是负的,所以截距高于多空本身的月均(13.62% / 12 ≈ 1.14%)。负的价值暴露和 2009 年价值反弹时动量多空大跌是同一方向。十个十分位超额收益的 GRS 是 7.65,T = 1196,F(10, 1183) 的 5% 临界值接近自由度无穷时的 1.83。联合检验拒绝「十个截距同时为 0」。

分窗口的市值加权高减低:

窗口 月数 算术年化 iid t NW t
1963-07 至 1990-12 330 20.41% 5.73 5.84
1963-07 至 2026-08 758 14.07% 4.39 4.35
1991-01 至 2025-12 420 8.57% 1.75 1.74

从 1963 年 7 月一直算到样本末,t 值仍是 4.39,因为窗口里含着 1963–1990 的 20.41%。只保留 1991–2025,t 值是 1.75。旧讲义里「1963 年以后 t 仍高于 3」依赖前一段仍留在样本里。两句都要报。

左:十组算术年化,市值加权与等权。右:高减低的累计倍数,未扣成本。

右图是自融资多空的连乘。1932-08 市值加权高减低为 −77.66%。这条曲线的最大回撤是 −95.56%,高点 1932-05,低点 1939-09。等权最大回撤 −99.28%,低点也在 1939-09。全样本 t = 4.92 和一次接近清零的回撤同时成立。杠杆账户挨不到右图的末端。

这些收益没有扣价差、冲击和借券。空头在个人账户里经常借不到。港股印花税打在成交额上,月频换仓的多空比这张研究曲线更薄。最高组 18.24% 是原始收益,含市场,不是把 13.62% 加到指数上。

仓库里的 XsMomentumStrategy 用的是另一条窗口:TR(m − 1) / TR(m − 13) − 1,跨度 12 个月,结束于上一个月。French 的 prior 是 11 个月,从 −12 到 −2。两条不要当成同一个信号。实验室季频秩相关接近 0,和 French 十分位的 t = 4.92 回答的也不是同一个股票池。

import pandas as pd

# 索引 t 是持有月。French 的排序用 t-12 到 t-2,不含 t-1。
# shift(2)/shift(13) 在 t 上只用到 t-2 及更早的价格,持有月收益尚未发生。
signal = monthly.shift(2) / monthly.shift(13) - 1
held = monthly.pct_change()
# 秩相关不用 scipy。Spearman 是秩的 Pearson。
left = signal.rank(axis=1)
right = held.rank(axis=1)
rank_ic = left.corrwith(right, axis=1)

若再把 held 做 shift(-1),会多跳一个月,和 French 文件的持有月错位。XsMomentumStrategy 的 12 个月窗口也不要写进这个 shift(2)。

10. 复制研究给检验设的门槛

Hou, Xue & Zhang (2020, RFS 33(5)) 用 NYSE 断点和市值加权处理微盘,检验 452 个异象的高减低。其中 65% 的 |t| 到不了 1.96,交易摩擦一类里 96% 到不了。把门槛放到他们使用的多重检验值 2.78,失败比例升到 82%。即便留下的异象,幅度也小于最初的报告。这是那套程序下的失败率,不是「任何 t 低于 2.78 的策略都应该丢弃」的项目规则。docs/workflow.md 的现行门槛以该文件开头为准。

Jensen, Kelly & Pedersen (2023, JF 78(5)) 在和上述原始收益检验更可比的美国样本里,复制率是 55.6%,对应 Hou 等人大约 35% 的通过率。他们改用截距、去掉原文本来就不显著的因子,并用贝叶斯多重检验之后,复制率到 82.4%。82.4% 不是 55.6% 的同一定义。两篇论文的张力在于样本、加权和「什么叫复现」,M08 再展开。本章只要求:报告你实际用的加权、断点和窗口,不要只留 t 值最大的那一次。

GMM 可以同时估计随机折现因子的矩条件。因子第 2.7 节有介绍。个人研究的日常输出仍然是排序、Fama–MacBeth 和秩相关。截面斜率 γ 也可以看成一个对目标特征暴露为 1、对控制变量暴露为 0 的组合收益,那是 M11 里纯因子组合的入口。

11. 宽表上的截面:一次矩阵,不要两层循环

第 5 节的两期手算是三只股票。特征都是 (1, 2, 3),下期收益是 (0.01, 0.02, 0.06) 和 (0.03, 0.03, 0.00)。斜率 0.025 与 −0.015,均值 0.005,t = 0.25。宽表把同一组数排成两行三列:行是月份,列是股票。收益列已经对齐到形成月的下一期,不要再 shift。特征在形成日已经知道。

按行去均值之后,斜率是一行里的乘积和除以特征离差平方和。股票那一维是向量运算,不再为每只股票写一层 Python 循环。

γₜ = (Σᵢ (x_ti − ¯xₜ)(y_ti − ¯yₜ)) / (Σᵢ (x_ti − ¯xₜ)²)

打印是 0.025000 与 −0.015000。样本标准差用 T − 1,t 值打印 0.250000。

带截距的截面回归把每一期的设计矩阵写成 [1, x]。T 期放进一个数组,用

(Xₜ′Xₜ)⁻¹ Xₜ′yₜ

一次解完。einsum 先把 X′X 和 X′y 在股票维上乘好,再对每一期做一次 2 × 2 的求解。截距是 −0.020000 与 0.050000,斜率仍是 0.025000 与 −0.015000。第一期:0.03 − 0.025 × 2 = −0.02。第二期:0.02 − (−0.015) × 2 = 0.05。

分层用另一张四列宽表,避免把上面的三列手算改成另一套斜率。特征 (1, 2, 3, 4),两期收益是 (0.00, 0.01, 0.02, 0.04) 和 (0.03, 0.02, 0.01, 0.00)。秩大于 2 的两列是高组,其余是低组。

第一期高组均值 0.03,低组均值 0.005,高减低 0.025000。第二期高组 0.005,低组 0.025,高减低 −0.020000。两期平均 0.002500。

statsmodels.api.OLS 可以逐期拟合同一张截面。可选库没装上时脚本降级,打印 statsmodels_fm skipped。装上之后,每期斜率应与 0.025000、−0.015000 一致;点估计相同,不需要再写一层股票循环。

char_d = char.sub(char.mean(axis=1), axis=0)
fwd_d = fwd.sub(fwd.mean(axis=1), axis=0)
gamma = (char_d * fwd_d).sum(axis=1) / (char_d**2).sum(axis=1)

ones = np.ones((char.shape[0], char.shape[1], 1))
design = np.concatenate([ones, char.to_numpy()[..., None]], axis=2)
xtx = np.einsum("tnk,tnj->tkj", design, design)
xty = np.einsum("tnk,tn->tk", design, fwd.to_numpy())
coef = np.linalg.solve(xtx, xty[..., None])[..., 0]

figures/M06/plot_momentum_sorts.py 的 panel_sort_and_fama_macbeth 打印 fm_t 0.250000、hml 0.025000 -0.020000 和 hml_mean 0.002500。


真实案例

案例 1:1932 年 8 月的多空

同一份市值加权十分位里,1932-08 的高减低是 −77.66%。从 1932-05 的前高到 1939-09,累计回撤 −95.56%。右图在 1940 年附近掉下去,就是这次。算术年化 13.62% 和 t = 4.92 是把这次跌幅和后来的恢复一起平均。自融资研究组合可以在账面上续算。加上杠杆或追加保证金的账户会在 −77% 的那个月失去仓位,接不到后面的恢复。这和 M04 的单位净值熔断是同一类约束。

案例 2:2009 年 3 月和 4 月,三套数字不要混

市值加权十分位高减低:2009-03 为 −39.19%,2009-04 为 −45.18%。同一图书馆的 Mom:2009-03 为 −11.80%,2009-04 为 −34.36%。Daniel & Moskowitz (2016) 表 2 的 WML 是 −42.28% 和 −45.52%,M02 已经按那张表写过。三套组合的空头宽度和市值权重不同,跌幅因此不同。引用时要写出是十分位、Mom 还是那张表。共同的机制仍是空头腿上的输家在反弹里涨得更多。

案例 3:1991 年之后的 t 值

1963-07 至 2026-08 的市值加权高减低,t = 4.39。1991-01 至 2025-12 的同一条多空,算术年化 8.57%,t = 1.75,NW t = 1.74。窗口把 1963–1990 的 20.41% 包括进来时,后一段的变弱被平均掉。检验若只报全样本或只报「1963 至今」,读者看不到 1.75。动量 Plus 实验室的季频秩相关 t = 0.21,则是另一个更小、且含幸存者的股票池,不能用来否定 French 的全样本,也不能被全样本 t 值覆盖。

方法论来源

概念 / 模型 核心文献或规范出处
截面动量 Jegadeesh & Titman (1993), JF 48(1)
双重排序 Fama & French (1993), JFE 33(1),NYSE 断点
GRS Gibbons, Ross & Shanken (1989), Econometrica 57(5)
Fama–MacBeth Fama & MacBeth (1973), JPE 81(3)
基本定律 Grinold (1989), JPM 15(3)
毛利 Novy-Marx (2013), JFE 108(1)
发表后与复制 Hou, Xue & Zhang (2020), RFS 33(5);Jensen, Kelly & Pedersen (2023), JF 78(5)
本仓库 12-1 src/quant/strategies/xs_momentum.py,窗口与 French 的 −12 到 −2 不同
图 plot_momentum_sorts.py

💡 思考回顾与巩固

核心认知纠偏

误区 反例 用法
当月收益对当月特征回归 特征若用了当月收盘,收益也含当月,排序和收益共用同一段价格 持有月的收益对齐到已经结束的排序窗口
method="spearman" 在本环境可用 默认环境没有 scipy,调用会失败 先 rank,再做 Pearson
French 的 −12 到 −2 等于仓库的 12-1 仓库是 TR(m − 1) / TR(m − 13) − 1,跨度 12 个月 十分位数字只描述 French 那 11 个月
等权更显著才是常态 这张动量表上等权多空 10.12%,市值加权 13.62% 两种加权都报,再谈小盘
Newey–West 总会把 t 值压低 市值加权多空的 t 从 4.92 升到 5.14 自相关可正可负,两个 t 都写
1963 年以后动量 t 值仍高于 3 1991–2025 的 t 是 1.75。4.39 含着 1963–1990 分段报告
IC = 0.03 配 500 只股票得到 IR 2.32 2.32 把每个股票月都当成独立赌注,且 TC = 1 同时写出一年 500 个赌注时的 0.67
十组高减低 13.62% 就是 Mom Mom 是 30/70、大小盘各半,算术年化 7.35% 回归里用哪一列就写哪一列

费曼自测

  1. 为什么时序回归的截距和 Fama–MacBeth 的平均斜率不是同一个数?
  2. 秩相关 0.5 的那五只股票,能不能当作这个特征已经有效?
  3. 市值加权动量多空的三因子月截距是 1.697%,原始月均大约 1.14%。截距为什么更高?
  4. GRS = 7.65 比单条多空的 t 值多拒绝了什么?
自测要点 1. 时序回归把因子收益当成已知,估计的是组合的暴露和剩下的月均。Fama–MacBeth 把特征当成已知,估计的是特征每个月的价格。一个是 α,一个是 ¯γ。输入换了,数字就不该相等。 2. 不能。0.5 是一个月、五只股票、没有并列秩的手算。因子是否有效看整段 IC 的均值和 t 值,以及排序是否单调、换窗口是否还在。实验室 45 个季度的均值只有 0.0086。 3. 多空对市场、规模、价值的斜率是 −0.37、−0.27、−0.738。这三个因子的全样本溢价为正,负斜率的期望贡献为负,截距要把这部分加回来,才会等于原始月均。截距高不表示可交易收益高。 4. t 值只看高减低这一条组合。GRS 同时看十个十分位的截距是否都为 0。中间组的截距也可以让联合统计量变大。7.65 高于 F(10, 1183) 大约 1.83 的 5% 临界值。

四维习题

A. 概念题

  1. 写出用排序法检验低市盈率的七步。哪一步专门挡住前视,哪一步专门挡住「只在等权里出现」?
  2. 时序回归和 Fama–MacBeth 各举一个本仓库或 French 文件里能落地的用途。
  3. Newey–West 改变的是哪一个数?在什么情况下它和 iid t 的差距会大?
  4. 行业中性化从特征里拿走了什么?什么策略不该做这一步?

B. 计算题

  1. 用第 6 节的五只股票复核 Rank IC。再计算 IC 均值 0.03、标准差 0.12、120 个月的年化 ICIR 和 t 值。
  2. IC = 0.03,TC = 1。500 只股票按「每月独立」和「每年 500 个独立赌注」分别估算 IR。TC 降到 0.5 时,两个数各变成多少?
  3. 复核两期 Fama–MacBeth 的斜率和 t = 0.25。
  4. 特征 1, 2, 3, 4, 100。按未放缩的 5 × MAD 写出截断后的五个数。

C. 编程实战题

  1. 用 French 月频十分位复现第 9 节的十组年化、高减低 t 值,以及 1991–2025 的 t 值。确认没有读入年度块。
  2. 把市值加权高减低对三因子回归,打印月截距、经典 t 和 HAC t。
  3. 在动量 Plus 的秩相关表里读出经典 12-1 的均值和 t 值,并写明它和 French 十分位为什么不能直接比。

D. 个人实战思考题

  1. 你只能做多、杠杆上限 1.0。French 高减低的 13.62% 里,哪一部分是你的账户拿不到的?
  2. 港股月频换仓还要付印花税。这条成本和「IC 只有 0.03 但广度很大」哪一边先碰到约束?
  3. 给以后的因子检验列一张最小清单:时点、两种加权、分段 t 值、成本。每一项对应本章的哪一节?
完整参考答案与解析 **A1.** 七步见第 2 节。挡住前视的是第 2 步和第 4 步:特征只用形成日已有的数据,收益用下一期。挡住「只在等权里出现」的是第 4 步里两种加权都报告。NYSE 断点是第 3 步,用来减轻微小市值占满极端组,它不代替两种加权。 **A2.** 时序回归:把 French 市值加权高减低对 Mkt-RF、SMB、HML 回归,读月截距 1.697%。Fama–MacBeth:每个月用市盈率或动量特征解释下月个股收益,再对斜率序列取均值。本章的两期手算是后者的步骤,不是一个已完成的定价检验。 **A3.** Newey–West 改变标准误,不改变均值或回归系数。收益重叠、方差聚集或一阶自相关明显时,差距变大。本章市值加权多空的一阶自相关只有 0.062,t 值从 4.92 变为 5.14,方向是变大。不能把「调整后 t 值更小」写成规律。 **A4.** 中性化拿走特征里与行业哑变量和对数市值线性相关的部分。若策略的收益来源就是行业或市值配置,这一步会把要检验的东西先删掉。纯选股特征才做中性化,并且中性化前后的 IC 都保留。 **B5.** 秩的 Pearson 是 5/10 = 0.5。`ICIR_月 = 0.25`,年化 0.25 √12 = 0.866,t = 0.25 √120 = 2.74。 **B6.** 每月独立:√6000 × 0.03 = 2.32。每年 500 个赌注:√500 × 0.03 = 0.67。TC = 0.5 时分别是 1.16 和 0.34。2.32 不是预测的实盘信息比。 **B7.** 斜率 0.025 和 −0.015,均值 0.005。样本标准差 √0.0008 = 0.02828,t = 0.005 / (0.02828/√2) = 0.25。 **B8.** 中位数 3,MAD = 1,界限 [−2, 8]。截断后是 1, 2, 3, 4, 8。若改用 1.4826 × MAD,界限不同,本章这一题固定用未放缩的 MAD。 **C9–C11.** 与 `figures/M06/plot_momentum_sorts.py` 同一契约,脚本已对 202608 版文件运行。市值加权高减低全样本算术年化 13.62%,t = 4.92,NW t = 5.14。1991–2025 是 8.57%,t = 1.75。月截距 1.697%,经典 t = 8.36,HAC t = 9.11。动量 Plus 的 `rank_ic_summary.csv` 里,经典 12-1 的季频均值是 0.0086,t = 0.21,45 个季度。股票池是全程存活的大盘股,频率是季,窗口也 shorter,和 French 的 1196 个月、含退市处理的研究组合不是同一次检验。
import pandas as pd

def rank_corr(left: pd.Series, right: pd.Series) -> float:
    common = left.dropna().index.intersection(right.dropna().index)
    # scipy 不在默认环境里。秩的 Pearson 就是 Spearman。
    a = left.loc[common].rank()
    b = right.loc[common].rank()
    return float(a.corr(b))
**D12.** 13.62% 是高组减低组。低组那一条空头需要借券,杠杆上限 1.0 也禁止为了放大多空再借款。账户若只买最高组,拿到的是含市场的原始收益,全样本算术年化 18.24%,不是 13.62% 的多空,也不是 1.697% 的月截距。借券费和无法成交的空头会使多空比 13.62% 更小。 **D13.** 印花税按成交额收取,月频换仓先碰到成本。广度公式里的 2.32 没有这一项。先把换手乘费用,看还剩多少给 IC。费用盖住预期差时,增加股票只数不会把信息比救回来。 **D14.** 时点对应第 2 节和第 9 节的 `shift`:排序窗口在持有月之前结束。两种加权对应第 3 节和第 9 节的并列报告。分段 t 值对应 1991–2025 的 1.75,不能只留全样本 4.92。成本对应第 9 节末和第 12 题:研究曲线未扣借券和印花税。清单写在实验记录里,不代替 `docs/workflow.md` 开头的流程门槛。

📌 章节知识总结

一句话核心洞察

  1. 特征用形成日已有的数据,收益用下一期。French 动量是 −12 到 −2。仓库的 12-1 跨度是 12 个月,两条信号不同。
  2. 时序回归给截距,Fama–MacBeth 给斜率的时间序列。秩相关要先转成秩再做 Pearson。
  3. 1927-01 至 2026-08,市值加权动量高减低算术年化 13.62%,t = 4.92。Mom 因子是 7.35%,不是这 13.62%。
  4. 1991–2025 同一条高减低的 t 值是 1.75。1963 至今的 4.39 含着更早的 20.41%。
  5. 1932-08 的市值加权高减低是 −77.66%,随后回撤到 −95.56%。全样本 t 值没有取消这次回撤。

公式与样本

对象 表达式或数值 前提
多空 高组收益 − 低组收益 方向事先定好
时序截距 超额对因子回归的 α 因子频率与组合相同
GRS (T − N − K) / N · (α′ Σ⁻¹ α) / (1 + μ′ Ω⁻¹ μ) 本章 Σ 除以 T − K − 1
Fama–MacBeth t ¯γ / (s/√T) 再按自相关做 HAC
宽表两期斜率 0.025000 与 −0.015000 与第 5 节同一组数,t = 0.250000
四列高减低 0.025000 与 −0.020000 两期平均 0.002500
Rank IC 秩的 Pearson 不调用缺失的 scipy
年化 ICIR 月 ICIR × √12 假定 IC 月间独立
基本定律 IR ≈ TC × IC × √BR 2.32 使用 BR = 6000
去极值 中位数 ± 5 × MAD 未乘 1.4826
French 窗口 1927-01 至 2026-08,1196 个月 不含年度块
1991–2025 高减低 年化 8.57%,t = 1.75 市值加权十分位

跨模块

结论 交给 位置
截距是模型残差 归因 M14
秩相关接近 0 的实验室股票池 不要用 French t 值覆盖 knowledge/Labs/momentum_plus_lab/outputs/rank_ic_summary.csv
12 个月动量的实现 与 French 的 11 个月区分 src/quant/strategies/xs_momentum.py
杠杆挨不住 −77% 的月份 仓位闸门 M04,docs/risk_policy.md
多重检验门槛 因子动物园 M08
纯因子组合 风险模型 M11

学习指引

概念卡片:Fama–MacBeth 回归 · GRS 检验

  • 精读:因子第 2 章的排序、两种回归和 IC。2.7 的 GMM 知道它在估计矩条件即可。
  • 对照:French 文件以脚本下载的 202608 版为准。书里的 A 股表不要和这张美股十分位对减。
  • 项目:本章不新增交易因子。检验若写进代码,时点规则与 XsMomentumStrategy 的窗口注释保持一致,并在注释里说明它不是 French 的 −12 到 −2。
  • 下一步:M07 把这套检验用到具体因子的定义上。定义没写清之前,不要比较 t 值。

自检清单

  • 能把低市盈率的排序七步写全,并指出收益用的是下一期
  • 能手算五只股票的 Rank IC = 0.5,以及 IC t = 2.74
  • 能说出 13.62% 和 Mom 的 7.35% 各是哪一个组合
  • 能把 1991–2025 的 t = 1.75 和 1963 至今的 4.39 放在同一张表里
  • 能指出 1932-08 的 −77.66% 是市值加权十分位高减低,不是 Daniel & Moskowitz 表 2 的数字
  • 能复述宽表斜率 0.025000、−0.015000 与 t = 0.250000,以及 statsmodels_fm skipped