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

因子模型基础:从 CAPM 到 Fama-French

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

一家面向沪深300成分股的私募基金新来的研究员,把基本面盈利筛选的多空组合回测呈到投委会:年化 6.4%,夏普 0.9,t 值 2.5。基金经理只说一句:「先把因子控掉再来汇报 alpha。」研究员意识到自己说不清三件事——「因子」指哪几个、为什么是这几个、基金经理隐含的是哪个检验。本节课就是这道问题的答卷。你会从 1964 年的 CAPM,走到 2015 年的 FF5 与 HXZ4,并学会两类标准检验——时间序列 alpha 回归与 Fama-MacBeth 两阶段截面回归——它们决定一个候选因子能否跑赢基准。

CAPM:单因子锚

资本资产定价模型(capital asset pricing model, CAPM)——Sharpe 1964、Lintner 1965、Mossin 1966——主张每只股票的预期超额收益,由一个数字完全决定:它对市场组合的 beta。

E[ri]rf=βi(E[rM]rf)E[r_i] - r_f = \beta_i \cdot (E[r_M] - r_f)

直白地讲:beta 等于 1.2 的股票,应当比市场本身多赚 20% 的市场风险溢价;beta 等于 0.5 的股票,应当只拿到一半的市场溢价。证券市场线(security market line, SML)把这个预言画出来——纵轴是预期超额收益,横轴是 beta,所有资产都应落在一条过原点、斜率等于市场溢价的直线上。这个模型极度节俭——只有一个因子,每只股票只有一个 beta,只有一份风险溢价——它的检验同样节俭:把股票超额收益对市场超额收益做回归,截距项就是 alpha;在 CAPM 零假设下 alpha 应当为零。如果 alpha 显著为正,说明 CAPM 漏掉了 一份预期收益的来源。

1980 年代到 1990 年代的实证文献,系统地记录了这种漏项。Banz 1981 发现了 ​规模效应​​:小市值股票的收益高出 CAPM 的预测。Stattman 1980、随后的 Rosenberg-Reid-Lanstein 1985、以及 Chan-Hamao-Lakonishok 1991 发现了 ​价值效应​​:账面市值比(book-to-market, B/M)高的股票——也就是「便宜」的股票——收益高出 CAPM 的预测。在数以百计的复现研究中,模式始终如一:按公司特征做截面排序,alpha 都是稳健地非零。单因子模型在实证上不完整。

Fama-French 三因子与 Carhart 四因子

Fama 与 French 1993 给出了最直接的修补方案:把因子加上去。具体来说,加入一个规模因子(SMB, small minus big,小盘减大盘)的多空组合,和一个价值因子(HML, high minus low book-to-market,高 B/M 减低 B/M)的多空组合。扩展后的定价方程是:

E[ri]rf=βMKTMKT+βSMBSMB+βHMLHMLE[r_i] - r_f = \beta_{\text{MKT}} \cdot \text{MKT} + \beta_{\text{SMB}} \cdot \text{SMB} + \beta_{\text{HML}} \cdot \text{HML}

一只股票的预期超额收益,由它对三个定价因子组合的暴露(回归系数)共同决定。在 1963 年之后的美国样本里,SMB 的年化收益约 2-3%,HML 约 4-5%,在样本内都远远跨过 t > 2 的常规门槛。

构造方法——二维 2x3 排序——是规范化的,值得逐条记住:

1. sort_date = June_end_year_t                          (每年)
2. size_split = breakpoint_median_market_cap                   (2 桶:小盘 / 大盘)
3. bm_split = breakpoint_30th_70th_percentile_BE_to_ME         (3 桶:低 / 中 / 高)
4. intersect_2x3 = 6_value_weighted_portfolios
5. SMB = mean(small_portfolios) - mean(big_portfolios)
6. HML = mean(high_BM_portfolios) - mean(low_BM_portfolios)

二维排序把规模与价值正交化:单变量按 B/M 排序会把小市值推入高 B/M 桶,把两个效应混在一起;先按规模分桶就消掉这种混淆。两组断点用断点宇宙(创业板偏小盘,沪深主板与中小创、北交所之间的差异扮演同样角色)算,各组合按市值加权;每年 6 月末换仓,匹配上一财年末账面权益。

Carhart 1997 把 FF3 扩展为四因子,加入了动量(UMD, up minus down,有时写作 WML, winners minus losers):做多过去 12 个月(跳过最近 1 个月以避免微观结构反转)收益排名前十分之一的股票、做空后十分之一的股票,得到的多空收益。Carhart 的动机是共同基金业绩持续性之谜:原始收益看,前十分位基金有显著持续性;FF3 控掉之后大部分持续性消失,但还残留一个动量暴露上的谜团。把 UMD 当作第四个因子加进去,这部分残留几乎全部被解释掉。

