2094 字
10 分钟

风险模型与业绩归因: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”很薄

赚的是不是自己以为的钱#

上面这张表正是归因的价值所在。一个自称”基本面选股”的策略,如果归因显示收益绝大部分来自市值和动量暴露、特质贡献接近零甚至为负,那么它实际上是一个披着基本面外衣的风格贝塔组合。这不一定是坏事——但你必须知道,并回答三个问题:

  1. 这些风格暴露是有意的还是无意的?无意的暴露是失控的风险。
  2. 如果剥离风格贡献,剩下的特质收益还够覆盖交易成本吗?
  3. 当主导风格逆转时,组合会承受多大回撤?可以用历史上风格因子的极端回撤期做情景测试。

反过来,如果你想做”纯选股”策略,归因给出了改进方向:在组合构建时约束各风格暴露接近零(风格中性化),把仓位集中在特质收益上。当然,中性化有代价——它会砍掉恰好来自风格的那部分收益,值不值得取决于你对自己特质 alpha 的信心。

从归因到风险预测#

风险模型的另一半用途是向前看:预测组合的波动,而不只是解释过去。思路是把组合方差拆成两块——因子暴露乘以因子收益协方差矩阵,加上特质方差的加权和:

# B: 组合因子暴露向量, F: 因子协方差矩阵, spec_var: 个股特质方差
port_var = B @ F @ B + (weights ** 2 * spec_var).sum()

这个分解的工程价值在于降维:直接估几千只股票的协方差矩阵,样本远远不够、估计极不稳定;而因子只有几十个,因子协方差矩阵可以估得相对可靠。有了它,你可以在调仓前回答”这次调整会让组合预期波动上升多少""跟踪误差主要花在了哪个因子上”,把风险预算从事后复盘前移到事前决策。对进阶学习者来说,先会用这个公式做组合层面的”沙盘推演”,比钻研估计细节更有性价比。

简化实现:不买商业模型也能起步#

商业风险模型贵,但思想可以低成本复现。一个够用的简化流程:

  1. 选因子:市值(流通市值取对数)、价值(账面市值比)、动量(过去若干月收益,常剔除最近一个月)、波动(历史波动率),行业用申万一级或中信一级分类的哑变量。
  2. 处理暴露:横截面去极值(如中位数绝对偏差法)、标准化;行业哑变量不标准化。
  3. 逐日回归:加权最小二乘(常用流通市值平方根加权),得到因子收益序列与残差。
  4. 归因:用你的组合权重乘以暴露,再乘以因子收益,累加成贡献表。
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 式流程,精度粗糙但足以指导组合诊断。

动手练习:取你此前做过的任一选股或轮动组合,构建市值、动量两个风格因子加行业哑变量的简化模型,做三个月的逐日横截面回归,输出组合收益的四层分解表。回答:特质贡献占比多少?哪个暴露是你此前没有意识到的?