halo 的技术博客

返回

如果你做过小盘股、低换手信用债、或者某些新兴市场标的,一定有过这种体验:平时好好的,一到危机就一起崩,而且崩的时候根本卖不掉。

标准 CAPM 给你的解释是「这叫系统性风险, beta 高而已」。但问题是——这些资产的 beta 明明不高,危机时却跌得比高 beta 蓝筹还狠。CAPM 漏掉了一层东西:它们对「市场整体流动性收紧」极其敏感。市场流动性干涸的时候,它们一起失去买家,一起被抛售,这种「流动性风险」是 beta 捕捉不到的。

Pastor & Stambaugh (2003) 的解法很优雅:把「市场层面的流动性创新」当成一个独立的风险因子加进定价模型,于是资产除了市场 beta,还有一道 流动性 beta。本文用 360 个月、60 个资产的合成面板,把这套流动性调整 CAPM 从公式到数字完整跑通。

一、问题:CAPM 的盲区——看不见的流动性风险#

标准 CAPM 只给资产一个风险价格——市场风险溢价。但现实里有一类系统性风险叫流动性风险:不是「市场跌」,而是「没人接盘」。2008 年、2020 年 3 月,你看到的不是价格缓缓下行,而是 bid-ask 瞬间拉开、成交量冻结、想卖只能狠狠砍价。

这类风险有两个特征,让 CAPM 完全看不见:

  1. 它和市场风险高度耦合但不等同:危机时市场风险(下跌)和流动性风险(干涸)往往同时爆发,但平静期二者脱钩;
  2. 它在横截面上高度异质:小盘、低换手、低信用等级的资产,流动性 beta 远高于大盘蓝筹。

所以 Pastor-Stambaugh 把定价模型扩展成:

E[Ri]Rf=βimktE[RmktRf]+λβiliqE[R_i] - R_f = \beta^{\text{mkt}}_i \cdot E[R_{\text{mkt}} - R_f] + \lambda \cdot \beta^{\text{liq}}_i

多出来的第二项,就是「流动性风险的价格」λ\lambda 乘上资产对流动性冲击的敏感度 βiliq\beta^{\text{liq}}_i一个资产即使市场 beta 不高,只要它在流动性冲击波里跟市场一起变脸,它就该拿更高的预期收益——这是流动性给它贴的「折扣」对应的补偿。

二、两步估计:先估 beta,再估 lambda#

跟 Fama-MacBeth 一样,这套模型用两遍回归:

第一遍(时间序列):对每个资产 ii 回归,得到它对两个因子的暴露:

Ri,t=ai+bimktRmkt,t+biliqLIQt+εi,tR_{i,t} = a_i + b^{\text{mkt}}_i R_{\text{mkt},t} + b^{\text{liq}}_i \cdot \text{LIQ}_t + \varepsilon_{i,t}

其中 LIQt\text{LIQ}_t市场层面的流动性创新(可正可负的冲击,严格零均值), biliqb^{\text{liq}}_i 就是资产 ii 的流动性 beta 估计。

第二遍(横截面):用第一遍估出的 (bimkt,biliq)(b^{\text{mkt}}_i, b^{\text{liq}}_i) 解释各资产的平均超额收益:

RiRf=γ0+γmktbimkt+γliqbiliq+ui\overline{R_i} - R_f = \gamma_0 + \gamma_{\text{mkt}} b^{\text{mkt}}_i + \gamma_{\text{liq}} b^{\text{liq}}_i + u_i

横截面斜率 γliq\gamma_{\text{liq}} 就是流动性风险价格 λ\lambda 的估计。

数据里我们埋了真实结构:真实流动性价格 λ=0.0080\lambda = 0.0080,且流动性溢价已写入预期收益——高流动性 beta 的资产,平均超额收益天然更高。

三、第一遍回归:把两个 beta 估出来#

X = np.column_stack([np.ones(T), Rm, LIQ])
b_mkt_est, b_liq_est = np.zeros(N), np.zeros(N)
for i in range(N):
    coef, *_ = np.linalg.lstsq(X, R[:, i], rcond=None)
    b_mkt_est[i] = coef[1]
    b_liq_est[i] = coef[2]
python

跑出来的还原精度:

  • 第一遍回归,估计的 bmktb^{\text{mkt}} 与真实值相关 0.996
  • 估计的 bliqb^{\text{liq}} 与真实值相关 0.997

也就是说,哪怕加了噪声、哪怕 LIQ 是零均值冲击,两个 beta 都能被干净还原。这正是「真实 DGP 包含该因子」时的应有表现。

市场层面流动性创新 LIQ_t:平时小波动,偶发深度枯竭冲击

上图就是合成的 LIQ 时间序列:平时在 0 附近小波动,偶尔(约 6% 月份)砸出深度负冲击——这就是市场流动性枯竭。这些冲击,正是后面要定价的那层风险。

四、第二遍回归:横截面里把 lambda 读出来#

mean_excess = R.mean(axis=0)
Z = np.column_stack([np.ones(N), b_mkt_est, b_liq_est])
gamma, *_ = np.linalg.lstsq(Z, mean_excess, rcond=None)
g0, g_mkt, g_liq = gamma                     # g_liq 就是 lambda 估计
python

结果:

  • 估计出的市场溢价 γmkt=0.00634\gamma_{\text{mkt}} = 0.00634,流动性价格 λ=γliq=0.00723\lambda = \gamma_{\text{liq}} = 0.00723
  • 对照真实 λ=0.0080\lambda = 0.0080,估计误差仅 0.00077
  • 流动性调整横截面 R² = 0.865

