halo 的技术博客

返回

有效市场假说最尴尬的反例之一,就是盈余预告(或盈余公告)后股价不立刻到位,而是沿惊喜方向慢慢漂。这就是经典的 PEAD(Post-Earnings-Announcement Drift,盈余公告漂移)。但大多数 PEAD 文章只做到「公告后 60 天 CAR 单调」这一步——是截面快照。

这篇文章把预告惊喜从「一个异象」升级成「一个因子」:

GSI(Guidance Surprise Index,标准化盈余预告惊喜)= 真实盈利惊喜 − 卖方一致预期,再按截面标准差标准化,构建月度再平衡的横截面因子,多高惊喜 / 空低惊喜(含负惊喜),验证它长期为正、十分组严格单调,并画预告后 12 个月 CAAR 衰减直接看到「漂移」本身。

数据声明:全文为自洽合成(含保守主义:卖方共识只缓慢跟随真实盈利变化,所以预告天然滞后于基本面),目的是把 GSI 因子的构建与检验机制跑通、可复现。所有量级均为合成校准,真实市场里会被覆盖偏差、做空成本、幸存者偏差大幅压缩——重点看方法

一、GSI 怎么算:把「惊喜」变成可比较的截面信号#

每只股票每月有一组真实盈利路径,以及一组「慢半拍」的卖方一致预期。定义:

# 真实盈利惊喜 vs 卖方一致预期
surprise = true_eps - consensus
# 按截面标准差标准化 → 可跨月比较的 GSI
gsi_sd = surprise.std(axis=0, keepdims=True) + 1e-6
GSI = surprise / gsi_sd
python

关键设计:

  1. 标准化,不裸用绝对值。不同月份、不同板块的「惊喜单位」不一样,除以截面标准差后,GSI 才有跨截面可比性(这正是 PEAD 文献里 SUE 的标准做法)。
  2. 一致预期用保守主义生成:共识只 70% 锚定上期、30% 跟随真实盈利。所以真实盈利一变,共识要滞后好几期才跟上——这种「慢半拍」正是漂移的来源。
  3. GSI 允许为负(预告下修、甚至变脸)。因子是对称的:多正惊喜、空负惊喜。

截面分布长这样——多数月份接近零,右尾为正向惊喜累积,左尾为负向下修:

GSI 截面分布:多数月份接近零,右尾为正向惊喜累积

二、从「异象」到「因子」:月度再平衡的长短组合#

异象回答「截面里有没有这个现象」;因子回答「我能不能持续、可复制地用它赚钱」。我们每月末按 GSI 排序,多最高 60 只 / 空最低 60 只,累计成因子净值:

def ls_curve(signal, n=60):
    ret = np.zeros(M)
    for t in range(M):
        order = np.argsort(signal[:, t])
        ret[t] = future[order[-n:], t].mean() - future[order[:n], t].mean()
    return np.cumprod(1 + ret)

gsi_cum = ls_curve(GSI)
python

GSI 长短因子:高惊喜多/低惊喜空,长期为正

净值长期向上,但注意——它不是一条平滑直线,而是被市场 beta 和个股噪声反复拉扯。这正是真实因子该有的样子:有趋势、有波动、没有「印钞机」幻觉。

三、十分组单调性:D1→D10 严格递增#

判断一个信号是不是「真因子」,最朴素也最硬的一刀是看分组是不是单调。我们把每月截面按 GSI 切成 10 组,算每组未来 1 月平均收益:

dec_avg = np.zeros(10)
for t in range(M):
    order = np.argsort(GSI[:, t])
    for d in range(10):
        idx = order[d * 60:(d + 1) * 60]
        dec_avg[d] += future[:, t][idx].mean()
dec_avg /= M
python

结果 D1(最负惊喜)到 D10(最正惊喜)严格单调递增:

GSI 十分组:单调递增,D10-D1 显著为正

单调性意味着没有「断点」或「倒挂」——高 GSI 组每一档都比低一档好。这是「信号是连续有效、而非个别极值驱动」的直接证据。真实数据里这条曲线一般会更平、端点没这么极端,但单调方向通常保持。

四、直接看「漂移」:预告后 12 个月 CAAR 衰减#

PEAD 的灵魂是「漂移」二字。我们不只是看下月收益,而是把最高惊喜组和最低惊喜组的**异常收益(减市场)**分别累积 12 个月:

预告后 12 个月 CAAR:高惊喜组持续走强,差距前 6 月拉开后走平

这张图把「漂移」画活了:

  • 高惊喜组(蓝)CAAR 持续上行,低惊喜组(红)持续落后——差距就是漂移本身。
  • 差距前 6 个月快速拉开,之后走平。这恰好对应「市场用半年时间慢慢把预告信息吸收完」的行为金融解释:不是不反应,是反应太慢
  • 走平后不再扩大,说明漂移有「半衰期」,不是无限累积——这对持有期设计(持有 3~6 个月再换仓)是直接的操作指引。