FF5 与 q 因子模型

Fama 与 French 2015 在 q 理论(q-theory)的启发下,又加入了两个因子:盈利能力(RMW, robust minus weak,按账面权益缩放的经营盈利)和投资(CMA, conservative minus aggressive,按资产增长率)。五因子定价方程是:

E[ri]rf=βMKTMKT+βSMBSMB+βHMLHML+βRMWRMW+βCMACMAE[r_i] - r_f = \beta_{\text{MKT}} \text{MKT} + \beta_{\text{SMB}} \text{SMB} + \beta_{\text{HML}} \text{HML} + \beta_{\text{RMW}} \text{RMW} + \beta_{\text{CMA}} \text{CMA}

同一篇 2015 年的论文里 Fama 与 French 还给出了一个反直觉的发现:HML 在 FF5 中是 ​冗余因子​​。HML 所捕捉的变化,被 SMB + RMW + CMA 完全张成,HML 的边际贡献接近零。这对从业者的意义有点微妙:HML 出于历史延续性继续被列入,但 FF5 的真正信息量,几乎只在四因子 MKT + SMB + RMW + CMA 上。

Hou、Xue 与 Zhang 2015 给出了另一条路径——q 因子模型 HXZ4——它直接从 q 理论的元素出发:市场因子、规模因子(ME)、投资因子(I/A)、盈利能力因子(ROE)。构造细节与 FF 略有不同(三重排序而非二维排序,用 30/70 断点而非 FF 的常规百分位),但概念上的覆盖与 FF5 大量重合。实证比拼的结论是:FF5 与 HXZ4 解释的截面比例相当,谁也没有压过对方;两者如今都是生产级基准。

需要记住的五个因子模型菜单:

1. CAPM          (1964, 只含市场)
2. FF3           (1993, + SMB + HML)
3. Carhart       (1997, + UMD/WML)
4. FF5           (2015, + RMW + CMA)
5. HXZ4          (2015, market + ME + I/A + ROE — the q-factor alternative)

五个模型的名称、引入年份、以及「生产级 TS alpha 检验把任意候选因子放在 FF5 或 HXZ4 上做回归」这条规则,跨地区逐字一致。A 股侧的对应基准是 Liu-Stambaugh-Yuan 2019 的 LSY-3 三因子模型(市场 + 规模 + 盈利收益率 E/P),将在 4.3.2 中单独展开。许多研究员会同时跑两套基准,以较差的 alpha 作为保守口径。

时间序列 alpha 检验

候选因子的 时间序列 检验,标准流程如下。设候选多空组合的月度收益为 r_LS,既有基准因子向量为 F = (MKT, SMB, HML, RMW, CMA),跑 OLS 回归:

rLS,t=α+βMKTMKTt+βSMBSMBt+βHMLHMLt+βRMWRMWt+βCMACMAt+ϵtr_{\text{LS},t} = \alpha + \beta_{\text{MKT}} \text{MKT}_t + \beta_{\text{SMB}} \text{SMB}_t + \beta_{\text{HML}} \text{HML}_t + \beta_{\text{RMW}} \text{RMW}_t + \beta_{\text{CMA}} \text{CMA}_t + \epsilon_t

报告截距(alpha)与其 t 值,标准误使用 Newey-West HAC,滞后取 6 期(月度数据,匹配多月自相关)。配方:

1. r_LS_t = monthly_long_short_return_of_candidate_factor
2. F_t = (MKT, SMB, HML, RMW, CMA)_t                                              (the FF5 factor vector at month t)
3. OLS_fit = OLS(r_LS, add_constant(F)).fit(cov_type='HAC', cov_kwds={'maxlags': 6})
4. alpha = OLS_fit.params[0]
5. t_stat_alpha = OLS_fit.tvalues[0]
6. pass_iff t_stat_alpha > 2                                                       (conventional bar; > 3 is the L2 multiple-testing bar)

六个步骤、HAC 滞后规则(maxlags=6)、以及「alpha 是候选因子收益 不能被 FF5 解释的部分」这条规则,跨地区逐字一致。解释:alpha 是候选因子收益中,FF5 基准 不能张成 的部分。alpha 在统计上显著(常规口径 t > 2,L2 多重检验调整口径 t > 3),就是该候选是一个 风险溢价来源、而非 FF5 暴露的重新标签的证据。

