2081 字
10 分钟

组合优化入门:均值方差与风险平价

本课目标:理解均值方差框架的直觉与它在实践中的脆弱性,认识风险平价的思想,并学会给优化问题加上实盘必需的约束。

上一课我们用分位数等权把因子分变成了持仓。等权简单可靠,但它对风险不闻不问:两只总分一样的股票,一只波动 15%、一只波动 60%,等权买入意味着组合风险被高波动的那只主导。组合优化要解决的就是”在预期收益和风险之间做系统性权衡”。本文不构成投资建议。

均值方差:优雅的框架#

均值方差框架的直觉一句话就能说完:在给定风险水平下最大化预期收益,或在给定预期收益下最小化风险。它需要两个输入——每只股票的预期收益向量 μ,和股票间的协方差矩阵 Σ;输出是一组最优权重 w。目标函数常写成:

最大化 wᵀμ − (λ/2)·wᵀΣw,其中 λ 是风险厌恶系数。

这个框架的漂亮之处在于它把”分散化”数学化了:只要资产不完全相关,组合波动就小于成分波动的加权平均——这是组合管理里少有的近似免费的午餐。它还给出了一个重要视角:一只股票值不值得加仓,不取决于它自身的风险收益,而取决于它对组合整体的边际贡献。在多因子语境下,μ 通常直接用上一课合成的因子分(经过缩放)充当。

输入敏感:优雅框架的阿喀琉斯之踵#

均值方差在教科书里完美,在实践中却出名地难用,核心原因是对输入误差极度敏感

  • 预期收益 μ 的微小扰动,会导致最优权重的剧烈翻转。优化器像一台”误差放大器”——它会最大化地押注那些被你高估了预期收益的资产;
  • 输出的组合经常极端:满仓押少数几只股票、大量权重贴在约束边界上;
  • 每期输入更新后权重大幅跳动,带来不可接受的换手。

而 μ 恰恰是我们估得最不准的东西——因子对收益的预测本来就只有微弱的相关性。所以实务共识是:对 μ 的精度保持悲观,用约束和正则化驯服优化器,而不是指望喂给它精确的预期收益。常见的驯服手段包括:只用 μ 的排序信息而弱化数值大小、把权重向基准或等权收缩、给目标函数加上惩罚换手的项。这些手段的共同精神是一句话——当输入不可靠时,宁可要一个”大致正确”的钝解,也不要一个”精确错误”的锐解。

协方差估计同样困难#

Σ 看起来比 μ 好估,其实也有自己的麻烦:

  • 维度灾难:N 只股票的协方差矩阵有 N(N+1)/2 个参数。500 只股票就有超过 12 万个参数,而一年只有约 240 个交易日的数据,样本协方差矩阵噪声极大甚至不可逆;
  • 时变性:相关性结构在危机中会集体抬升,“平时分散、跌时抱团”;
  • 常见对策:压缩估计(把样本协方差向结构化目标收缩)、因子风险模型(假设股票收益由少数风格/行业因子驱动,把估计对象从 12 万个参数降到几十个因子的协方差)、以及拉长半衰期的指数加权估计。

进阶阶段不必自己实现因子风险模型,但要理解一点:直接把样本协方差矩阵塞进优化器,是新手最常见的翻车方式之一。

风险平价:不猜收益,只配风险#

既然 μ 最不可靠,一个激进的思路是干脆不用它。风险平价(risk parity)的思想是:让每个资产(或每类资产)对组合总风险的贡献相等

对比三种配置逻辑:

方案均衡的对象需要的输入
等权资金
风险平价风险贡献协方差(主要是波动率)
均值方差边际收益/边际风险预期收益 + 协方差

最简化的版本是波动率倒数加权(忽略相关性):

vol = ret.rolling(60).std() * np.sqrt(250) # 年化波动
raw_w = 1.0 / vol.iloc[-1]
weights = raw_w / raw_w.sum() # 归一化

完整的风险平价需要数值求解,使每只资产的风险贡献 wᵢ·(Σw)ᵢ 相等。风险平价常用于大类资产配置(股、债、商品),在股票组合内部则常以”波动率倒数”或”风险预算”的简化形态出现。它的代价也很直白:完全放弃了收益观点,低波动资产会拿到很高的权重。

在多因子选股的语境下,一个折中方案很自然:用因子分决定”选哪些股票”,用风险平价或波动率倒数决定”每只买多少”。选股环节保留收益观点,配权环节只做风险均衡——这比把因子分直接塞进均值方差优化器要稳健得多,实现成本也低,很适合作为进阶阶段的默认方案。

实盘必需的约束#

无论用哪个框架,裸的优化解都不能直接交易。常见约束及其动机:

  • 个股上限(如单票不超过 5%):防止优化器把误差押成重仓,控制个股黑天鹅暴露;
  • 行业上限/行业偏离约束(如相对基准行业偏离不超过 ±3%):把收益来源约束在选股而非行业押注上;
  • 换手约束(如单次调仓换手不超过 20%):直接控制交易成本,也间接抑制了权重对输入噪声的敏感;
  • 禁买/剔除清单:停牌、ST、流动性不足的股票直接排除,避免优化解落在无法执行的标的上。

带约束的优化本质是一个二次规划问题,Python 生态里可用 scipy.optimize.minimize 或凸优化库求解。示意(最小化跟踪风险的骨架):

from scipy.optimize import minimize
def objective(w, mu, cov, lam=10.0):
return -(w @ mu) + 0.5 * lam * w @ cov @ w
cons = [{"type": "eq", "fun": lambda w: w.sum() - 1.0}]
bounds = [(0.0, 0.05)] * n_assets # 不做空,单票上限 5%
res = minimize(objective, x0, args=(mu, cov), bounds=bounds, constraints=cons)

一个务实的经验:约束收紧到一定程度后,不同优化方法的结果会趋同——约束本身就是最强的正则化。先把约束设计好,再谈优化器的高级技巧。

最后别忘了评价基准:任何优化组合都应与等权组合放在同一回测框架下对比,看年化波动、最大回撤、换手率和成本后收益。如果精心调校的优化器在成本后跑不过等权,说明当前输入质量还撑不起这套复杂度,退回简单方案不丢人。

本课小结#

  • 均值方差框架直觉优雅,但对预期收益输入极度敏感,优化器天然是”误差放大器”;
  • 协方差矩阵参数量巨大,直接用样本协方差是常见翻车点,压缩估计与因子风险模型是主流对策;
  • 风险平价放弃收益预测、只均衡风险贡献,是对输入不确定性的一种务实回应;
  • 个股、行业、换手三类约束是实盘组合的标配,约束本身就是最有效的正则化;
  • 复杂优化应先与等权、波动率倒数加权这类朴素基准对比,胜出了才有存在的理由。

动手练习:取上一课多因子组合的前 50 只股票,分别用等权和 60 日波动率倒数加权构建两个组合,按月调仓回测,对比两者的年化波动、最大回撤与换手率,体会”只动风险、不动收益观点”能带来多大差异。