五、为什么会有漂移:三个微观解释#

  1. 保守主义(conservatism)。投资者(包括分析师)对新信息反应不足,锚定旧预期。共识慢半拍 → 价格也慢半拍。心理学实验里,人对连续信号的更新速度天然慢于贝叶斯最优,这是 PEAD 最底层的认知根源。
  2. 有限注意力(limited attention)。散户不会逐字读每份预告,机构也只在既定调仓窗口重新评估持仓。信息被逐步扩散到价格里,而不是公告瞬间一次性反映。
  3. 套利限制(limits to arbitrage)。PEAD 多空需要同时做多小盘+做空「坏消息」股,而坏消息股往往流动性差、做空成本高,套利者无法瞬间消除定价错误,错误被保留成可交易的漂移。

这三点合起来,就是「有效市场说的『该秒到位』,实际『慢半年才到位』」的完整因果链。

它和《分析师修正动量》《PEAD》是什么关系#

  • PEAD(盈余公告漂移) 是母题:公告后价格沿惊喜方向漂。
  • 分析师修正动量(REV) 看的是「一致预期在往哪个方向变」,是预告 之前 的预期层面信号。
  • 本文的 GSI 直接看「实际公告/预告相对一致预期的偏差」,是预告 之后 的已兑现惊喜。

三者是同一枚硬币的不同切面:REV 赚「预期还在调」,GSI 赚「预期调完了价格还没跟上」。组合里两者相关性不高,可以互补叠加。

六、真实的四类陷阱(必须说清楚)#

陷阱一:公告前视(look-ahead)。 GSI 用「真实盈利」减「一致预期」。真实盈利在公告日 之后 才知道。回测里若用已公告的真实盈利算惊喜、却在公告前交易,就是作弊。正确做法:惊喜在公告日确定,信号在公告后第一个调仓点(月末)才可用,持有从下月算起。

陷阱二:做空约束。 因子要「空低 GSI / 空负惊喜」。但 A 股融券难、美股小盘做空借券贵,负惊喜组往往正是流动性最差的一批。空头腿在真实市场里会被成本吞掉大半,甚至根本建不起来——所以实盘更常见的是「只做多高 GSI」的半截策略。

陷阱三:幸存者偏差。 合成面板里所有股票都活满 12 年。真实里,最负的 GSI 常常伴随退市/ST——而这些本该进空头组的样本从指数里消失了,让历史回测的空头收益被系统性高估。

陷阱四:覆盖偏差。 卖方一致预期只覆盖被券商覆盖的中大盘股。小盘股没有一致预期,GSI 对它无定义——而 PEAD 在小盘上的漂移往往更强。只用有覆盖的股票,等于主动放弃最强的一段信号。

七、落地路径(真实数据怎么做)#

把合成机制换成真实数据,骨架不变:

  1. 取预告/公告数据:Wind/聚源/Compustat 的业绩预告、盈余公告、一致预期(EPS 预测中位数)。
  2. 算 SUE/GSI(实际 EPS − 预期 EPS) / 预期 EPS 的滚动标准差,或直接用分析师预测修正(参见《分析师修正动量》那篇的 REV)。
  3. 横截面 z 标准化,月末排序分层,多高组空低组。
  4. 持有设计:CAAR 图显示漂移半衰期约 6 个月,建议持有 3~6 个月再换仓,而非每月全换(省成本、吃满漂移)。
  5. 行业/市值中性化:GSI 常顺带暴露规模,建议对行业哑变量 + 对数市值回归取残差,避免「买小盘」马甲。

七、和「股息率 / 回购」因子的区别(顺带一提)#

盈余漂移(GSI)赚的是「已兑现惊喜后的价格惯性」,属于事件后的惯性因子;而回购强度赚的是「内部人当下的低估判断」,属于资本动作因子。两者正交:一个看「过去盈利超预期没」,一个看「管理层现在愿不愿买」。在组合里可以同时持有,相关性低、互补性强。

八、小结#

盈余预告惊喜因子的核心一句话:市场对公司盈利预告反应不足,预告后股价沿惊喜方向缓慢漂移 6 个月左右。用标准化 GSI 把它做成月度再平衡横截面因子,验证十分组严格单调、长短因子长期为正、且 CAAR 衰减图直接可视化了「漂移」本身。它不是免费午餐——公告前视、做空约束、幸存者偏差、覆盖偏差四道坎,每一道都在真实落地时把收益砍一刀。但正因为它有这些「不完美」,它才几十年没被套利干净,至今仍是实盘里最朴素也最耐用的一类信号。

代码与配图均由自洽合成数据真实计算生成,可复现;真实量级请以你的数据重跑为准。

盈余预告惊喜与漂移:把『预告反应不足』做成可交易的横截面因子
https://blog.halo26812.eu.org/blog/earnings-guidance-drift
Author halo
Published at 2026年7月20日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