02-因子溢价来源
预计学习时间:2-3 小时
难度:⭐⭐⭐⭐
核心问题:因子为什么能预测收益?是因为你承担了风险,还是因为大多数人犯了错误?
从一个根本问题出发
假设你发现”便宜的股票长期收益更高”——这个现象已经被学术界验证了几十年。
但关键问题是:为什么?
是市场犯了错误(便宜的股票被低估了),还是便宜的股票确实更”危险”(困境公司、破产风险),投资者只是得到了应有的补偿?
这个”为什么”的问题,决定了你对因子投资的态度:
- 如果因子有效是因为风险补偿,那因子的溢价应该是稳定的、长期的
- 如果因子有效是因为行为偏差,那当投资者”学习”了之后,溢价可能消失
- 如果因子有效只是数据挖掘,那它在样本外根本不成立
本章深入讨论因子溢价的三种主要来源,以及由此衍生的重要问题。
一、风险补偿理论
1.1 核心思想:因子有效是因为你承担了某种系统性风险
这是最”正统”的解释,也是最被学术界接受的理论。
白话版本:你因为承担了某种风险,所以获得了额外补偿。因子溢价不是”捡便宜”,而是”风险的价格”。
1.2 CAPM:一个因子的世界
CAPM 是一切因子模型的起点。
它说:股票的预期收益只取决于一个风险——市场风险(系统性风险)。
其中:
- :股票 的预期收益
- :无风险利率
- :股票 对市场风险的暴露
- :市场风险溢价
CAPM 的含义:Beta 越高的股票,承担的市场风险越大,预期收益越高。这个关系是线性的。
但 CAPM 有一个问题:现实中,很多高 Beta 的股票并没有获得更高的收益(低波动异象),而且很多与 Beta 无关的变量也能预测收益(价值、规模、动量)。
1.3 多因子模型:多个风险源,每个都有补偿
既然一个因子不够,那就加更多。
Fama-French 三因子模型(1993):
- MKT:市场因子(和 CAPM 一样)
- SMB(Small Minus Big):小公司 - 大公司的收益差
- HML(High Minus Low):高 B/P - 低 B/P 的收益差
Fama-French 五因子模型(2015):
新增:
- RMW(Robust Minus Weak):高盈利 - 低盈利
- CMA(Conservative Minus Aggressive):保守投资 - 激进投资
多因子模型的核心逻辑:每个因子代表一种系统性风险。你暴露于某种风险,就会得到相应的补偿。
1.4 APT:套利定价理论
Ross(1976)提出的 APT 比 CAPM 更一般化。它不假设市场组合是最优的,而是说:
如果两个资产的因子暴露完全相同,它们的预期收益也应该相同。如果不相同,套利者就会买入便宜的、卖出贵的,直到价格调整到位。
其中 是因子 的风险溢价, 是资产 对因子 的暴露。
APT 不需要知道因子是什么——只要存在能驱动收益的系统性因子,APT 就成立。这是一个更灵活的框架。
1.5 Python:用模拟数据验证多因子模型
import numpy as np
import pandas as pd
import statsmodels.api as sm
np.random.seed(42)
# ============================================================
# 模拟 300 只股票 60 个月的数据
# ============================================================
n_stocks = 300
n_months = 60
# 模拟因子收益(每月随机,但有均值回归)
factor_names = ['MKT', 'SMB', 'HML', 'UMD']
true_premiums = [0.005, 0.003, 0.004, 0.006] # 真实的因子溢价
factor_returns = np.zeros((n_months, len(factor_names)))
for t in range(n_months):
for k in range(len(factor_names)):
# 因子收益围绕真实溢价波动
factor_returns[t, k] = (true_premiums[k]
+ np.random.normal(0, 0.02))
# 模拟股票的因子暴露
betas = np.random.normal(0, 0.5, (n_stocks, len(factor_names)))
# 股票收益 = 因子暴露 × 因子收益 + 特质收益
stock_returns = np.zeros((n_months, n_stocks))
for t in range(n_months):
stock_returns[t] = betas @ factor_returns[t] + np.random.normal(0, 0.05, n_stocks)
# ============================================================
# Fama-MacBeth 回归验证因子溢价
# ============================================================
# 第一步:每个月做截面回归
monthly_coefficients = []
for t in range(n_months):
y = stock_returns[t]
X = sm.add_constant(betas)
model = sm.OLS(y, X).fit()
monthly_coefficients.append(model.params)
coefficients = np.array(monthly_coefficients)
# 第二步:对系数取时间序列平均
print("=" * 60)
print("Fama-MacBeth 因子溢价估计")
print("=" * 60)
print(f"{'因子':>8} {'真实溢价':>10} {'估计溢价':>10} {'t 统计量':>10}")
print("-" * 40)
for k, name in enumerate(factor_names):
mean_coef = np.mean(coefficients[:, k + 1]) # +1 跳过截距
std_coef = np.std(coefficients[:, k + 1], ddof=1)
t_stat = mean_coef / (std_coef / np.sqrt(n_months))
print(f"{name:>8} {true_premiums[k]:10.4f} {mean_coef:10.4f} {t_stat:10.2f}")
print("\n结论: 如果 t 统计量 > 2,说明该因子的溢价在统计上显著")1.6 风险补偿理论的局限性
| 问题 | 说明 |
|---|---|
| 价值因子是风险吗? | 价值股=困境公司?但很多价值股经营很好 |
| 动量的风险是什么? | 动量崩盘风险?但崩盘的概率和频率无法精确量化 |
| 低波动因子的风险? | 低波动=低风险,但收益更高——这和风险补偿理论矛盾 |
| 因素太多 | 如果每种收益差异都能用”某种风险”来解释,理论就失去了约束力 |
风险补偿理论最大的问题是”后验性”:先发现了因子,再去找”合理”的风险解释。这削弱了理论的预测能力。
二、行为金融解释
2.1 核心思想:因子有效是因为大多数人犯了心理偏差
如果风险补偿理论说”市场是对的,你得到了风险补偿”,那行为金融说:“市场经常犯错,因子溢价来自对错误的纠正”。
2.2 价值因子:投资者过度反应
故事:投资者看到一家公司连续几年业绩下滑,就认为”这家公司完了”,过度抛售导致价格过低。等到公司恢复增长,价格纠偏,价值投资者获利。
相关心理偏差:
- 锚定效应:投资者锚定过去的表现,低估了均值回归的可能性
- 外推偏差:把过去的趋势外推到未来
- 损失厌恶:不愿意卖出亏损的成长股(它们曾经是好公司)
2.3 动量因子:信息扩散缓慢
故事:好公司的利好消息不会一天就被市场完全消化。投资者需要时间来接收、理解、反应。在这个过程中,价格逐步上涨,形成了动量。
相关心理偏差:
- 处置效应:投资者倾向于”卖出赚钱的、持有亏钱的”,导致好的股票被过早卖出(减缓了上涨速度),坏股票被持有太久(减缓了下跌速度)
- 确认偏差:投资者倾向于寻找支持自己观点的信息
- 信息扩散的层级性:机构投资者先反应,散户后反应
2.4 规模因子:覆盖不足
故事:分析师和机构投资者主要覆盖大公司。小公司缺少研究覆盖和媒体关注,信息不对称更大,定价效率更低。
相关心理偏差:
- 注意力偏差:人们只关注”有名”的东西
- 羊群效应:机构投资者集中在少数大股票上
2.5 风险补偿 vs 行为金融:一个统一的框架
| 因子 | 风险补偿解释 | 行为金融解释 |
|---|---|---|
| 价值 | 困境公司的经营风险 | 投资者对坏消息过度反应 |
| 规模 | 小公司的融资和破产风险 | 小公司被分析师和机构忽视 |
| 动量 | 动量崩盘的尾部风险 | 信息扩散缓慢 + 处置效应 |
| 质量 | 高质量公司的可持续性不确定 | 投资者忽视”枯燥”的好公司 |
| 低波动 | (风险补偿理论无法解释) | 杠杆约束 + 基准竞争 + 彩票偏好 |
实际中,两种解释可能同时成立。某个因子的溢价可能部分来自风险补偿,部分来自行为偏差。区分两者的比例很难,但理解两种解释都有助于你判断因子的未来有效性。
三、市场摩擦
除了风险补偿和行为偏差,还有一些更”机械”的原因导致因子溢价。
3.1 流动性溢价
不好卖的资产,持有成本高。你需要补偿:
- 买卖价差
- 市场冲击成本
- 持仓等待时间
白话:流动性好的股票大家都愿意买,价格被推高;流动性差的股票没人愿意买,价格被压低。持有后者,你就获得了流动性溢价。
3.2 卖空限制
有些股票不能做空(或做空的成本极高)。这意味着:即使投资者认为某只股票被高估了,他也无法通过做空来纠正价格。高估的价格就维持着。
影响:
- 被高估的股票(通常是成长股、热门股)价格持续偏高
- 相对地,被低估的股票(价值股)就有正溢价
- 这是价值因子溢价的重要来源之一
3.3 搜索成本
投资者的时间和精力有限,不可能研究所有股票。信息获取和处理是有成本的。
影响:
- 投资者倾向于关注热门股票和知名公司
- 被忽视的股票(小公司、冷门股)可能有更大的错误定价
import numpy as np
import pandas as pd
np.random.seed(42)
# ============================================================
# 模拟搜索成本对因子溢价的影响
# ============================================================
n_stocks = 500
# 每只股票的信息不对称程度(越大越难获得信息)
info_cost = np.random.uniform(0, 1, n_stocks)
# 真实的内在价值
true_value = np.random.normal(100, 20, n_stocks)
# 市场价格 = 真实价值 + 定价误差
# 信息成本越高,定价误差越大
pricing_error = np.random.normal(0, 10 * info_cost, n_stocks)
market_price = true_value + pricing_error
# 错误定价的绝对值
mispricing = np.abs(pricing_error)
# 按 info_cost 分组
df = pd.DataFrame({
'info_cost': info_cost,
'mispricing': mispricing,
'market_price': market_price
})
df['cost_group'] = pd.qcut(df['info_cost'], 5,
labels=['极低', '低', '中', '高', '极高'])
print("搜索成本 vs 错误定价:")
print(df.groupby('cost_group')['mispricing'].describe()[['count', 'mean', 'std']])
# 结论:信息成本越高的股票,错误定价越大
# → 持有这些股票的投资者获得了"搜索成本溢价"四、数据挖掘 vs 真实 Alpha
4.1 核心问题
你发现了一个”新因子”——在样本内回测表现很好。问题是:这是真实的 Alpha,还是你只是”运气好”?
4.2 多重检验问题
假设你试了 1000 个因子,每个因子的 p 值阈值设为 0.05。
在零假设下(所有因子都无效),你期望有 个因子”显著”。但这些因子其实全是假的。
白话:试的越多,“碰巧”显著的越多。如果你在 1000 个因子中选最好的 10 个,当然很好看——但这是过拟合。
4.3 如何区分真实 Alpha 和数据挖掘?
| 方法 | 原理 | 具体做法 |
|---|---|---|
| 样本外检验 | 在”没见过”的数据上验证 | 留出 30% 数据做测试 |
| 经济直觉 | 有理论解释的因子更可信 | 因子是否有经济学逻辑? |
| 多市场验证 | 在不同市场/时间段都有效 | A 股有效的因子在美股也有效? |
| 调整显著性水平 | 考虑多重检验 | Bonferroni 校正: |
| 因子生存期 | 存活时间越长越可信 | 因子被发现后是否持续有效? |
4.4 Python:模拟多重检验问题
import numpy as np
import pandas as pd
np.random.seed(42)
# ============================================================
# 模拟 1000 个"假因子"
# ============================================================
n_factors = 1000
n_stocks = 300
n_months = 60
# 模拟数据:所有因子都是随机噪声,没有真实预测力
factor_returns = np.random.normal(0, 0.001, n_months) # 每月市场收益
stock_returns = np.random.normal(0.01, 0.06, (n_months, n_stocks))
# 对每个假因子做 Fama-MacBeth 回归
import statsmodels.api as sm
significant_count = 0
t_stats_all = []
for i in range(n_factors):
# 随机生成因子暴露(每次都不同 = 试 1000 个不同的因子)
exposure = np.random.normal(0, 0.5, (n_stocks, n_months)).T
# Fama-MacBeth:每月截面回归
monthly_coefs = []
for t in range(n_months):
y = stock_returns[t]
X = sm.add_constant(exposure[t])
try:
model = sm.OLS(y, X).fit()
monthly_coefs.append(model.params[1])
except:
continue
if len(monthly_coefs) > 10:
mean_coef = np.mean(monthly_coefs)
std_coef = np.std(monthly_coefs, ddof=1)
t_stat = mean_coef / (std_coef / np.sqrt(len(monthly_coefs)))
t_stats_all.append(t_stat)
# 传统标准:|t| > 2 就认为显著
if abs(t_stat) > 2:
significant_count += 1
t_stats_all = np.array(t_stats_all)
print("=" * 50)
print("多重检验问题演示")
print("=" * 50)
print(f"真实有效因子数: 0(全部是随机噪声)")
print(f"发现'显著'因子数: {significant_count} / {n_factors}")
print(f"最大 t 统计量: {np.max(np.abs(t_stats_all)):.2f}")
print(f"最小 t 统计量: {np.min(np.abs(t_stats_all)):.2f}")
print(f"\n如果你只报告显著的因子,就是在欺骗自己")
# Bonferroni 校正
bonferroni_threshold = 2.58 / np.sqrt(n_factors) # 更严格的阈值
bonferroni_significant = np.sum(np.abs(t_stats_all) > bonferroni_threshold)
print(f"\nBonferroni 校正后 (α = 0.05/{n_factors}):")
print(f" 校正后阈值: |t| > {bonferroni_threshold:.2f}")
print(f" 校正后显著因子数: {bonferroni_significant}")五、因子拥挤(Crowding)
5.1 什么是因子拥挤?
因子拥挤是指太多投资者使用同一个因子,导致因子的 alpha 被稀释。
白话版本:如果你发现了一个好因子,而且只有你一个人用,你赚大钱。但如果所有人都用了这个因子,你就赚不到钱了——因为所有人都买一样的股票,价格已经被推到合理水平了。
5.2 因子拥挤的后果
| 后果 | 说明 |
|---|---|
| Alpha 衰减 | 因子收益逐渐降低,趋近于零 |
| 回撤加大 | 当投资者同时卖出时,因子集中崩盘 |
| 波动率上升 | 拥挤因子的收益波动率增大 |
| 反转风险 | 拥挤因子可能突然反转 |
5.3 如何检测因子拥挤?
import numpy as np
import pandas as pd
np.random.seed(42)
# ============================================================
# 模拟因子拥挤的信号
# ============================================================
n_months = 120 # 10 年
# 模拟因子收益
# 前 5 年:不拥挤,因子有稳定溢价
# 后 5 年:越来越拥挤,溢价衰减,波动加大
factor_returns = np.zeros(n_months)
for t in range(n_months):
if t < 60:
# 不拥挤阶段:稳定溢价
factor_returns[t] = 0.005 + np.random.normal(0, 0.02)
else:
# 越来越拥挤:溢价衰减,波动加大
crowding = (t - 60) / 60 # 拥挤度从 0 到 1
premium = 0.005 * (1 - 0.8 * crowding) # 溢价衰减 80%
vol = 0.02 * (1 + crowding) # 波动率增加
factor_returns[t] = premium + np.random.normal(0, vol)
# ============================================================
# 检测拥挤的指标
# ============================================================
# 1) 滚动 12 个月 Sharpe
rolling_sharpe = pd.Series(factor_returns).rolling(12).apply(
lambda x: np.mean(x) / np.std(x) * np.sqrt(12) if np.std(x) > 0 else 0,
raw=True
)
# 2) 滚动 12 个月最大回撤
cumulative = (1 + pd.Series(factor_returns)).cumprod()
rolling_max = cumulative.rolling(12, min_periods=1).max()
rolling_drawdown = (cumulative - rolling_max) / rolling_max
# 3) 滚动相关性:因子收益之间的相关性上升(说明大家在交易同样的东西)
# 这里用因子收益的自相关作为代理
rolling_autocorr = pd.Series(factor_returns).rolling(12).apply(
lambda x: pd.Series(x).autocorr(lag=1) if len(x) > 2 else 0,
raw=True
)
# ============================================================
# 输出
# ============================================================
print("=" * 50)
print("因子拥挤检测")
print("=" * 50)
print(f"\n前 5 年(不拥挤):")
print(f" 年化收益: {np.mean(factor_returns[:60]) * 12:.2%}")
print(f" 年化波动: {np.std(factor_returns[:60]) * np.sqrt(12):.2%}")
print(f" Sharpe: {np.mean(factor_returns[:60]) / np.std(factor_returns[:60]) * np.sqrt(12):.2f}")
print(f"\n后 5 年(拥挤):")
print(f" 年化收益: {np.mean(factor_returns[60:]) * 12:.2%}")
print(f" 年化波动: {np.std(factor_returns[60:]) * np.sqrt(12):.2%}")
print(f" Sharpe: {np.mean(factor_returns[60:]) / np.std(factor_returns[60:]) * np.sqrt(12):.2f}")
print(f"\n拥挤指标变化:")
print(f" 前 5 年平均 Sharpe: {rolling_sharpe[:60].mean():.2f}")
print(f" 后 5 年平均 Sharpe: {rolling_sharpe[60:].mean():.2f}")5.4 应对因子拥挤
- 因子多样性:不要只押注一个因子,分散到多个不相关的因子
- 动态因子配置:根据拥挤度调整因子权重
- 寻找新因子:在主流因子拥挤之前,研究更细分的因子
- 交易频率差异化:避免和拥挤的资金在同一时间交易
六、因子轮动
6.1 核心思想
不同因子在不同的经济环境下表现不同。因子轮动就是根据经济环境动态调整因子配置。
6.2 经济周期与因子的关系
| 经济阶段 | 特征 | 表现好的因子 | 表现差的因子 |
|---|---|---|---|
| 复苏初期 | 增长加速、利率低位 | 动量、规模 | 价值、低波动 |
| 复苏后期 | 增长见顶、利率上升 | 价值、质量 | 规模、低波动 |
| 衰退初期 | 增长放缓、利率高位 | 低波动、质量 | 动量、规模 |
| 衰退后期 | 增长低迷、利率下降 | 价值、动量 | 低波动 |
6.3 价值 vs 成长的轮动
这是最常见的因子轮动。价值股和成长股的相对表现会随着利率环境变化:
- 利率上升:折现率上升 → 远期现金流的现值下降 → 成长股受损(它们的价值更多来自远期)→ 价值股相对受益
- 利率下降:折现率下降 → 远期现金流的现值上升 → 成长股受益 → 价值股相对受损
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.random.seed(42)
# ============================================================
# 模拟 10 年的价值/成长轮动
# ============================================================
n_months = 120
# 模拟利率周期(正弦波 + 噪声)
interest_rate_cycle = np.sin(np.linspace(0, 3 * np.pi, n_months)) * 0.5
rate_change = np.diff(np.concatenate([[0], interest_rate_cycle]))
# 价值因子收益:利率上升时表现好
value_returns = 0.003 + 0.01 * rate_change + np.random.normal(0, 0.02, n_months)
# 成长因子收益:利率下降时表现好
growth_returns = 0.003 - 0.01 * rate_change + np.random.normal(0, 0.02, n_months)
# 累计收益
value_cum = (1 + pd.Series(value_returns)).cumprod()
growth_cum = (1 + pd.Series(growth_returns)).cumprod()
print("价值 vs 成长轮动(模拟 10 年):")
print(f" 价值因子累计收益: {value_cum.iloc[-1] - 1:.2%}")
print(f" 成长因子累计收益: {growth_cum.iloc[-1] - 1:.2%}")
print(f"\n 相关系数: {np.corrcoef(value_returns, growth_returns)[0,1]:.3f}")
print(" (价值和成长通常负相关,这是轮动的基础)")6.4 因子轮动的风险
- 宏观指标滞后:你用到的经济数据有延迟,等你确认经济阶段时,轮动可能已经发生了
- 过度交易:频繁轮动会产生大量交易成本
- 非线性关系:经济阶段和因子的关系不是稳定的,历史规律可能失效
七、跨市场因子可移植性
7.1 核心问题
一个在美股有效的因子,在 A 股、港股、欧洲市场也有效吗?
7.2 因子的跨市场有效性
| 因子 | 美股 | A 股 | 欧洲 | 日本 | 新兴市场 |
|---|---|---|---|---|---|
| 价值 | 强 | 中 | 强 | 中 | 弱 |
| 规模 | 中 | 强 | 中 | 强 | 强 |
| 动量 | 强 | 弱 | 强 | 弱 | 弱 |
| 质量 | 中 | 中 | 中 | 弱 | 中 |
| 低波动 | 中 | 强 | 中 | 中 | 弱 |
关键发现:
- 价值和规模在全球都比较稳健
- 动量在发达市场很强,但在 A 股和日本较弱(短期反转更明显)
- 低波动在 A 股特别有效(A股散户多,偏好”暴富”股票,推高高波动股票价格)
7.3 为什么跨市场有效性不同?
| 原因 | 说明 |
|---|---|
| 投资者结构 | A 股散户多,美股机构多 → 行为偏差类型不同 |
| 做空限制 | A 股做空难 → 错误定价更难被纠正 |
| 信息环境 | 发达市场信息披露更完善 → 错误定价空间更小 |
| 制度差异 | 涨跌停、T+1 等制度影响因子实现方式 |
| 文化因素 | 不同文化对风险的偏好不同 |
7.4 跨市场研究的建议
- 不要直接照搬:美股的因子参数不能直接用于 A 股
- 本地化调整:调整因子构造方法以适应本地市场特征
- 样本外验证:在每个市场独立验证因子的有效性
- 理解机制:理解因子在特定市场有效的机制,而不是只看结果
小结
| 问题 | 主要解释 |
|---|---|
| 因子为什么有效? | 风险补偿 + 行为偏差 + 市场摩擦(三者共存) |
| 是风险还是错误定价? | 因子而异,但多数因子两者兼有 |
| 是真实 Alpha 还是数据挖掘? | 需要多重检验校正、样本外验证、经济直觉 |
| 因子会失效吗? | 会,拥挤导致 alpha 衰减 |
| 如何管理因子? | 因子多样性、动态配置、拥挤监控 |
最核心的教训:因子投资不是”找到一个永远有效的公式”。因子是一个有经济学基础的、会在特定环境下失效的、需要持续管理的投资框架。
→ 下一章:03-因子研究方法论 —— 从统计角度验证因子是否真的有效