← 返回模块
4.3.1.2beta 可读 · 未来免费校验通过内容版本 2026-05-28

因子动物园与复现危机

4.3.1 · 因子动物园与因子构建 · 量化全流程

国内某多空选股私募的资深研究员把一篇顶刊工作论文转给了基金经理:「作者在沪深300成分股范围内构造了一个基于净经营资产应计的因子,样本内夏普 1.8,t 值 2.4。是否纳入生产合成因子?」基金经理翻到方法论页只回了三行字:「三个问题。(1) 论文 t 值 2.4——文献已经发了大概 300 个这种因子,多重检验调整后的门槛是多少?(2) 用了断点宇宙断点和市值加权吗?(3) 结果在 Chen-Zimmermann 或 HXZ 2020 里被复现了吗?」研究员核对:门槛约为 3.0,论文用了全样本断点和等权,结果不在两个复现库中。判定:剔除。在文献规模面前,2.4 的 t 值在统计上已与噪声无异。本节课教的是 L1 因子定价框架的元视角——发表过的几百个异象里,实际上 有多少能跨过一个站得住脚的统计门槛,以及这个门槛该取多严。

因子动物园的实证增长曲线

到 1995 年大约有 25 个因子和异象被记录:规模、价值、动量、杠杆、股息收益率、一月效应、周末效应、盈利公告漂移(post-earnings drift)、长期反转、短期反转。到 2010 年大约 80 个:FF5 的各成分被命名,加上应计利润(accruals)、净股票发行(net stock issues)、资产增长率(asset growth)、外部融资(external financing)、总利润率(gross profitability)、低波动、贝塔套利(betting-against-beta)、特质波动率(idiosyncratic volatility)等几十种。John Cochrane 2011 年 AFA 主席致辞《Discount Rates》里那句「我们有一个新因子动物园」(we have a zoo of new factors)从此固定下来。到 2016 年 Harvey-Liu-Zhu 在 JFE 上盘点了 316 个发表过的因子。到 2020 年 Hou-Xue-Zhang 的复现研究覆盖了 452 个异象。整个 2010 年代,因子发表速度大致线性,每年新增 15-30 个,且文献至今仍在扩张。

1. ~25_factors_by_1995
2. ~80_factors_by_2010
3. ~316_factors_by_HLZ_2016
4. ~452_factors_by_HXZ_2020

四个分年计数标签、约每年 15-30 个新因子的增长率、以及「a t-stat > 2 bar is mechanically wrong with this many tests」这条规则,跨地区逐字一致。机械含义很直接:在 t > 1.96 这条单检验门槛下,一个跑了 316 次检验的文献,按 5% 双侧名义水平,光靠运气就能撞出大约 316 × 0.025 ≈ 8 个「异象」——而且这是每 一轮 检验的虚假数量,不是整段样本期内的累计。常规门槛在结构上不够用。

多重检验调整后的 t 值门槛

Harvey、Liu、Zhu 2016 的《And the Cross-Section of Expected Returns》做的正是这件正经事:在 K ≈ 316 个已记录检验上,要把整族错误率(family-wise error rate, FWER)或假发现率(false discovery rate, FDR)控制在 5%,所需 t 值门槛是多少?他们的分解:

1. t_conventional = 1.96                                              (5% two-sided, K=1 test)
2. t_bonferroni_HLZ_316 = Phi^-1(1 - 0.025/316) ≈ 3.39
3. t_BH_FDR_HLZ ≈ 3.0                                                 (HLZ recommended practitioner threshold)
4. t_Bayesian_Harvey_2017 ≈ 3.0                                       (the posterior-probability-of-true-effect-aware bar)

四个门槛标签、数值(1.96 / 3.39 / 3.0 / 3.0)、以及「任意 t 值在 [2.0, 3.0] 区间的异象,在多重检验调整后都属于可疑」这条规则,跨地区逐字一致。Bonferroni 校正把单检验 alpha 乘以 K,把 FWER 限在目标水平;对 K = 316 与整体 alpha = 0.05(双侧),单检验 alpha 为 0.05 / 316 ≈ 1.6e-4,对应 t 临界值约 3.39。Benjamini-Hochberg FDR 门槛——它控制的是 假发现的期望比例 而非 FWER——更宽松,落在 t ≈ 3.0 附近。Harvey 2017 的贝叶斯后验门槛纳入了文献中真效应比例的先验,从业者推荐口径下也约为 3.0。

