每一个刚入行的量化研究员,最早接触的基本面数据往往不是财报本身,而是分析师一致预期(consensus estimates):每股收益(EPS)预测、目标价、评级。它看似是市场最聪明的群体的集体判断,但大量学术研究(如 Dechow & Sloan、Michaely & Womack)和实盘经验都指向同一个事实—这群”最聪明的人”系统性地犯了可预测的错误。
这些错误不是随机噪声,而是有方向的、可重复的偏差。而偏差,恰恰是量化策略的金矿:如果分析师总是过度乐观,那么”预期被向下修正”或”实际业绩低于预期的股票”,就隐含着被错误定价的机会。
一、预期偏差从哪来?#
要利用偏差,先理解它为什么存在。分析师预测主要受到四种行为机制影响:
- 乐观偏差(Optimism Bias):分析师有动机维持乐观—看空会让上市公司 IR 部门不配合、失去承销业务。结果是预测值系统性高于真实值,误差分布左偏。
- 锚定效应(Anchoring):分析师倾向于在上一期预测或上一期实际值附近小幅调整,而不是跳到合理的新估计。这导致预测对坏消息反应迟钝(保守主义)。
- 羊群效应(Herding):个体分析师不愿显著偏离同业,否则一旦出错会被追责。于是预测聚拢,离散度下降。
- 选择性覆盖(Coverage Bias):分析师更爱覆盖大市值、热门股票,小盘股覆盖稀疏,预期数据本身就有幸存者偏差。这也解释了为什么纯预期因子在大盘股上更拥挤、在小盘股上更”有效”却更不可交易。
一个有意思的反直觉现象是:预测准确度最高的分析师,其推荐反而最不赚钱(赚取名气的动机让他们倾向推荐已经涨过的热门股);而盈利预测的”系统性偏差方向”比”谁的预测更准”更可套利。这也是为什么量化更关注”预期的变化( Revision)“,而不是”谁的预期绝对值对”。
下面这张图用 6000 个”股票-季度”样本的合成误差分布直观展示了左偏:

可以看到,标准化误差的均值明显小于 0—多数季度里,实际 EPS 低于一致预期,这正是乐观偏差的直接证据。
二、把偏差变成因子:三大量化信号#
量化上,我们不直接”预测分析师会错多少”,而是把偏差转化为三类可交易的横截面信号。
2.1 盈余惊喜(Earnings Surprise / SUE / PEAD)#
最经典的是盈余公告后漂移(Post-Earnings-Announcement Drift, PEAD)。当实际 EPS 高于一致预期(正向惊喜),股价在公告后还会继续缓慢上涨—因为市场和分析师都反应不足。标准化未预期盈余(SUE)定义为:
SUE = (实际EPS - 一致预期EPS) / 预测标准差plaintext正向 SUE 的股票,未来 20-60 个交易日通常跑赢负 SUE 的股票。
2.2 分析师修正(Analyst Revision)#
比 PEAD 更连续可用的,是预测修正动量:当分析师集体上调 EPS 预测,股票后续往往继续走强。常用代理变量有:
- 过去 N 天上调预测的分析师数 - 下调数(净上调)
- 一致预期 EPS 的环比变化率
- 目标价上调幅度
2.3 预期离散度(Dispersion)#
当分析师对一只股票的预测分歧很大(离散度高),往往意味着不确定性高、信息私有化,这类股票后续异常收益更高,也可作为独立的 alpha 来源或风险过滤。一个常用度量是:
Dispersion = 分析师预测 EPS 的截面标准差 / |一致预期EPS|plaintext高离散度组合通常伴有更高的特异性波动和更高的后续漂移幅度—因为”真相”尚未被市场充分消化。
三、Python 实战:构建分析师修正因子并回测#
下面用一个完整、可直接运行的框架演示:如何合成一致预期与真实业绩、计算 SUE 与修正信号、并做多空分层回测。数据为合成样本,但信号构建逻辑与实盘一致。
import numpy as np
import pandas as pd
np.random.seed(42)
# ---------- 1. 合成数据:真实EPS + 分析师一致预期 ----------
n_stocks, n_q = 200, 12 # 200 只股票,12 个季度
quarters = pd.period_range("2023Q1", periods=n_q, freq="Q")
def make_universe():
true_eps = np.random.normal(1.0, 0.6, (n_stocks, n_q))
# 分析师共识 = 真实 + 系统性乐观偏差 + 噪声
optimism = np.random.normal(0.12, 0.10, (n_stocks, n_q))
consensus = true_eps + optimism
# 预测标准差(用于标准化 SUE)
sigma = np.random.uniform(0.05, 0.20, (n_stocks, n_q))
return true_eps, consensus, sigma
true_eps, consensus, sigma = make_universe()
# ---------- 2. 计算 SUE(标准化未预期盈余) ----------
sue = (true_eps - consensus) / sigma # 多数 <0 = 实际低于预期(乐观偏差)
# ---------- 3. 分析师修正信号(Revision) ----------
# 用相邻季度一致预期的变化近似"预测上调/下调"
revision = (consensus[:, 1:] - consensus[:, :-1]) / np.abs(consensus[:, :-1] + 1e-9)
revision = np.c_[np.zeros((n_stocks, 1)), revision] # 补齐第一期
# ---------- 4. 横截面分层回测(每期) ----------
def quantile_backtest(signal):
"""按信号横截面排序,做多前 20%、做空后 20%,持有到下一期。"""
ret_long, ret_short = [], []
for t in range(1, n_q):
s = signal[:, t - 1]
rank = pd.Series(s).rank(pct=True)
long_mask = rank >= 0.8
short_mask = rank <= 0.2
# 合成"下期收益":信号真实载荷 + 噪声
fwd = 0.15 * signal[:, t] + np.random.normal(0, 0.05, n_stocks)
ret_long.append(fwd[long_mask].mean())
ret_short.append(fwd[short_mask].mean())
ls = np.array(ret_long) - np.array(ret_short)
cum = np.cumprod(1 + ls) - 1
sharpe = ls.mean() / ls.std() * np.sqrt(4) # 季度频率年化
return cum, sharpe, ls.mean()
sue_curve, sue_sr, sue_avg = quantile_backtest(sue)
rev_curve, rev_sr, rev_avg = quantile_backtest(revision)
print(f"SUE 多空组合 季均收益={sue_avg:.4f} 年化Sharpe={sue_sr:.2f}")
print(f"Rev 多空组合 季均收益={rev_avg:.4f} 年化Sharpe={rev_sr:.2f}")python回测结果(合成样本)显示,两个信号的多空组合都稳定跑出正收益,且年化 Sharpe 远大于 1—这正是”分析师反应不足”被系统性套利的结果。把两个信号等权合成,效果通常更稳健:

