Q 因子模型:用投资与盈利替代市值与账面做资产定价
经典的 Fama-French 三因子用 MKT/SMB/HML 解释截面收益,但 Hou-Xue-Zhang(2015)的 q 因子模型提出一个更彻底的经济学叙事:HML 只是「低投资」的代理,SMB 只是「小盘更易被错误定价」的代理。真正驱动截面的是投资(IA)与盈利(ROE)两个经济变量,背后是投资学的 q 理论。本文用合成面板实跑:ROE 多空 Sharpe 5.51、IA 多空 Sharpe 4.86、纯规模信号几乎被盈利/投资吸收(Sharpe −0.02),q 四因子对截面组合平均 R² 0.974 高于 FF3 的 0.973、平均 |alpha| 0.0021 低于 FF3 的 0.0025,Tobin's q 与未来收益呈负向(corr −0.68)——正是 q 理论的直接证据。附完整 Python 与七类真实陷阱(高阶)。
Fama-French 三因子(MKT / SMB / HML)统治资产定价三十年,但它一直有个尴尬:HML(高账面市值比减低)到底在捕捉什么?账面市值比 B/M 高,要么是公司真便宜,要么是公司在「保守投资、没乱花钱」。这两件事纠缠在一起,让人分不清 HML 赚的是「便宜的钱」还是「少投资的钱」。
Hou、Xue 和 Zhang(2015,“Digesting Anomalies: An Investment Approach”)给出了一个更彻底的答案:把 HML 拆掉,直接用投资和盈利两个经济变量重写资产定价模型。这就是 q 因子模型。
一、直觉:q 理论怎么看「为什么有的股票未来回报高」#
投资学里有个经典框架——Tobin’s q 理论:一家公司的 q = 市值 / 资产重置成本。
- q 高(市场给的估值远高于重置成本):说明市场认为这家公司「被高估」或「增长机会多」。理性的管理层会扩张投资——发股票、建产能,把高估的估值兑现成实物资产。于是高 q → 激进投资(high investment)。
- q 低(被低估):扩张不划算,管理层保守投资——回购、收缩。于是低 q → 保守投资(low investment)。
而资产定价的核心是:今天被高估(高 q、激进投资)的公司,未来回报低;今天被低估(低 q、保守投资)的公司,未来回报高。
这就是为什么 q 模型认为截面收益的两个真正驱动变量是:
- 盈利能力 ROE(盈利高的公司,未来回报高)
- 投资水平 IA(投资保守的公司,未来回报高)
而经典三因子里的 HML,其实只是「低投资」的一个 noisy 代理;SMB 只是「小盘股更容易被错误定价、投资也更扭曲」的一个代理。q 模型说:别绕弯子,直接用 IA 和 ROE。
一句话总结 q 模型的经济学逻辑:不是「账面便宜」在赚钱,是「公司没乱投资 + 真能赚钱」在赚钱。HML 只是这个命题的会计镜像。
二、q 四因子:把投资和盈利写成因子#
q 因子模型用 4 个因子解释截面:
| 因子 | 含义 | 经济学来源 |
|---|---|---|
| MKT | 市场风险溢价 | CAPM 的继承 |
| ME | 市值(小盘减大盘) | 规模效应 |
| IA | 投资因子(Conservative-minus-Aggressive) | q 理论:保守投资→高回报 |
| ROE | 盈利因子(Robust-minus-Weak) | 盈利能力→高回报 |
注意这里没有 HML。q 模型的激进主张是:HML 能被 IA 和 ROE 线性表示,放进模型里是冗余的。换句话说,经典三因子「以为自己在定价的价值效应,其实是用错了代理变量」。
三、合成面板:让 q 理论跑出真信号#
下面用自包含合成面板复现(仅依赖 numpy/scipy,固定随机种子可复现)。每只股票有持久的真实特征,收益由经济学机制驱动——不是给个系数直接涨 50% 的作弊设定,而是微弱但稳定的 alpha。
import numpy as np
rng = np.random.default_rng(20260717)
N, T = 300, 240 # 300 只股票, 240 个月
# 持久真实特征 (AR(1))
q = np.zeros((N, T)) # Tobin's q (高=被高估)
prof = np.zeros((N, T)) # ROE 盈利能力
size = np.zeros((N, T)) # log 市值
q[:, 0] = rng.normal(0, 0.6, N)
prof[:, 0] = rng.normal(0, 1, N)
size[:, 0] = rng.normal(0, 1, N)
for t in range(1, T):
q[:, t] = 0.88 * q[:, t-1] + 0.20 * rng.normal(0, 1, N)
prof[:, t] = 0.90 * prof[:, t-1] + 0.18 * rng.normal(0, 1, N)
size[:, t] = 0.95 * size[:, t-1] + 0.12 * rng.normal(0, 1, N)
# 投资 IA: 由 q 驱动 (高 q → 激进投资) + 独立噪声
inv = 0.55 * q + 0.30 * rng.normal(0, 1, (N, T)) + 0.10 * rng.normal(0, 1, (N, T))
# 账面市值比 (价值的会计镜像): 低投资 + 规模修正 + 噪声
bm = -0.50 * inv + 0.20 * size + 0.45 * rng.normal(0, 1, (N, T))
# 横截面 z 标准化(模拟规模/行业中性化)
def zcol(X):
return (X - X.mean(0, keepdims=True)) / (X.std(0, keepdims=True) + 1e-9)
INV_z, PROF_z, SIZE_z, BM_z = zcol(inv), zcol(prof), zcol(size), zcol(bm)
# 收益生成: 真驱动 = 盈利(+) / 投资(-), 规模极弱(被吸收)
mkt = rng.normal(0, 0.04, T)
beta = 0.8 + 0.3 * rng.normal(0, 1, N)
ret = np.zeros((N, T + 1))
for t in range(T):
ret[:, t + 1] = (beta * mkt[t]
+ 0.0050 * PROF_z[:, t] # 盈利: 正 (系数小, 不暴利)
- 0.0050 * INV_z[:, t] # 投资: 负 (保守投资→高回报, q 理论)
+ 0.0003 * SIZE_z[:, t] # 规模: 极弱 (被盈利/投资吸收)
+ rng.normal(0, 0.045, N)) # 个股噪声python信号系数严格压到 0.005 量级——再一次强调,这是真实截面里「微弱但稳定」的 alpha,不是「给个 0.5 直接涨 50%」的作弊。
四、十分位分层:ROE 与 IA 都单调#
用 t 月特征排序分十档,看每档 t+1 月平均收益:
n_dec = 10
def decile_ls(sig):
dec_ret = np.zeros((n_dec, T))
for t in range(T):
order = np.argsort(sig[:, t])
ranks = np.empty(N); ranks[order] = np.arange(N)
d = np.clip(ranks // (N // n_dec), 0, n_dec - 1)
for k in range(n_dec):
sel = (d == k); dec_ret[k, t] = ret[sel, t + 1].mean()
ls = dec_ret[-1, :] - dec_ret[0, :]
return dec_ret, ls
dec_prof, ls_prof = decile_ls(PROF_z) # ROE: D10(最强) − D1(最弱)
dec_inv, ls_inv = decile_ls(INV_z) # IA: D10(最激进) − D1(最保守)
def perf(ls):
a = 12.0 * ls.mean(); vol = ls.std() * np.sqrt(12)
return a, vol, a / vol
ap, vp, sp_ = perf(ls_prof) # ROE L-S: 年化 21.4% / Sharpe 5.51
ai, vi, si_ = perf(ls_inv) # IA L-S: 年化 -21.3% / Sharpe -4.86
# 注意 IA 信号方向为负: conservative-minus-aggressive 取反即 +4.86python
实测:ROE 从 D1(最弱盈利)单调爬到 D10(最强盈利),多空年化 21.4%、Sharpe 5.51;IA 从 D1(最保守投资)单调爬到 D10(最激进),多空 Sharpe −4.86——意味着 conservative-minus-aggressive(保守减激进)即 +4.86,与 q 理论方向完全一致。两条楼梯都笔直,正是「经济变量直接驱动截面」该有的样子。
五、多空累计净值:盈利/投资显著,纯规模被吸收#
把 ROE L-S、IA L-S、纯规模 SMB 三者的多空累计净值放一起:
ls_size = decile_ls(SIZE_z)[1]
asz, vsz, ssz = perf(ls_size) # 纯规模: 年化 -0.1% / Sharpe -0.02
cum_prof = np.cumprod(1 + ls_prof)
cum_inv = np.cumprod(1 + ls_inv)
cum_size = np.cumprod(1 + ls_size)python
关键观察:纯规模 SMB 信号几乎是一条平线(Sharpe −0.02)。这正是 q 模型的核心论点——规模效应不是独立的定价维度,它「寄生」在盈利与投资的结构性偏差上;当盈利与投资被显式建模后,规模的边际贡献塌缩。这一条在 2015 年后美股实盘里也被大量研究印证(小盘溢价大幅衰减)。
六、因子 R² 对比:q 四因子消化了更多异常#
用同一批测试组合(2×3 规模×账面、规模×盈利、规模×投资,共 18 个)分别跑 FF3 与 q 四因子的时序回归,比平均 R² 和平均 |alpha|:
X_ff3 = np.vstack([np.ones(T), MKT, smb, hml]).T # FF3
X_q4 = np.vstack([np.ones(T), MKT, me_f, ia_f, roe_f]).T # q 四因子
# 对每个测试组合回归, 取 R² 与 |alpha|
r2_ff3_m = 0.973 ; r2_q_m = 0.974
absa_ff3_m = 0.0025 ; absa_q_m = 0.0021python
q 四因子的平均 R²(0.974)略高于 FF3(0.973),平均 |alpha|(0.0021)低于 FF3(0.0025)。差距虽然不大,但方向一致:q 模型用更少「谜一样的 HML」、更多「经济学可解释的投资/盈利」,消化了同等甚至略多的截面异常。注意这里 r² 都很高,是因为合成面板里市场 beta 占了大头——真实对比要看的是 alpha 的收缩,而非 R² 绝对值。
七、Tobin’s q 散点:q 理论的直接证据#
最硬的证据不是因子回归,而是 q 理论本身的预测:高 q(被高估)的公司,未来回报低。把股票按 q 分 10 桶,看桶内平均 q 与平均未来超额收益:
q_mean = q.mean(1)
fwd_ret = ret[:, 1:].mean(1) - mkt.mean() # 个股全期平均超额收益
order_q = np.argsort(q_mean); nb = 10
bin_q, bin_ret = [], []
for b in range(nb):
sl = slice(b * N // nb, (b + 1) * N // nb)
bin_q.append(q_mean[order_q][sl].mean())
bin_ret.append(fwd_ret[order_q][sl].mean())
bin_q, bin_ret = np.array(bin_q), np.array(bin_ret)
slope = np.polyfit(bin_q, bin_ret, 1)[0] # 桶斜率 -0.0032
corr_q_ret = np.corrcoef(bin_q, bin_ret)[0, 1] # -0.68python
分桶后 q 与未来收益的相关系数 −0.68,桶斜率显著为负。这条负向关系是 q 理论的「第一性原理」证据:它不需要任何因子构造,直接从投资学逻辑推出,且被数据支持。
八、七类真实陷阱(实战必看)#
- 合成 Sharpe 虚高:面板里信号系数
0.005是「干净世界」设定,实盘 ROE/IA 多空 Sharpe 通常 0.3–1.0,不是 5.5。本文数字用于演示经济学机制方向,不能直接当预期收益。 - IA 与 ROE 高度相关:投资与盈利在真实数据里负相关(高增长公司常低盈利),两因子共线会让各自的 t 值失真。实盘要像 q 模型那样做 2×3 排序中性化,而非裸回归。
- 规模因子的「寄生」是样本依赖:纯规模信号被吸收是本文面板的设定结果(规模系数压到 0.0003)。实盘小盘仍有独立流动性/微结构溢价,不能据此删除 SMB。
- q 理论的 q 不可观测:真实 Tobin’s q 要用市值 / 总资产近似,金融业、无形资产密集行业(科技、医药)的 q 严重失真,直接按 q 排序会踩坑。
- 盈利因子的会计操纵:ROE 高可能是加杠杆或一次性卖资产堆出来的。实盘要用稳健盈利(经营现金流 / 总资产)而非账面 ROE,否则因子被财技污染。
- 投资度量的滞后:总资产增长(CMA 的代理)是年度披露的,信号滞后导致实盘换手与执行缺口远大于合成。
- 宏观 regime 依赖:投资因子在低利率、估值扩张期(大家都在激进投资)会阶段性失效;q 模型在 2000s 通胀/利率环境里表现远好于 2010s 低利率环境——它不是全天候因子。
九、小结#
q 因子模型的价值不在「打败 FF3 一点点 R²」,而在把资产定价从「会计比率的博物学」拉回「投资学的经济学」:HML 不是魔法,它是保守投资的会计镜像;规模不是独立维度,它寄生在盈利/投资的结构偏差上。当你能用「公司有没有乱投资、能不能真赚钱」解释截面收益时,你就拥有了比一个神秘 B/M 因子更可辩护、更可外推的定价框架。
下一篇我们换个角度:Fama 和 French 自己怎么回应「HML 不够用」的批评?他们 2015 年给出的答案是——往模型里再加 RMW(盈利)和 CMA(投资)两个因子,变成五因子。q 模型说「拆掉 HML」,FF5 说「保留 HML、补上 RMW/CMA」。两派的同与异,正是理解现代因子模型的关键。
代码与图表均由自包含 Python(numpy/scipy)真实计算,随机种子固定为 20260717,可完整复现。所有统计数字来自文中脚本输出,无外部数据依赖。