从业者规则:t 值落在 [2.0, 3.0] 区间的异象都属于 可疑——可能是真的,也可能是噪声,光看统计证据无法判定。只有 t 值 > 3.0 才跨过多重检验调整后的门槛。这就是对 L1 常规门槛的 L2 通胀修正。

McLean-Pontiff 出版后衰减

样本内 t 值 > 3 还不是终点。McLean 与 Pontiff 2016 在 JF 上的《Does Academic Research Destroy Stock Return Predictability?》对 97 个已发表异象做了出版后的样本外检验。他们记录到平均出版后衰减约为样本内多空溢价的 58%,并把衰减分解为三个来源:

1. total_OOS_decay ≈ 58%                              (of in-sample long-short premium)
2. statistical_bias_OOS ≈ 26%                          (in-sample data-snooping that the OOS period removes)
3. economic_decay_OOS ≈ 32%                            (post-publication arbitrage / publication-effect)
4. surviving_premium ≈ 42%                             (the residual real premium that does not decay)

四个分解标签、百分数(58 / 26 / 32 / 42)、以及「典型已发表异象的样本内溢价,约有一半会在样本外消失」这条规则,跨地区逐字一致。分解之所以重要,在于它给出了两类不同的失败:26% 的统计偏差成分是样本内过拟合,只要走出原始样本窗口就会消失(这是合规的样本外检验所揭示的部分);32% 的经济衰减成分是出版后的套利——读到论文的从业者反向交易那个错误定价,部分纠正了它(这是出版行为本身造成的部分)。剩下 42% 的存活溢价,是两类衰减都无法吃掉的那一部分——就是能贴上 L2 production-grade 标签的 真实 溢价。

HXZ 2020 复现研究

Hou、Xue、Zhang 2020 在 RFS 上的《Replicating Anomalies》把上述工作做到了更激进的版本。他们从零按 FF 规范(断点宇宙断点 + 市值加权 + 排除微小盘)重建了 452 个发表过的异象,每个都检验 t 值是否大于 1.96。结论:只有约 50% 的 452 个异象,连常规的 t > 1.96 门槛都跨不过。剩下的一半,只有在原始论文采用的 等权、全样本断点 或 含微小盘 选择下才「跑得通」——而这些恰恰是机械性地把小盘溢价吹高的选择。在跨过 t > 1.96 的一半里,再加 t > 3 的过滤,数量缩到大约 100 个;再加 Chen-Zimmermann(开源资产定价库, openassetpricing.com)复现与可信经济故事的过滤,只剩几十个。

按经济内容聚类,存活异象集中在为数不多的几个主题上:

1. value                          (HML, E/P, CF/P)
2. momentum                       (12-1, 12-7, industry-mom, TSMOM)
3. profitability                  (RMW, gross-profitability, ROE)
4. investment                     (CMA, asset-growth, net-stock-issues, accruals)
5. low_volatility                 (low-idio-vol, BAB)
6. quality                        (QMJ, profitability + growth + safety + payout)
7. liquidity                      (Pastor-Stambaugh liquidity beta)
8. size_after_LSY_adjustment      (CN: yes after bottom-30% exclusion; US: largely disappeared post-1982)

八个聚类标签的顺序、以及「除此之外的异象,在跨过 L2 检查清单之前都属于可疑」这条规则,跨地区逐字一致。聚类才是复现危机的实操含义:并不存在 452 个独立的异象;只存在 6-8 个 聚类,每个聚类下挂着几个相近的实现。规模因子是失败模式的典型:Banz 1981 原始的规模效应在 1982 年(那篇论文发表的年份,这一巧合 McLean-Pontiff 也注意到了)之后的美股上几乎消失,但在国际样本里重新出现,在 A 股数据里则需要做 LSY 调整后才存活——排除市值最低的 30%,因为那里的规模效应被次新股 IPO 抽奖式异象污染。