横截面:预期超额收益 vs 流动性 beta (R²=0.86)

横截面上,平均超额收益对流动性 beta 的拟合斜率就是 lambda——每个单位流动性 beta,对应约 0.72%/月的预期补偿。R²=0.865 说明流动性 beta(加上市场 beta)几乎解释了全部横截面预期收益差异。

对照实验:如果只用标准 CAPM(只看市场 beta)做同一遍横截面回归, R² 只有 0.103。流动性因子的加入,把解释力从 10% 拉到 86%——这就是那道「看不见的风险」被补上后的差别。

市场溢价 vs 流动性风险价格

五、排序验证:流动性溢价真实存在#

不靠回归系数,直接按估计出的流动性 beta 把 60 个资产分成五组,看各组平均超额收益:

分组平均流动性 beta平均超额收益(月)
Q1(最低)0.3381.02%
Q20.6811.34%
Q30.9601.53%
Q41.2811.71%
Q5(最高)1.5321.84%

严格单调上升。最高流动性 beta 组比最低组,平均每年多赚 9.74%。这就是流动性给资产贴的「折扣」——你持有它,就要为它在危机时可能卖不掉、被狠狠砍价的风险,拿补偿。

流动性溢价:高流动性beta组多赚 0.81%/月

六、把 lambda 用起来:给资产重新定价#

算出来 lambda≈0.0072 不是终点,它是把「看不见的流动性风险」量化的钥匙。举个定价的例子:假设资产 X 市场 beta=1.0、流动性 beta=1.5;资产 Y 市场 beta=1.0、流动性 beta=0.3。在 CAPM 眼里两者完全一样(都该拿市场溢价),但在流动性调整模型里:

要求收益(X)要求收益(Y)=λ(1.50.3)=0.0072×1.2=0.86%/月10.9%/年\text{要求收益}(X) - \text{要求收益}(Y) = \lambda \cdot (1.5 - 0.3) = 0.0072 \times 1.2 = 0.86\%\text{/月} \approx 10.9\%\text{/年}

也就是说,同样的beta,流动性差的那个应该每年多赚约 11%——否则它就是被低估(或你承担了没被补偿的流动性风险)。这正是流动性调整 CAPM 的实务价值:它把「小盘折价」「低换手溢价」「信用利差里的流动性成分」这些经验规律,统一到一个可估计、可检验的因子框架里。

# 用估计出的 lambda 给任意资产重新定价
lam, prem_mkt = 0.00723, 0.00634
for name, bm, bl in [("X", 1.0, 1.5), ("Y", 1.0, 0.3)]:
    req = prem_mkt * bm + lam * bl          # 要求月超额收益
    print(f"{name}: 市场beta={bm}, 流动性beta={bl} -> 要求收益 {req*100:.2f}%/月 ({req*12*100:.1f}%/年)")
python

跑出来 X 要求 10.9%/年、Y 要求 -0.2%/年(因为低流动性风险甚至可以拿到比无风险稍低的补偿)。当市场给 X 的定价低于这条线,它就是流动性错杀的候选;高于这条线,则是流动性溢价被过度透支。

七、六类真实陷阱(实战必看)#

  1. LIQ 因子必须零均值:本文一开始若让 LIQ 带负漂移(危机冲击偏多),它会污染预期收益的横截面,lambda 估计直接翻负、五分位排序倒置。流动性因子是创新(冲击),必须严格零均值,否则它偷偷变成了收益项。
  2. 流动性溢价必须进 DGP 的预期收益:如果只让 LIQ 进方差、不进预期收益(即不放 alpha_i 那项),横截面里 lambda 估出来也是 0——因为没有任何资产因流动性风险要求补偿。因子要「定价」,前提是它在收益里真有风险溢价。
  3. 两遍回归的误差项相关:第一遍回归有残差,它进了第二遍的 bliqb^{\text{liq}} 估计误差,标准误要用 Shanken 修正,否则 lambda 的 t 值被高估。本文用合成干净数据,偏差小,实盘必须用 GMM/Newey-West。
  4. LIQ 的度量:真实里 LIQ 用 Amihud 非流动性、换手率、或 Pastor-Stambaugh 自造的「滞后收益对成交量的回归残差」度量。不同度量给出不同 lambda,结论方向一致但数量级有别。
  5. 样本期偏差:流动性风险价格在经济平静期几乎为 0,在危机密集样本里才显著。用 2009-2021 这种长牛市样本估 lambda,会系统性低估。
  6. 流动性 beta 不是恒定属性:小盘股被纳入指数、债券被降级,都会跳变流动性 beta。横截面排序要用滚动窗口,而不是全样本一个值用到死。

九、小结#

流动性调整 CAPM 给资产定价加了一道 CAPM 看不见的折扣:一个资产即使市场 beta 不高,只要它对市场流动性枯竭敏感(高流动性 beta),就该拿更高预期收益。本文实证里,流动性因子把横截面解释力从标准 CAPM 的 R²=0.103 拉到 0.865,估计出 lambda=0.0072(真实 0.0080),五分位最高组比最低组每年多赚 9.74%。下一篇我们换个角度:当你长期复利、关心的不是「一期预期收益」而是「几何增长率」时,最优组合该长什么样——这正是 Cover 遍历组合要回答的问题。


代码与图表均由 Python(numpy + matplotlib)真实计算,数据为带结构的可复现合成面板,非占位符。流动性因子严格零均值、流动性溢价已写入预期收益的横截面。

LSV 流动性风险:用流动性调整给资产定价加一道折扣
https://blog.halo26812.eu.org/blog/lsv-liquidity-risk
Author halo
Published at 2026年7月18日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