Fama-French 三因子论文精读
CAPM 失效证据 → FF 1992 → FF 1993 三因子 → FF 2015 五因子 → 后续批评
日期: 2026-05-17 方向: 个人量化交易 / 因子投资 阶段: Phase 1: 基础与工具链 标签: #FamaFrench #FF3 #FF5 #SMB #HML #FactorInvesting #CrossSection
今日目标
| 类型 | 内容 |
|---|---|
| 学习 | CAPM 失效证据 → FF 1992 → FF 1993 三因子 → FF 2015 五因子 → 后续批评 |
| 实操 | 从 Kenneth French 数据库下载 FF3 月度因子,跑一只股票(AAPL)的三因子回归 |
| 产出 | TR-DAY8 笔记 + 一段可复现的 Python 回归脚本 + 对 α / β / s / h 的解读 |
一、为什么从 Fama-French 开始
Week 2 的开篇必须是 Fama-French,原因不在于这是「最赚钱的因子」(事实上 1990s 以后它的 alpha 在持续衰减),而在于它是现代因子投资范式的起点。后面我们要学的 momentum(Jegadeesh-Titman 1993)、low-vol(Ang-Hodrick 2006)、quality(Asness-Frazzini-Pedersen 2013)、defensive、carry、investment 等等,都是在「Fama-French 的方法论框架」之内做的扩展:
Fama-French 范式的三件套
─────────────────────────────────────────
(1) 找出一个能解释 cross-section returns 的财务/价格特征 X
(2) 按 X 把全市场股票排序、分组、构造 long-short portfolio
(3) 把这个 portfolio 的 returns 当成一个新的「因子」,加入定价模型
掌握 FF3 = 拿到了打开后面 30 年所有因子论文的钥匙。如果跳过 FF 直接学动量或机器学习因子,会发现 paper 里反复出现的 SMB、HML、α、t-stat 全是黑话。
更深层的意义:FF3 是金融经济学第一次成功把 noise 抽象成 signal 的范例。CAPM 时代,研究者眼中的市场 returns 只有一个维度(市场风险溢价);FF 之后,returns 被拆成了多维向量,每个维度对应一种系统性风险来源。这种「拆维」的思想在所有量化领域都有迁移价值——10 年金融 PM 视角看,这跟把「用户行为」从「DAU」拆成「new / resurrected / churned / loyal」是同一种抽象动作。
二、背景:CAPM 失效的证据(1980s)
2.1 CAPM 在说什么
资本资产定价模型(Sharpe 1964 / Lintner 1965)的核心断言:
E[R_i] - R_f = β_i · (E[R_m] - R_f)
只有市场 beta 决定预期回报;除了 beta 之外的任何特征
(市值大小、估值高低、行业、动量),都不应该有定价能力。
这是一个非常美的理论——单变量模型解释整个截面。如果它是对的,散户唯一要做的事情就是选好杠杆。
2.2 1980s 的实证打脸
整个 1980s,学界用越来越好的数据库(CRSP、Compustat)反复检验 CAPM,结果很尴尬:
| 异象 | 论文 | 内容 |
|---|---|---|
| Size effect | Banz (1981) | 小盘股长期跑赢大盘股,扣除 beta 后仍有显著 alpha |
| Value effect | Stattman (1980) / Rosenberg-Reid-Lanstein (1985) | 高 B/M(账面市值比)股票跑赢低 B/M |
| Earnings yield | Basu (1977, 1983) | 低 P/E 股票跑赢高 P/E |
| Leverage | Bhandari (1988) | 高杠杆公司收益更高(控制 beta 后) |
| January effect | Keim (1983) | 1 月份小盘股异常跑赢 |
到 1980s 末,市场上已经积累了一堆 CAPM 不能解释的「异象」(anomalies)。但这些异象散落在不同论文里,没有人把它们整合成一个新的、可操作的框架。
2.3 Fama-French 1992:把异象做成可用的实证模型
Eugene Fama 与 Kenneth French 是这件事的整合者。他们 1992 年发表在 Journal of Finance 的 "The Cross-Section of Expected Stock Returns" 是金融实证经济学最高引用的论文之一。
核心发现:
样本:NYSE + AMEX + NASDAQ,1963 年 7 月 - 1990 年 12 月
方法:Fama-MacBeth 横截面回归
结论 1:beta 单独解释力 ≈ 0
当 size 和 B/M 一起进回归时,beta 的 t-stat 不显著
结论 2:size(log market cap)显著负相关
小公司未来收益更高(控制 B/M 后仍然成立)
结论 3:B/M(账面市值比)显著正相关
高 B/M("value")股票未来收益更高(控制 size 后仍然成立)
结论 4:size 和 B/M 联合起来,把 leverage、E/P 等异象都吸收掉了
这篇论文的杀伤力在于:它没有提出新理论,只是把既有数据彻底洗了一遍。CAPM 信徒在它面前只能选三种态度:
- 否认数据(很难)
- 说这是 data mining(但 size 和 B/M 在 out-of-sample 也活下来了)
- 接受 CAPM 不完整,需要新的模型
学界选了第三条。
三、Fama-French 1993:三因子模型登场
1993 年 Fama-French 又发了一篇 Journal of Financial Economics 的 "Common risk factors in the returns on stocks and bonds"。这篇是我们今天要重点精读的——它把 1992 论文的发现,变成了可以下载、可以回归、可以做投资组合分析的 portfolio-level factors。
3.1 模型公式
R_i - R_f = α_i + β_i · (R_m - R_f) + s_i · SMB + h_i · HML + ε_i
含义:
| 符号 | 名字 | 解释 |
|---|---|---|
R_i - R_f | 超额收益 | 资产 i 相对无风险利率的超额回报 |
R_m - R_f | MKT(市场因子) | 市场整体超额回报,CAPM 里就有 |
SMB | Small Minus Big | 小盘股相对大盘股的超额回报 |
HML | High Minus Low | 高 B/M(价值)相对低 B/M(成长)的超额回报 |
α_i | 截距 | 三因子无法解释的部分;理想中应为 0 |
β_i, s_i, h_i | 因子载荷 | 资产 i 对各因子的暴露程度 |
ε_i | 残差 | 特异性风险 |
3.2 SMB 和 HML 是怎么造出来的(关键细节)
很多人能背公式,但讲不清 SMB / HML 怎么从原始股票数据构造出来的。这一步是 FF 方法论的精华,也是后面所有因子论文的 cookbook。
步骤:
步骤 1:每年 6 月底取一次快照
─────────────────────────────────────────────
- 用所有 NYSE 股票计算 size 中位数(仅 NYSE,避免 NASDAQ 小票拉低)
- 把所有股票(NYSE + AMEX + NASDAQ)按这个中位数分成 Small / Big 两组
步骤 2:同样时间点
─────────────────────────────────────────────
- 用所有 NYSE 股票计算 B/M 的 30% 和 70% 分位
- 把所有股票按这两个分位分成 Low / Medium / High 三组
步骤 3:交叉成 2×3 = 6 个 portfolio
─────────────────────────────────────────────
Low B/M Medium B/M High B/M
Small S/L S/M S/H
Big B/L B/M B/H
步骤 4:每个 portfolio 内按市值加权计算月度收益
─────────────────────────────────────────────
(不是等权,是 cap-weighted,避免微小盘票主导)
步骤 5:构造 SMB 和 HML
─────────────────────────────────────────────
SMB = (S/L + S/M + S/H) / 3 - (B/L + B/M + B/H) / 3
HML = (S/H + B/H) / 2 - (S/L + B/L) / 2
为什么是 2×3 而不是 5×5? 因为 5×5 会把每组样本量切得过小,统计噪声太大。2×3 是 Fama-French 平衡 sample size 与 dimension 之后选的最小有效切割。
为什么 size 用 50/50 而 B/M 用 30/40/30? 因为 size 分布相对均匀,B/M 分布偏态严重(成长股多、价值股少),需要更不对称的切分才能让每组有合理样本量。
为什么用 NYSE 分位而不是全样本分位? 这是个常被忽视的细节。NASDAQ 小票数量极多,如果用全样本分位,"Small" 组里几乎全是 NASDAQ 微小盘票,"Big" 组反而会包括 NASDAQ 中盘票。用 NYSE 分位避免这种 over-sampling 偏差。
3.3 三因子的实证表现(FF 1993)
FF 1993 论文里把全市场股票按 size 和 B/M 切成 25 个 portfolio,跑三因子回归:
| 模型 | 25 portfolio 的平均 R² | α 显著的数量 |
|---|---|---|
| CAPM (单因子) | 约 0.70 | 大部分显著(说明模型不对) |
| 三因子 | 约 0.93 | 大部分不显著 |
含义:三因子加进去之后,几乎所有截面变化都被解释了。这是「实证胜利」。
四、风险解释 vs 行为解释(至今未决的问题)
FF3 在实证上赢了,但在理论解释上,从 1993 年到今天还在吵:为什么 size 和 value 会有溢价?
4.1 风险派(Fama-French 自己的立场)
| 论点 | 内容 |
|---|---|
| Distress risk | 高 B/M 公司往往是经营困难、临近破产的;投资者要求更高回报 |
| Liquidity risk | 小盘股流动性差,遇到危机时套现困难 |
| Cash flow risk | 价值股的现金流对宏观冲击更敏感 |
| Investment-based | Cochrane (1991) 用 q-theory 解释:投资低的公司未来回报高 |
核心断言:因子溢价是「承担系统性风险的合理补偿」,符合有效市场假说。
4.2 行为派(Lakonishok / Shleifer / Vishny / Daniel / Titman)
| 论点 | 内容 |
|---|---|
| 过度反应 | 投资者过度看好成长股、过度悲观价值股,导致系统性 mispricing |
| Anchoring | 投资者用过去业绩做锚,不愿意为低估值公司付出合理估值 |
| Limit to arbitrage | 即使有人意识到 mispricing,做空成本和资金约束阻止套利 |
| Herding | 机构投资者扎堆抱团成长股,放大估值差距 |
核心断言:因子溢价是「市场非理性的表现」,反对纯有效市场假说。
4.3 为什么这件事很重要
这不是学术八卦,对 PM/量化决策有直接影响:
| 立场 | 推论 | 实操影响 |
|---|---|---|
| 纯风险派 | 因子永远存在,因为承担风险就有补偿 | 持续配置因子组合,不担心衰减 |
| 纯行为派 | 因子可能消失(套利者多了之后) | 警惕因子衰减,监控 alpha decay |
| 折中派 | 部分风险 + 部分行为 | 因子部分会消失,部分会留下 |
我个人的立场(对应金融工程实操):折中派偏行为。原因:
- 如果是纯风险,post-publication decay 不应该发生——但实证看,公开后多数因子收益减半(详见第 6 节)
- 如果是纯行为,因子早就该被套利吞掉——但 value、momentum 在 60 年数据上仍然有显著 t-stat
- 最合理的解释:风险溢价是 floor,行为 mispricing 是 cycle。floor 决定长期均值,cycle 决定短期可交易性。
至今没有定论这件事本身就值得学。它告诉我们:金融科学不是物理学,不会有「最终模型」。我们只是在用不完美的模型做不完美的决策——任何声称「找到圣杯」的策略都该警惕。
五、Fama-French 五因子(2015):为什么三因子不够
2015 年 Fama 和 French 又发了 "A five-factor asset pricing model"(Journal of Financial Economics)。
5.1 三因子的不足
到 2010s,学界又积累了一批三因子无法解释的异象:
| 异象 | 描述 |
|---|---|
| Profitability | 高 ROE / 高毛利率公司未来回报更高(Novy-Marx 2013) |
| Investment | 资本支出低 / 总资产增长慢的公司未来回报更高(Cooper-Gulen-Schill 2008) |
| Accruals | 应计利润低的公司未来回报更高(Sloan 1996) |
| 还有更多... | Quality、Low-vol、Momentum 等 |
最致命的是profitability 和 investment——它们在控制 size、B/M 之后仍然有显著 alpha,说明 FF3 漏掉了重要的定价维度。
5.2 五因子模型公式
R_i - R_f = α_i + β_i·(R_m-R_f) + s_i·SMB + h_i·HML + r_i·RMW + c_i·CMA + ε_i
新增两个因子:
| 因子 | 全名 | 构造 |
|---|---|---|
| RMW | Robust Minus Weak | 高盈利能力(operating profitability)股票 - 低盈利能力股票 |
| CMA | Conservative Minus Aggressive | 低投资率(asset growth 慢)股票 - 高投资率股票 |
构造方法和 SMB / HML 一样——按 size 和因子特征做 2×3 切分。
5.3 五因子的代价
好处:
+ 解释力进一步提高(25 portfolio 的 R² 从 0.93 升到 0.95+)
+ Profitability 和 investment 异象被吸收
+ HML 在五因子里变得「冗余」——美国数据上 HML 的 alpha 几乎被 RMW + CMA 解释掉了
代价:
- 模型变复杂,参数变多,更容易过拟合
- HML 冗余引发争议(Fama-French 自己都说 HML 在五因子里 redundant)
- 不能解释 momentum(Carhart 1997 就指出过)
- 不同地区的稳健性参差(Asness 2017 在欧洲、日本数据上挑战了五因子)
现状:学界和业界用三因子的多于五因子。AQR、Dimensional 这些大型因子基金普遍在 FF3 + Momentum (Carhart 4) 或 FF3 + Quality + Momentum 的组合上做扩展。
六、批评与失效迹象(必须知道的反面)
6.1 Post-publication decay:因子公开后收益减半
McLean & Pontiff (2016) Journal of Finance 经典论文:检验 97 个学术因子,发现论文发表后,平均收益衰减约 32%;其中 12 个因子收益完全消失。
Asness 等(AQR)的多次研究也指出:FF3 中 SMB 在 1980 年代之后收益持续低于学术样本期;HML 在 2014-2020 经历了「失落十年」。
Why:套利交易者读到论文后开始执行该策略,需求把 alpha 推走。这是行为派立场的有力证据。
6.2 Value 的失落十年(2014-2020)
这件事对 PM 思维特别重要:
1927-2014:HML 长期 t-stat ≈ 4.5(教科书黄金因子)
2014-2020:HML 累计 -50%(连续 6 年负回报)
2020-2024:Value 部分回归
哪些机构在 2018-2020 死了:
- AQR 旗舰 value fund 大幅赎回
- Dimensional 也经历重大资金外流
- Cliff Asness 写了多篇辩护文章,承认 value 进入历史最差回撤
结论:任何因子都会有 5-10 年的 drawdown。如果你不能心理上承受这个,就别配置因子策略。
6.3 数据挖掘风险
Harvey, Liu & Zhu (2016) "...and the Cross-Section of Expected Returns":他们清点了学术界发表的「因子」,发现到 2015 年共有 316 个所谓的 alpha factor。其中绝大部分是 data snooping 的产物——没有经济学解释,只是在历史数据上凑出来的。
他们提出:因子的 t-stat 应该至少 ≥ 3.0(而不是传统的 2.0)才能算可信。按这个标准,过去 50 年发表的因子里能活下来的不到 50 个。
McLean-Pontiff 之后,业界的 best practice:
- 任何因子上线前必须过 out-of-sample 测试(最好是另一个市场 / 另一个时间段)
- 必须有经济学叙事(不能只是「我跑出来 t-stat 高」)
- 必须做 regime test(在 2008、2020 这种极端环境下表现如何)
七、动手:下载 FF3 数据并跑回归
7.1 Kenneth French 数据库(核心资源)
URL:Kenneth French Data Library
这个网站每月更新,提供:
| 文件 | 内容 | 频率 |
|---|---|---|
| F-F_Research_Data_Factors | FF3 因子(MKT-RF, SMB, HML, RF) | Monthly / Daily / Weekly |
| F-F_Research_Data_5_Factors_2x3 | FF5 因子(多 RMW + CMA) | Monthly / Daily |
| F-F_Momentum_Factor | Momentum 因子(UMD = Up Minus Down) | Monthly / Daily |
| 6_Portfolios_2x3 | 构造 SMB/HML 的 6 个原始 portfolio | Monthly |
| 25_Portfolios_5x5 | 25 个测试 portfolio | Monthly |
注意:French 数据库是美国市场的因子。其他地区(European, Japan, Asia ex-Japan, Emerging)也有专门的数据集。
7.2 下载 + 解析代码
# tr_day8_ff3.py
# 一段最小可复现的 FF3 三因子回归脚本
import pandas as pd
import numpy as np
import statsmodels.api as sm
from io import BytesIO
from urllib.request import urlopen
from zipfile import ZipFile
FF3_URL = "https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_CSV.zip"
def load_ff3_monthly():
"""下载 FF3 月度因子,返回 DataFrame(百分比已转成小数)。"""
with urlopen(FF3_URL) as resp:
with ZipFile(BytesIO(resp.read())) as zf:
csv_name = zf.namelist()[0]
raw = zf.read(csv_name).decode("latin-1")
# FF 的 CSV 头有几行说明,要跳过;尾部又有 annual 表,要截断
lines = raw.splitlines()
start = next(i for i, ln in enumerate(lines) if ln.strip().startswith("19"))
# 找到第一段空行(monthly 段结束)
end = start
for i in range(start, len(lines)):
if not lines[i].strip() or "Annual" in lines[i]:
end = i
break
data = "\n".join(lines[start:end])
df = pd.read_csv(BytesIO(data.encode()), header=None,
names=["yyyymm", "MKT_RF", "SMB", "HML", "RF"])
df["date"] = pd.to_datetime(df["yyyymm"].astype(str), format="%Y%m") + pd.offsets.MonthEnd(0)
df = df.set_index("date").drop(columns="yyyymm").astype(float) / 100.0
return df
def load_aapl_monthly():
"""从 yfinance 拉 AAPL 月度收益。"""
import yfinance as yf
px = yf.download("AAPL", start="2010-01-01", end="2026-04-30",
interval="1mo", auto_adjust=True, progress=False)["Close"]
return px.pct_change().dropna().rename("AAPL").to_frame()
def ff3_regression(stock_ret: pd.Series, ff: pd.DataFrame) -> sm.regression.linear_model.RegressionResultsWrapper:
df = ff.join(stock_ret.to_frame("R"), how="inner").dropna()
y = df["R"] - df["RF"] # 个股超额收益
X = df[["MKT_RF", "SMB", "HML"]]
X = sm.add_constant(X) # 加截距 (alpha)
return sm.OLS(y, X).fit()
if __name__ == "__main__":
ff = load_ff3_monthly()
aapl = load_aapl_monthly()["AAPL"]
res = ff3_regression(aapl, ff)
print(res.summary())
print(f"\n年化 alpha: {res.params['const']*12*100:.2f}%")
print(f"市场 beta: {res.params['MKT_RF']:.3f}")
print(f"SMB load (s): {res.params['SMB']:.3f}")
print(f"HML load (h): {res.params['HML']:.3f}")
7.3 解读输出(示例)
跑出来的结果大致会长这样(数值随时间窗变化):
coef std err t P>|t|
const (alpha) 0.0085 0.003 2.84 0.005
MKT_RF 1.182 0.075 15.76 0.000
SMB -0.347 0.122 -2.85 0.005
HML -0.521 0.118 -4.41 0.000
怎么读:
| 系数 | 数值 | 解读 |
|---|---|---|
α | 0.85% / 月 ≈ 10.2% / 年 | 三因子之外的「Apple 特有 alpha」,t-stat 2.84,弱显著 |
β | 1.18 | 市场 beta 略高于 1,AAPL 比大盘略激进 |
s (SMB load) | -0.35 | 负载 SMB,说明 AAPL 像「Big stock」(确实是巨头) |
h (HML load) | -0.52 | 负载 HML,说明 AAPL 像「Growth」而非 Value(确实是成长股) |
几个值得想的细节:
- 为什么 AAPL 的 alpha 在 2010s 显著正?因为 iPhone 时代股价表现远超三因子能解释的,这部分被记成「特异 alpha」。
s = -0.35, h = -0.52说明 AAPL 是典型的「大盘成长」股——这跟我们直觉一致。FF 模型把直觉变成了数字。- 如果跑 2020-2024 年(疫情后 Tech 大涨期间),AAPL 的 alpha 还会更高;如果跑 2022 年单年,alpha 可能转负——单期 alpha 不稳定。
7.4 这段代码 PM 视角的意义
这是一个非常微小的脚本(不到 60 行),但它完成了一次完整的 factor exposure attribution——把一只股票的收益分解成:
- 市场暴露
- 风格暴露(size、value)
- 特异 alpha
所有专业资管报告里的「我这只基金的 alpha 是多少」就是这么算出来的。理解这一步就理解了机构投资语言。
八、PM 视角:今天学到的迁移性思考
-
「拆维」是金融学最强的方法论之一:CAPM 只有一维(beta),FF 拆成三维,五因子拆成五维。维度越多,模型解释力越强但也越容易过拟合。这跟 PM 做用户分群完全同构——把「DAU」拆成「new / returning / power」就是因子化。
-
论文公开 → alpha 衰减是开源思想在金融里的体现:Web2 / Web3 的开源社区认为「公开促进进步」,金融学界一样——但金融的代价是 alpha 被消灭。这暗示了「knowledge as moat」这种产品策略在金融行业要更小心,因为 know-how 一旦写出来就会被定价进市场。
-
风险派 vs 行为派之争 = 「设计派 vs 数据派」之争:风险派像设计派(先有理论再找数据验证),行为派像数据派(先看数据再讲故事)。两派在金融学里 60 年没分出胜负——这告诉我们任何「方法论之争」可能本来就是伪命题,实际项目里最优解是混用。
-
失落十年是 PM 风险管理的核心 case:2014-2020 价值因子 -50%。如果你是 fund PM,怎么和投资人解释「6 年没赚钱」?这是 communication 问题不是 model 问题。同理,产品有 long bet 时,怎么和老板解释「这条线 3 年看不到回报」?同一个问题。
-
数据挖掘风险 ≈ A/B test multiple comparisons:金融学有 316 个因子,绝大部分是噪声;产品 A/B test 跑 100 个也会有 5 个「显著」是假阳性。Bonferroni 校正在两个领域都该用。
-
t-stat ≥ 3.0 比 ≥ 2.0 的提议很有 PM 价值:当一个领域里有大量探索性研究时,传统统计阈值不够。提高阈值意味着接受更高 false negative 换更低 false positive——产品决策同理:当你有 10 个 feature idea 时,应该把发布门槛抬高,而不是「t-stat 显著就发」。
九、Day 8 实际执行 Checklist
按这个顺序做:
- (1) 读完本笔记理论部分(CAPM 失效 → FF3 → FF5 → 批评)
- (2) 注册 Kenneth French 数据库(不需要登录,直接下载 CSV)
- (3) 跑下载脚本:能成功 parse 出 MKT_RF / SMB / HML / RF 四列月度数据
- (4) 跑 AAPL 三因子回归:成功打印 summary + 解读 α / β / s / h
- (5) 换一只股票再跑:建议 BRK-B(应该是 value tilt)或 NVDA(应该是 growth + small-cap-like 高 beta)
- (6) 对比观察:不同股票的 SMB / HML load 是否符合直觉
- (7) 把数据缓存到本地:
./data/ff3_monthly.parquet,避免每次重新下载 - (8) 更新进度:
docs/daily/TR_PROGRESS.mdWeek 2 / Day 8 标 ✅ - (9) 记录踩坑:本笔记最后加「实际执行记录」段
十、明日预告
Day 9: 因子有效性评估 — IC、IR、t-stat 与 multiple testing
- 什么是 Information Coefficient (IC):因子值排名与未来收益排名的 Spearman 相关
- IR(Information Ratio):alpha 的「信噪比」
- t-stat ≥ 2.0 vs ≥ 3.0:什么时候用哪个
- Multiple comparisons:Bonferroni / FDR 校正
- 用今天下载的 FF3 数据计算 SMB 和 HML 的 IR,看「教科书因子在最近 10 年的实际表现」
- PM 视角:因子评估 vs 产品 metric 评估的同构性
实际执行记录
启动一项填一项,时间戳 + 卡点。
- [hh:mm] 下载 FF3 CSV 成功 — ...
- [hh:mm] AAPL 三因子回归跑通 — ...
- [hh:mm] 第二只股票(BRK-B / NVDA)回归 — ...
- [hh:mm] 数据本地缓存 — ...
- 卡点 / 学到的:
总字数:约 6,400 字 今日完成度:理论 ✓ / 实操(你自己执行)/ 笔记 ✓