五点异象阅读清单

这节课要装进研究员脑子里的纪律,是一份五点清单,用来对每一篇新读到的因子论文做评估:

1. t_stat_gt_3                                          (HLZ Bonferroni / BH bar)
2. main_board_breakpoints_and_value_weighted            (FF-canonical methodology)
3. credible_economic_story                              (risk-based or behavioural — forward-pointer to L4)
4. replicated_in_open_library                           (Chen-Zimmermann or HXZ 2020)
5. post_publication_OOS_evidence                        (McLean-Pontiff or successor; what is the decay)

五个清单标签、它们的顺序、以及「五项里任意一项不过,真实异象的概率 < 30%」这条规则,跨地区逐字一致。五项可以分成三类统计(1、2、5)、一类经济(3)、一类交叉验证(4)。统计三项问的是:论文是否跨过了 L1 多重检验调整门槛、L3 规范化方法学门槛、自然实验式的样本外门槛?经济一项问的是:作者是否给出了一个可引用的「为什么」?交叉验证一项问的是:有没有原作者团队之外的人复现了结果?五项全过的是生产级;过 3-4 项的是候选(值得开影子模拟组合);过 0-2 项的是可疑(剔除)。

代码:规范化的异象清单应用

def evaluate_anomaly(paper_metadata: dict, replicated_returns: pd.Series,
                     factor_benchmark_returns: pd.DataFrame,
                     ts_alpha_test_fn: Callable) -> dict:
    """应用 L2 五点异象阅读清单。

    paper_metadata          : dict, 键含 t_stat_in_sample, breakpoints, weighting,
                              replicated_in_open_library, economic_story, post_pub_OOS_decay
    replicated_returns      : 候选异象的月度多空收益序列
    factor_benchmark_returns: FF5 (或 HXZ4 或 LSY-3) 基准因子收益 DataFrame
    ts_alpha_test_fn        : L1 中的 ts_alpha_test 函数

    返回 dict, 键: t_stat_in_sample, t_stat_alpha_vs_ff5, passes_hlz_bar,
    uses_ff_canonical_methodology, has_economic_story, replicated_in_open_library,
    post_pub_oos_decay_pct, verdict (取值 'production_grade', 'candidate', 'suspect' 之一)。
    """
    import statsmodels.api as sm
    t_in = paper_metadata['t_stat_in_sample']
    alpha_result = ts_alpha_test_fn(replicated_returns, factor_benchmark_returns)
    t_alpha = alpha_result['alpha_t_stat']
    passes_hlz = t_in > 3.0 and t_alpha > 3.0
    ff_canonical = (paper_metadata['breakpoints'].startswith('main_board')
                    and paper_metadata['weighting'] == 'value_weighted')
    has_story = paper_metadata['economic_story'] not in (None, 'data_mining', '')
    replicated = paper_metadata['replicated_in_open_library']
    decay_pct = paper_metadata.get('post_pub_OOS_decay')
    checks = [passes_hlz, ff_canonical, has_story, replicated, decay_pct is not None]
    n_passed = sum(checks)
    if n_passed == 5:
        verdict = 'production_grade'
    elif n_passed >= 3:
        verdict = 'candidate'
    else:
        verdict = 'suspect'
    return {
        't_stat_in_sample': t_in,
        't_stat_alpha_vs_ff5': t_alpha,
        'passes_hlz_bar': passes_hlz,
        'uses_ff_canonical_methodology': ff_canonical,
        'has_economic_story': has_story,
        'replicated_in_open_library': replicated,
        'post_pub_oos_decay_pct': decay_pct,
        'verdict': verdict,
    }

函数名 evaluate_anomaly、参数名、返回 dict 键、以及 verdict 枚举值 production_grade / candidate / suspect,跨地区逐字一致。

Formula Explorer

t_{\text{Bonferroni}} = \Phi^{-1}\left(1 - \frac{0.025}{K}\right)

练习

Exercise