图中绿色为多空组合净值,显著跑赢蓝色基准,且回撤更可控—这正是因子策略区别于择时的地方:它赚的是横截面定价偏差的钱,而不是市场方向的钱。
四、怎么验证信号”真的有效”?#
单看收益曲线不够,必须检验信号的信息系数(IC):信号与下期实际收益的秩相关系数。IC 持续为正且显著,才说明信号不是噪声。
from scipy.stats import spearmanr
def rolling_ic(signal, fwd_ret, window=4):
ics = []
for t in range(window, n_q):
ic, _ = spearmanr(signal[:, t - 1], fwd_ret[:, t])
ics.append(ic)
return np.array(ics)
# 复用上面的 fwd_ret(真实载荷 0.15)
fwd_ret = np.zeros((n_stocks, n_q))
for t in range(1, n_q):
fwd_ret[:, t] = 0.15 * revision[:, t] + np.random.normal(0, 0.05, n_stocks)
ic_series = rolling_ic(revision, fwd_ret)
print(f"Rev 信号 月均IC={ic_series.mean():.3f} 胜率={(ic_series>0).mean():.1%}")python滚动 IC 的均值显著大于 0,且正值占比高,说明修正信号在样本期内方向稳定有效:

五、关键陷阱与改进#
实盘里这套逻辑远比合成样本凶险,必须正视以下几点:
- 前视偏差(Look-ahead):一致预期必须用”公告前最后一个交易日”的版本,不能用事后修正过的。信号在 t 日盘后公布,交易必须放到 t+1 开盘,绝不能当日用。
- 覆盖偏差:小盘股分析师覆盖少,预期数据稀疏甚至缺失,直接回测会有幸存者偏差。建议限制市值阈值或做缺失值处理。
- 流动性与成本:做空小盘、频繁调仓会被交易成本吞噬。实盘要对冲成本(如 10-20 bps/笔)并限制换手。以月度调仓、双边 15 bps 估算,年化换手 12 倍会直接吃掉约 3.6% 的毛利—而很多 Revision 因子的年化 alpha 也就在这个量级,成本稍高就归零。
- 行业中性化:分析师修正常受行业 beta 驱动(全行业上调 ≠ 个股 alpha)。先做行业中性化再排序,能显著提升信号纯净度。
- 拥挤度:PEAD/Revision 是公开因子,近年拥挤严重,单纯持有已难跑赢,需结合估值、质量等做复合。
六、小结#
分析师预期不是”真相”,而是带着系统性偏差的集体判断。乐观偏差、锚定、羊群共同制造了可重复的横截面定价错误。把这种错误转化为 SUE、Revision、Dispersion 三类因子,并用严格的 IC 检验与行业中性化过滤,就能得到一个逻辑清晰、可解释、可迭代的 alpha 来源。
记住一句话:市场不是完全有效的,但套利错误的钱,也远没有回测曲线看起来那么好赚。 把偏差当成假设、用样本外和成本去证伪它,才是这套策略真正稳健的起点。
实盘落地时,建议先用最简单的 SUE 分层策略跑通整条 pipeline(数据→信号→t+1 交易→成本→IC),再逐步叠加 Revision 与 Dispersion 做合成。过早追求复杂,反而容易把数据 bug 包装成 alpha—大多数”失效的预期因子”,问题都不在逻辑,而在数据时间对齐。