风险模型与业绩归因:Barra 思想入门
本课目标:理解 Barra 式风险模型的基本思想,学会把组合收益分解为市场、行业、风格与特质四层,并用归因回答”我赚的是不是自己以为的钱”。
为什么需要风险模型
假设你的选股策略今年表现不错。一个必须回答的问题是:这份收益来自你的选股能力,还是来自你不知不觉持有了一堆小市值高波动股票,而这类股票恰好今年整体走强?如果是后者,你赚的其实是某种风格的贝塔,而风格会轮动——当小市值风格逆转时,“选股能力”会同步消失。
风险模型就是回答这类问题的工具。它的核心思想很朴素:个股收益的大部分共同波动,可以被少数几个系统性因子解释;剩下无法解释的部分才是真正属于个股的特质收益。有了这个分解,你才能看清组合到底押注了什么。本文只讨论分析方法,不构成投资建议。
风格因子暴露:给组合画像
Barra 式模型把系统性因子分为三类:市场(所有股票共同的涨跌)、行业(股票所属行业的整体表现)、风格(跨行业的共同特征)。常见的风格因子包括:
| 风格因子 | 度量的特征 |
|---|---|
| 市值(Size) | 大盘股 vs 小盘股 |
| 价值(Value) | 估值高低(如市净率的倒数) |
| 动量(Momentum) | 过去一段时间的相对强弱 |
| 波动(Volatility) | 历史波动率高低 |
| 盈利(Profitability) | 盈利能力(如 ROE) |
| 流动性(Liquidity) | 换手率高低 |
每只股票在每个因子上有一个暴露(exposure),通常做法是把原始指标在横截面上去极值、标准化为均值 0、标准差 1 的 z 分数。组合的因子暴露就是成分股暴露的持仓加权平均:
# exposures: DataFrame(index=股票, columns=因子), weights: Series(index=股票)portfolio_exposure = exposures.mul(weights, axis=0).sum()组合在市值因子上的暴露是 -0.8,意思就是它显著偏向小盘——不管你的策略文档里写没写这一条,市场都会按这个暴露给你结账。
收益分解:市场、行业、风格、特质
有了暴露,第二步是估计每个因子在每期”值多少钱”,即因子收益。标准做法是横截面回归:在每个交易日,用全市场股票当日收益对它们的因子暴露做一次回归,回归系数就是各因子当日的收益,残差就是各股票当日的特质收益。
于是组合任意一天的收益可以写成:
组合收益 = Σ(组合因子暴露 × 因子收益)+ 特质收益贡献
把每一项沿时间累计,就得到一张收益来源表。例如某策略年度收益的分解可能长这样(示意结构,非真实数据):
| 来源 | 贡献 | 解读 |
|---|---|---|
| 市场 | 正 | 满仓带来的贝塔 |
| 行业 | 小幅正 | 略微超配了某几个行业 |
| 风格 | 显著正 | 主要来自小市值与高动量暴露 |
| 特质 | 接近零 | 真正的”选股 alpha”很薄 |
赚的是不是自己以为的钱
上面这张表正是归因的价值所在。一个自称”基本面选股”的策略,如果归因显示收益绝大部分来自市值和动量暴露、特质贡献接近零甚至为负,那么它实际上是一个披着基本面外衣的风格贝塔组合。这不一定是坏事——但你必须知道,并回答三个问题:
- 这些风格暴露是有意的还是无意的?无意的暴露是失控的风险。
- 如果剥离风格贡献,剩下的特质收益还够覆盖交易成本吗?
- 当主导风格逆转时,组合会承受多大回撤?可以用历史上风格因子的极端回撤期做情景测试。
反过来,如果你想做”纯选股”策略,归因给出了改进方向:在组合构建时约束各风格暴露接近零(风格中性化),把仓位集中在特质收益上。当然,中性化有代价——它会砍掉恰好来自风格的那部分收益,值不值得取决于你对自己特质 alpha 的信心。
从归因到风险预测
风险模型的另一半用途是向前看:预测组合的波动,而不只是解释过去。思路是把组合方差拆成两块——因子暴露乘以因子收益协方差矩阵,加上特质方差的加权和:
# B: 组合因子暴露向量, F: 因子协方差矩阵, spec_var: 个股特质方差port_var = B @ F @ B + (weights ** 2 * spec_var).sum()这个分解的工程价值在于降维:直接估几千只股票的协方差矩阵,样本远远不够、估计极不稳定;而因子只有几十个,因子协方差矩阵可以估得相对可靠。有了它,你可以在调仓前回答”这次调整会让组合预期波动上升多少""跟踪误差主要花在了哪个因子上”,把风险预算从事后复盘前移到事前决策。对进阶学习者来说,先会用这个公式做组合层面的”沙盘推演”,比钻研估计细节更有性价比。
简化实现:不买商业模型也能起步
商业风险模型贵,但思想可以低成本复现。一个够用的简化流程:
- 选因子:市值(流通市值取对数)、价值(账面市值比)、动量(过去若干月收益,常剔除最近一个月)、波动(历史波动率),行业用申万一级或中信一级分类的哑变量。
- 处理暴露:横截面去极值(如中位数绝对偏差法)、标准化;行业哑变量不标准化。
- 逐日回归:加权最小二乘(常用流通市值平方根加权),得到因子收益序列与残差。
- 归因:用你的组合权重乘以暴露,再乘以因子收益,累加成贡献表。
import numpy as np
# X: 当日暴露矩阵(股票 × 因子), r: 当日个股收益, w_reg: 回归权重W = np.diag(w_reg)factor_ret = np.linalg.solve(X.T @ W @ X, X.T @ W @ r)resid = r - X @ factor_ret简化模型的估计肯定粗糙,但对”看清组合押注了什么”这个目的而言,方向的正确远比小数点后的精度重要。
几个实现细节提醒:横截面回归的样本要用当日全部可交易股票,而不是只用你的持仓——因子收益衡量的是市场对某种特征的定价,样本必须覆盖整个市场;停牌股票当日应剔除;行业哑变量与市场因子共线,工程上常见做法是去掉市场截距项、或对行业收益施加加权和为零的约束,初学阶段选一种并保持一致即可。归因结果最好做成每周自动生成的报表,让”看暴露”变成和”看净值”同样频繁的习惯。
本课小结
- 风险模型把个股收益分解为市场、行业、风格与特质四层,让组合的真实押注显形。
- 因子暴露是横截面标准化后的 z 分数,组合暴露是持仓加权平均。
- 因子收益靠逐日横截面回归估计,残差即特质收益。
- 归因的核心问题是”赚的是不是自己以为的钱”:无意的风格暴露是失控的风险。
- 用公开数据就能搭一个简化 Barra 式流程,精度粗糙但足以指导组合诊断。
动手练习:取你此前做过的任一选股或轮动组合,构建市值、动量两个风格因子加行业哑变量的简化模型,做三个月的逐日横截面回归,输出组合收益的四层分解表。回答:特质贡献占比多少?哪个暴露是你此前没有意识到的?