举个具体的例子。把美股动量因子 UMD 在 1963-2024 月频上对 FF5 回归,alpha 约每月 0.7%,t 值接近 5。UMD 没有被 FF5 张成,它确实是一个独立的收益来源,Carhart 当年的论证至今成立。反过来,把 账面市值比 特征打包成 HML 多空组合,在 FF5 上的 alpha 接近零,t 值小于 1。HML 在 FF5 中冗余:它的收益完全被 MKT + SMB + RMW + CMA 张成。

Fama-MacBeth 两阶段截面回归

截面 检验问的问题相关但不同:公司特征是否承载了被定价的风险溢价?Fama-MacBeth 1973 的方法,逐期跑截面回归,然后对斜率做时间序列平均:

1. stage_1_per_t = OLS(r_{i,t}, add_constant(char_i)).fit() for each rebalance date t   (giving time series of slopes lambda_1_t)
2. stage_2_mean = mean(lambda_1_t over t)
3. stage_2_hac_se = NeweyWest_SE(lambda_1_t, lag=6)
4. t_stat_FMB = stage_2_mean / stage_2_hac_se
5. pass_iff t_stat_FMB > 2

五个步骤、HAC 滞后规则(lag=6)、以及「FMB tests characteristics-as-priced-risk; TS tests factor-as-portfolio」这条规则,跨地区逐字一致。操作上:在每个换仓日(典型为月频),把当期 N 只股票的收益对当期 N 只股票的公司特征做截面回归,得到一个斜率 lambda_1_t,可以读作「特征每高一个单位,本期多赚 lambda_1_t 的额外收益」。把所有 T 期的 lambda 摞起来,算时间序列均值,除以滞后 6 的 Newey-West HAC 标准误,得到的 t 值与门槛比对。

与 TS 检验的对比是概念性的:TS 问候选因子 组合 在 FF5 之外有没有 alpha;FMB 问背后那条公司 特征 在截面上是否承载风险溢价。两者在真实信号上应当同号,但量纲会有偏差——TS 在多空腿内部按市值加权汇总,被大盘股的暴露主导;FMB 把每只股票当作一期一观测,在样本内对各类股票更民主。两者互补,不冗余:生产级判定通常要求两者同时通过。

Formula Explorer

r_{LS,t} = \alpha + \beta_{MKT} \cdot MKT_t + \beta_{SMB} \cdot SMB_t + \beta_{HML} \cdot HML_t + \beta_{RMW} \cdot RMW_t + \beta_{CMA} \cdot CMA_t + \epsilon_t

代码:TS alpha 检验

def ts_alpha_test(r_ls: pd.Series, factors_df: pd.DataFrame, hac_lag: int = 6) -> dict:
    """规范化 Fama-French 时间序列 alpha 检验。

    r_ls       : 候选多空月收益序列
    factors_df : 基准因子收益 DataFrame(FF5 或 HXZ4)
    hac_lag    : Newey-West HAC 标准误的滞后期数(月频默认 6)

    返回 dict, 键为: alpha, alpha_t_stat, alpha_p_value, factor_loadings, r_squared.
    """
    import statsmodels.api as sm
    import pandas as pd
    df = pd.concat([r_ls.rename('r_ls'), factors_df], axis=1).dropna()
    X = sm.add_constant(df.drop(columns='r_ls'))
    fit = sm.OLS(df['r_ls'], X).fit(cov_type='HAC', cov_kwds={'maxlags': hac_lag})
    return {
        'alpha': fit.params['const'],
        'alpha_t_stat': fit.tvalues['const'],
        'alpha_p_value': fit.pvalues['const'],
        'factor_loadings': fit.params.drop('const').to_dict(),
        'r_squared': fit.rsquared,
    }

函数名 ts_alpha_test、参数名 r_ls / factors_df / hac_lag、默认值 hac_lag=6、以及返回 dict 的键 alpha / alpha_t_stat / alpha_p_value / factor_loadings / r_squared,跨地区逐字一致。

代码:FF 二维 2x3 排序