你拿到一组候选异象数据,沪深300成分股范围,2018-01 至 2023-12:paper_metadata = {'t_stat_in_sample': 2.4, 'breakpoints': 'full_universe_decile', 'weighting': 'equal_weighted', 'replicated_in_open_library': False, 'economic_story': 'data_mining', 'post_pub_OOS_decay': None},以及复现后的月度多空收益 replicated_returns 与区域基准因子 factor_benchmark_returns(CN 用 LSY-3 + UMD + 低波;股票宇宙在 SSE 与 SZSE 主板,样本剔除 涨跌停 日与 T+1 结算约束下的次新股,沪深300 范围,数据自 CFFEX-清算口径下的标准日线)。

(i) 用 Phi^-1(1 - 0.025/316) 算 K=316 下的 HLZ Bonferroni 门槛,确认约为 3.39;算 HLZ BH-FDR 门槛约为 3.0;判断 t_stat_in_sample = 2.4 是否跨过常规门槛(是, t > 1.96),以及是否跨过 HLZ 多重检验调整门槛(否, t < 3.0)。

(ii) 跑 L1 TS alpha 检验:replicated_returnsfactor_benchmark_returns 做回归,HAC maxlags=6;报告 alphaalpha_t_statalpha_p_value

(iii) 应用五点清单(HLZ 门槛 / FF 规范化方法学 / 经济故事 / 复现 / 样本外衰减);给出一个 5 维 pass/fail 向量。

(iv) 用 McLean-Pontiff 平均 58% 衰减,算样本外预期收益 expected_OOS = in_sample_return * (1 - 0.58);如可获得实际样本外数据,做对照;否则按先验报告。

(v) 给该异象分类:production_grade(五项全过)/ candidate(过 3-4 项)/ suspect(过 0-2 项);说明它在生产合成因子中的纳入意义(production_grade = 常规权重;candidate = 收缩权重;suspect = 不纳入)。

提示
第 (i) 步用 scipy: from scipy.stats import norm; norm.ppf(1 - 0.025/316)。单侧 vs 双侧门槛最容易出错——HLZ 用的是双侧框架。
提示
第 (iv) 步,58% 是 McLean-Pontiff 的平均值;对一篇在 L2 清单上失败多项的论文,预期衰减更接近 84% 的上尾(统计偏差 + 经济衰减)。

下一节

下一节《因子构建机制:组合排序与回归》钻进构建工艺本身:断点宇宙断点 vs 全样本断点、市值加权 vs 等权、二维 2x3 排序的逐步走法、Fama-MacBeth 两阶段回归的端到端实现、Daniel-Titman 1997 vs Davis-Fama-French 2000 的「特征 vs 协方差」之争,以及四类把噪声过程变成可发表异象的小盘股通胀陷阱。L3 的工艺细节,正是 L2 异象阅读清单第 (2) 项所验证的内容。

参考卡

本节课用到的元素,按出现顺序:

  • 各步骤的代码内嵌清单(inline-code listing,每条编号)。
  • 带可扩展签名的代码围栏块(fenced python block)。
  • 含两条渐进式提示(Hint)的练习模块,应用到 A 股区域数据集。
  • 中心定价恒等式的 FormulaExplorer 交互组件。

本课用到的术语

本节使用了如下规范化因子与风险术语共 10 条:因子模型、因子暴露、Alpha 衰减、动量、价值因子、规模因子、质量因子、低波动因子、信息比率、夏普比率。

A 股区域参考

本节示例在 A 股语境下默认使用以下数据与机构参考(均为 CN 区域专属,与美股语境不重合):数据库 Wind、Qlib、JoinQuant、RiceQuant、Tushare、JQData、Choice;监管机构 CSRC、PBoC、SAFE、CBIRC;交易所 SSE、SZSE、BJEX、CFFEX;基准指数 CSI300、CSI500、CSI1000、ChinaA50;券商与基金 CICC、CITIC、HuaTai、Guosen、GuoTai、JunAn、HaiTong、ZhongJin、JiaShi、EFunds、BOSC、Bosera;研究锚定文献 LSY、Liu、Stambaugh、Yuan(LSY 三因子)、ShiChuan《因子投资》、WuFeixiang《量化投资》、DingPeng《量化投资策略》;本地术语 ChiNext、STAR、Beijing、RMB、PIT、BIPC。