def ff_bivariate_sort(prices: pd.DataFrame, market_cap: pd.DataFrame,
                      book_equity: pd.DataFrame, breakpoint_universe: str = 'main_board') -> dict:
    """Fama-French 1993 规模 x 账面市值比 二维 2x3 排序。

    prices              : 月度收盘价, date x symbol
    market_cap          : 月度市值, date x symbol
    book_equity         : 上一财年末账面权益(向前 carry forward), date x symbol
    breakpoint_universe : 美股规范 'main_board'; CN 对应 'CSI300_main_board' (沪深主板)

    返回 dict, 键为 SMB, HML, portfolio_returns(2x3 = 6 个交叉组合).
    """
    import pandas as pd
    bm = book_equity / market_cap
    # 6 月末换仓:每年 6 月的截面作为排序日
    june_dates = market_cap.index[market_cap.index.month == 6]
    portfolios = {k: [] for k in ['SL', 'SM', 'SH', 'BL', 'BM', 'BH']}
    for sort_date in june_dates:
        bp_mask = market_cap.loc[sort_date].index  # 占位:断点宇宙掩码
        size_median = market_cap.loc[sort_date, bp_mask].median()
        bm_30 = bm.loc[sort_date, bp_mask].quantile(0.30)
        bm_70 = bm.loc[sort_date, bp_mask].quantile(0.70)
        # ... 把每只股票分配到 SL / SM / SH / BL / BM / BH 六个桶之一
        # ... 计算 t 年 7 月到 t+1 年 6 月的市值加权月收益
        # (完整实现见 scripts/factor_construction/ff_bivariate.py)
    smb = None  # mean(SL, SM, SH) - mean(BL, BM, BH)
    hml = None  # mean(SH, BH) - mean(SL, BL)
    return {'SMB': smb, 'HML': hml, 'portfolio_returns': portfolios}

函数名 ff_bivariate_sort、参数名、默认值 breakpoint_universe='main_board'、以及返回 dict 的键 SMB / HML / portfolio_returns,跨地区逐字一致。

练习

Exercise

你拿到 12-1 动量多空组合 mom_ls 在沪深300成分股范围内 2018-01 至 2023-12 的月度收益,以及对应的因子收益 DataFrame factors_df,其中 CN 情景下列名为 MKTSMB_lsyEP_lsy(LSY-3 三因子,可选扩展盈利能力与投资);所有股票均按 T+1 结算约束,且 涨跌停 日的样本已被排除(SSE / SZSE 主板 标准)。

(i) 跑 TS alpha 检验:拟合 OLS(mom_ls, sm.add_constant(factors_df)).fit(cov_type='HAC', cov_kwds={'maxlags': 6});报告 alphaalpha_t_statalpha_p_value,以及因子载荷(CN 情景下的 beta_MKTbeta_SMB_lsybeta_EP_lsy)。

(ii) 判断该候选因子是否 survives_ff5,等价于 alpha_t_stat > 2(常规口径);并标注它是否同时通过 L2 多重检验调整后的 alpha_t_stat > 3 门槛。

(iii) 跑 FMB 截面回归:用 12-1 动量 特征 作为自变量,对个股截面收益做回归(剔除 ST、停牌、 涨跌停 日及上市不满 6 个月的次新股,沪深300 范围);报告 stage-1 平均斜率与它的 Newey-West HAC t 值(滞后 6)。

(iv) 比较 TS alpha 的 t 值与 FMB 平均斜率的 t 值;用一句话解释为什么两者通常符号一致但数值可能不同(TS 测的是 factor-as-portfolio,组合内部按市值加权;FMB 测的是 characteristic-as-risk-premium,每只股票每期一观测)。

(v) 把候选动量因子归类为 survives_ff5_at_2survives_ff5_at_3fails_ff5 之一;说明这对它在生产级合成因子中所占权重的意义。

提示
第 (i) 步先把 mom_ls 的日期索引与 factors_df 对齐——都用月末时间戳;Ken French 库的因子序列为百分数,如需要转为小数。
提示
第 (iii) 步可用 linearmodels.asset_pricing.FamaMacBeth 直接调用,或手写:逐月循环跑 sm.OLS(returns_cross_section, sm.add_constant(char_cross_section)),收集斜率后再算 NeweyWest_SE(slopes, lag=6)

下一节

下一节《因子动物园与复现危机》接过 L1 给出的框架,问一个元层级的问题:已经发表的因子异象有三百多种,我们到底该用多严的统计门槛?你会学到 Cochrane 2011 的「因子动物园」提法、Harvey-Liu-Zhu 2016 多重检验调整后的 t 值门槛约为 3.0、McLean-Pontiff 2016 出版后衰减的分解、Hou-Xue-Zhang 2020 对 452 个异象的复现研究,以及 五点异象阅读清单——它让你能在十分钟内,对任何新论文里的因子做出「真实信号 vs 统计假象」的概率判断。

参考卡

本课元素:inline-code listing(代码清单)、fenced ```python(代码围栏)、Exercise(练习)、FormulaExplorer。术语:因子模型、因子暴露、动量、价值因子、规模因子、质量因子、低波动因子、贝塔、夏普比率、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。