跳到正文

为什么 MVO 权重不稳定(以及应对办法)

Michaud (1989) 称均值-方差优化为"误差放大器"。本文给出数学解释,并介绍收缩、重采样和稳健优化三种应对手段。

第 5 篇 · 共 12 篇 约 11 分钟

Markowitz 1952 年的论文给出一个优美、简洁的二次规划。求解它,就能得到有效前沿。闭式解、两基金分离、诺奖级的数学。

只是有一个问题:实际上它跑不通。

1989 年,Richard Michaud 在《Financial Analysts Journal》发文指出,按通常方式实现的均值-方差优化是”误差放大器”而非”均值-方差优化器”。他并没有玩文字游戏。他的意思是:优化器对输入估计误差的放大程度,超过了对输出中真实均值-方差结构的捕捉。

本文用数学讲清楚为什么。然后介绍三族修复方法:收缩、重采样和稳健优化。

输入是骗人的

Markowitz 的 QP 接受两个输入:μ\mu 和 Σ\Sigma。两者都需要从数据中估计。在标准设置下,你取历史收益、计算样本均值和样本协方差,再喂给优化器。

问题就出在这里。

资产收益的样本均值极其有噪声。如果你用 60 个月度收益(5 年)来估计单只股票的预期收益,估计的标准误就是收益标准差除以 60\sqrt{60}。对一只月波动率 6% 的典型股票,结果是 6%/60≈0.77%6\% / \sqrt{60} \approx 0.77\% 每月,年化约 9%。对 10% 的预期收益估计,信噪比约为 1。你在猜。

协方差矩阵相对更稳定,但也有自己的问题。对 NN 个资产、TT 个观测,你需要估计 N(N+1)/2N(N+1)/2 个自由参数。对 N=50N = 50、T=60T = 60,参数多达 1,275 个,数据点却只有 3,000 个。当 T/NT/N 较小时,样本协方差矩阵众所周知地不稳定。其特征值在尾部方向上偏大、在领头方向上偏小(这就是 Marčenko-Pastur 定律)。

然后你把这些含噪声的估计喂给优化器,它要计算 Σ\Sigma 的逆并求解 w⋆=λΣ−1μ+γΣ−11w^\star = \lambda \Sigma^{-1} \mu + \gamma \Sigma^{-1} \mathbf{1}。Σ−1\Sigma^{-1} 放大了小特征值上的估计误差。与 μ\mu 相乘又叠加上噪声。得到的 w⋆w^\star 与”真实”最优权重差异巨大,更糟的是这些权重高度集中且不稳定。

问题的数学

我们把话说得更精确一些。假设真实输入为 (μ0,Σ0)(\mu_0, \Sigma_0),但你估计出 (μ^,Σ^)(\hat{\mu}, \hat{\Sigma})。优化器返回 w^⋆(μ^,Σ^)\hat{w}^\star(\hat{\mu}, \hat{\Sigma})。真实输入下的最优组合是 w⋆(μ0,Σ0)w^\star(\mu_0, \Sigma_0)。

Kan & Zhou (2007) 给出的一个经典结果延续了 Frost & Savarino (1986) 等人的早期工作,把估计误差引起的期望损失分解为四项:

E[L(w^)−L(w⋆)]=bias2⏟tracking error+variance⏟weight dispersion+cross terms⏟interaction\mathbb{E}[L(\hat{w}) - L(w^\star)] = \underbrace{\text{bias}^2}_{\text{tracking error}} + \underbrace{\text{variance}}_{\text{weight dispersion}} + \underbrace{\text{cross terms}}_{\text{interaction}}

具体而言,对 GMV 组合,期望平方跟踪误差为:

E[∥w^−w0∥2]≈tr[(Σ−111⊤Σ−1)Cov(Σ^)]\mathbb{E}\left[\|\hat{w} - w_0\|^2\right] \approx \text{tr}\left[\left(\Sigma^{-1} \mathbf{1} \mathbf{1}^\top \Sigma^{-1}\right) \text{Cov}(\hat{\Sigma})\right]

位于前面的 Σ−111⊤Σ−1\Sigma^{-1} \mathbf{1} \mathbf{1}^\top \Sigma^{-1} 就是把协方差估计的误差”接住”的部分。如果 Σ\Sigma 的特征值很小(风险集中),Σ−1\Sigma^{-1} 会爆炸。如果 Σ\Sigma 是用太少数据估计的,Cov(Σ^)\text{Cov}(\hat{\Sigma}) 会很大。两者相乘。这就是”误差放大器”效应。

对切线组合更糟,因为你还要承受 μ\mu 的噪声:

E[∥w^tan−w0∥2]∝1(B/A−rf)2[Cov(μ)+(rf2)Cov(Σ)+cross terms]\mathbb{E}\left[\|\hat{w}_{\text{tan}} - w_0\|^2\right] \propto \frac{1}{(B/A - r_f)^2} \left[ \text{Cov}(\mu) + (r_f^2) \text{Cov}(\Sigma) + \text{cross terms} \right]

所以,你对收益估计越自信,优化器就会把你犯下的任何错误放大得越厉害。最优 Markowitz 组合恰恰是你能从金融数据中构造出来的最不稳定的对象。

Michaud 真正说了什么

下面这段是 Michaud (1989) 的核心论点:

“用样本估计的均值-方差优化,有望产生一个’优化’组合,它在样本外表现上以高概率劣于等权组合。”

1989 年这是一句极具争议的话。它的隐含之意是:一个复杂的优化器在样本外 Sharpe 上可能输给 1/N 这种朴素启发式。二十年后,DeMiguel, Garlappi & Uppal (2009) 在 7 个数据集上对比 1/N 与 14 个优化组合,恰好证实了这一点。优化组合在样本外长期跑输 1/N。

本文并非要批驳 Markowitz。Markowitz 的理论没有问题。问题在于,他的理论假设你已知 (μ,Σ)(\mu, \Sigma)。实际中你并不知道,而优化器对这些输入的敏感性是残酷的。

修复一:收缩

最简单、最稳健的修复是:不要直接用样本估计,而是把它们向某个结构化目标做收缩。

Ledoit & Wolf (2004) 给出了协方差矩阵的闭式收缩估计:

Σ^shrunk=δF+(1−δ)Σ^\hat{\Sigma}_{\text{shrunk}} = \delta F + (1 - \delta) \hat{\Sigma}

其中 FF 是”结构化目标”,通常取单位阵的倍数 F=σˉ2IF = \bar{\sigma}^2 I,δ∈[0,1]\delta \in [0, 1] 是收缩强度,通过解析方式选择以最小化期望平方误差:

δ⋆=∑i,jVar(σ^ij)/N2∑i,j((σ^ij−fij)2/N2)\delta^\star = \frac{\sum_{i,j} \text{Var}(\hat{\sigma}_{ij}) / N^2}{\sum_{i,j} \left( (\hat{\sigma}_{ij} - f_{ij})^2 / N^2 \right)}

用文字描述:把样本协方差向”平均方差乘以单位阵”做收缩,强度选择要使收缩后估计的均方误差低于样本估计。

Ledoit-Wolf 收缩是”旋转不变”的,也就是说它不关心资产的方位。在”协方差应接近 FF“的先验下,结合高斯假设,它也是最大似然估计。

更灵活的一个版本是”近似 oracle 收缩”(OAS),它使用了不同的目标,在高维场景下通常表现更好。

对 μ\mu,可以向横截面均值 μˉ1\bar{\mu} \mathbf{1} 收缩、向零收缩,或向均衡先验收缩(这正是 Black-Litterman 的做法,见下一篇文章)。

收缩的效果:把权重拉向等权或拉向结构化目标。从数学上保证降低样本外权重的方差,代价是引入一些样本内偏差。实践中几乎总是净赚的。

修复二:重采样

Michaud 自己的方案是重采样(后来在 Michaud & Michaud, 1998 中正式成型,并由 López de Prado 的 Advances in Financial Machine Learning(2018,第 16 章)落地为可操作流程)。

步骤如下:

  1. 从历史收益中生成 BB 个 bootstrap 样本。
  2. 对每个 bootstrap 样本,估计 (μ^b,Σ^b)(\hat{\mu}_b, \hat{\Sigma}_b) 并计算最优组合 wb⋆w_b^\star。
  3. 平均权重:wˉ=1B∑bwb⋆\bar{w} = \frac{1}{B} \sum_b w_b^\star。

直觉:bootstrap 样本是对同一潜在分布的有噪声估计,它们的最优解围绕真实最优分散开。取平均就能得到中心位置的更稳定估计,同时也抹平了来自任一 bootstrap 样本的极端权重分配。

数学上的可行性来自:每个 wb⋆w_b^\star 具有相同的期望值(真实最优),bootstrap 过程提供了来自优化器抽样分布的(近似)独立抽样。在中心极限定理下,平均权重的方差以 1/B1/B 缩放。

代码层面,核心循环很短:

import numpy as np
from scipy.optimize import minimize

def resampled_weights(returns, target_return, n_bootstrap=200):
    n_obs, n_assets = returns.shape
    weights = np.zeros((n_bootstrap, n_assets))
    
    for b in range(n_bootstrap):
        # Bootstrap resample with replacement
        idx = np.random.choice(n_obs, size=n_obs, replace=True)
        boot = returns[idx]
        mu_b = boot.mean(axis=0)
        Sigma_b = np.cov(boot.T)
        
        # Solve MVO on this bootstrap sample
        weights[b] = solve_mvo(mu_b, Sigma_b, target_return)
    
    # Average the optimal weights
    return weights.mean(axis=0)

López de Prado 在 mlfinlab 中的实现给这套流程加了额外的安全检查。他还指出了一个重要的细节:如果在第 2 步中配合使用收缩或稳健输入,可以叠加各种改进。重采样可以和所有其他方法叠加。

代价:重采样很慢。每轮迭代都是一个 QP 求解。对 B=200B = 200、N=100N = 100,相当于求解 200 个二次规划。在现代机器上配合 cvxpy 或 quadprog 是几秒钟的事,而在 1990 年代的彭博终端上则不可行,这也是 Michaud 的思想花了 30 年才被采纳的部分原因。

修复三:稳健优化

第三族修复把输入视为不确定的,并针对最坏情况进行优化。Goldfarb & Iyengar (2003) 是经典文献。本模块后面会单独写一篇文章。

核心思路:不求解

min⁡ww⊤Σ^w\min_w w^\top \hat{\Sigma} w

而求解

min⁡wmax⁡Σ∈Uw⊤Σw\min_w \max_{\Sigma \in \mathcal{U}} w^\top \Sigma w

其中 U\mathcal{U} 是围绕 Σ^\hat{\Sigma} 的不确定集。U\mathcal{U} 的常见选择:

  • 盒式不确定:每个 σij\sigma_{ij} 独立地在 ±ϵ\pm \epsilon 内变化。
  • 椭球不确定:U={Σ:(Σ−Σ^)∈E}\mathcal{U} = \{\Sigma : (\Sigma - \hat{\Sigma}) \in \mathcal{E}\},E\mathcal{E} 为某椭球。

稳健对偶问题仍是凸规划(事实上常常仍是 QP 或 SOCP)。它给出的权重能保证在不确定集中的任意输入下都接近最优。代价是权重通常比名义最优更保守。

Tütüncü & Koenig (2004) 证明:椭球不确定下的稳健 MVO 等价于对协方差矩阵”加稳健化”后的 MVO:

Σrobust=Σ^+δI\Sigma_{\text{robust}} = \hat{\Sigma} + \delta I

即加上单位阵的倍数。这本质上就是换了件外衣的 Ledoit-Wolf 收缩,只不过推导来自 max-min 论证而非 min-MSE 论证。

实践中的选择

实践建议:

  • 样本 MVO:永远不要在生产环境中使用。仅供学习。
  • 对 Σ\Sigma 做收缩(Ledoit-Wolf):便宜、理论扎实,几乎总能改善样本外表现。用它。
  • 对 μ\mu 做收缩:也不错,但目标选择更重要。Black-Litterman 提供了一个有原则的目标。
  • 重采样:效果好,但计算代价不小。López de Prado 推荐它在回测中作为默认方法。
  • 稳健 MVO:当你对输入不确定度有强先验时很有用。在纯多头股票组合中较少部署。
  • 约束:这是隐形的杀手。加上 1⊤w=1\mathbf{1}^\top w = 1、w≥0w \geq 0 以及行业/资产上限,能在不使用上述任何工具的情况下大幅稳定权重。

合理的生产配置:对 Σ\Sigma 做 Ledoit-Wolf 收缩,对 μ\mu 用 Black-Litterman 先验(下一篇文章),重采样得到最终权重,并配合不允许做空和集中度约束。这是一个站得住脚的机构级配置。

文献综述

  • Michaud (1989). “The Markowitz Optimization Enigma: Is ‘Optimized’ Optimal?” Financial Analysts Journal 45(1): 31-42. “误差放大器”的批评。
  • Michaud & Michaud (1998). Efficient Asset Management. Harvard Business School Press. 重采样方案。
  • Ledoit & Wolf (2004). “A Well-Conditioned Estimator for Large-Dimensional Covariance Matrices.” Journal of Multivariate Analysis 88(2): 365-411. 收缩估计量。
  • Ledoit & Wolf (2003). “Improved Estimation of the Covariance Matrix of Stock Returns with an Application to Portfolio Selection.” Journal of Empirical Finance 10(5): 603-621.
  • Frost & Savarino (1986). “An Empirical Bayes Approach to Efficient Portfolio Selection.” Journal of Financial and Quantitative Analysis 21(3): 293-305.
  • Kan & Zhou (2007). “Optimal Portfolio Selection with Risk-Constraint.” Quantitative Finance 7(2): 165-185. 偏差-方差分解。
  • DeMiguel, Garlappi & Uppal (2009). “Optimal Versus Naive Diversification: How Inefficient is the 1/N Portfolio Strategy?” Review of Financial Studies 22(5): 1915-1953. 1/N 跑赢优化组合的结果。
  • Goldfarb & Iyengar (2003). “Robust Portfolio Selection Problems.” Mathematics of Operations Research 28(1): 1-21. 稳健 MVO 基础。
  • López de Prado (2018). Advances in Financial Machine Learning. Wiley. 第 16 章详细讨论重采样。ISBN: 978-1-119-48208-6.
  • Tütüncü & Koenig (2004). “Robust Asset Allocation.” Annals of Operations Research 132(1-4): 157-187. 稳健 MVO 的等价性。

仿真研究

“误差放大器”效应在仿真中最为直观。下面是一个完整实验:

  1. 从已知真实分布(例如,均值为 μ0\mu_0、协方差为 Σ0\Sigma_0 的多元正态)生成 N=50N = 50 个资产、T=60T = 60 个月的收益。
  2. 计算样本估计 μ^,Σ^\hat{\mu}, \hat{\Sigma}。
  3. 求解 MVO。计算差距 ∥w⋆(μ^,Σ^)−w⋆(μ0,Σ0)∥\|w^\star(\hat{\mu}, \hat{\Sigma}) - w^\star(\mu_0, \Sigma_0)\|。
  4. 重复 1000 次。绘制差距的直方图。

对 N=50N = 50、T=60T = 60,差距常常超过 ∥w⋆(μ0,Σ0)∥\|w^\star(\mu_0, \Sigma_0)\| 本身。也就是说,估计出的最优点平均而言比等权组合离真实最优还要更远。这就是”误差放大器”效应在起作用。

import numpy as np
from scipy.optimize import minimize

def simulate_mvo_error(N=50, T=60, n_trials=1000):
    # True parameters
    mu_0 = np.random.uniform(0.05, 0.15, N) / 12  # Monthly
    A = np.random.randn(N, N) * 0.02
    Sigma_0 = A @ A.T + np.eye(N) * 0.001  # PSD
    
    # True optimum (long-only for realism)
    def neg_sharpe_unconstrained(w):
        return -(w @ mu_0) / np.sqrt(w @ Sigma_0 @ w)
    
    # Run trials
    gaps_naive = []
    for _ in range(n_trials):
        # Generate sample
        returns = np.random.multivariate_normal(mu_0, Sigma_0, T)
        mu_hat = returns.mean(axis=0)
        Sigma_hat = np.cov(returns.T)
        
        # Solve MVO with sample estimates
        w_naive = np.linalg.solve(Sigma_hat, mu_hat)
        w_naive = w_naive / w_naive.sum()  # Normalize
        
        # True optimum (unconstrained, then normalized)
        w_true = np.linalg.solve(Sigma_0, mu_0)
        w_true = w_true / w_true.sum()
        
        gaps_naive.append(np.linalg.norm(w_naive - w_true))
    
    return np.mean(gaps_naive), np.std(gaps_naive)

mean_gap, std_gap = simulate_mvo_error()
print(f"Mean gap: {mean_gap:.4f}, Std: {std_gap:.4f}")

对典型参数,平均差距在 1.5-3.0 之间(归一化权重空间)。等权组合的差距约为 0.5-1.0。所以使用样本估计的 MVO 平均而言比等权还差。这不是偶然,而是结构性特征。

贝叶斯替代方案

一种更有原则的处理估计误差的方法是:对 (μ,Σ)(\mu, \Sigma) 做贝叶斯推断。

模型:

μ∼N(μ0,Σμ),rt∣μ∼N(μ,Σ)\mu \sim \mathcal{N}(\mu_0, \Sigma_\mu), \quad r_t | \mu \sim \mathcal{N}(\mu, \Sigma)

带有先验超参数 (μ0,Σμ,Σ)(\mu_0, \Sigma_\mu, \Sigma)。

后验:

μ∣r1:T∼N((TΣ−1+Σμ−1)−1(TΣ−1rˉ+Σμ−1μ0), (TΣ−1+Σμ−1)−1)\mu | r_{1:T} \sim \mathcal{N}\left( (T \Sigma^{-1} + \Sigma_\mu^{-1})^{-1} (T \Sigma^{-1} \bar{r} + \Sigma_\mu^{-1} \mu_0), \ (T \Sigma^{-1} + \Sigma_\mu^{-1})^{-1} \right)

后验均值就是一种收缩估计量,它把样本均值 rˉ\bar{r} 向先验均值 μ0\mu_0 收缩,强度取决于相对精度。

贝叶斯最优组合为:

w⋆=1δΣ−1E[μ∣data]w^\star = \frac{1}{\delta} \Sigma^{-1} \mathbb{E}[\mu | \text{data}]

即把后验均值代回标准的 MVO。

这套思路在数学上很干净。它推广了 Black-Litterman(后者本身就是一个贝叶斯模型,其中 μ0\mu_0 取均衡收益)。它也推广了 James-Stein 收缩(即 K=1K = 1 时这一框架的经验贝叶斯版本)。

层次贝叶斯

对多层估计问题(例如,行业组合嵌套股票组合),层次贝叶斯给出部分池化。思路是:

μsector∼N(μ0,Σsector),μstock∼N(μsector,Σstock)\mu_{\text{sector}} \sim \mathcal{N}(\mu_0, \Sigma_{\text{sector}}), \quad \mu_{\text{stock}} \sim \mathcal{N}(\mu_{\text{sector}}, \Sigma_{\text{stock}})

估计股票层面的均值需要数据,但向行业层均值部分池化能减少估计误差。这正是因子模型底层的结构。

对时变预期收益 μt\mu_t 还可以引入布朗运动先验。模型为:

μt+1=μt+ηt,ηt∼N(0,Ση)\mu_{t+1} = \mu_t + \eta_t, \quad \eta_t \sim \mathcal{N}(0, \Sigma_\eta)

并有 rt∣μt∼N(μt,Σ)r_t | \mu_t \sim \mathcal{N}(\mu_t, \Sigma)。Kalman 滤波器给出最优的 E[μt∣r1:t]\mathbb{E}[\mu_t | r_{1:t}],它就是一个时变收缩估计量。

这是应对”时变 alpha 主动管理”的正确框架。Black-Litterman 模型可以扩展来处理这种情况(Meucci, 2008)。

交叉验证用于超参数选择

上述大多数方法都有超参数:收缩强度 δ\delta、观点协方差 Ω\Omega、稳健不确定集大小。标准做法是通过交叉验证来选择它们。

步骤:

  1. 将历史数据切分为 KK 折(按时间序列感知的方式,而非随机)。
  2. 对每一折,在训练部分拟合超参数。
  3. 在留出部分上评估样本外表现。
  4. 选取平均留出表现最好的超参数。

López de Prado 提出的”组合式净化交叉验证”(CPCV)是金融时间序列上的严格版本。它考虑了序列自相关和多重检验问题。

实践中,多数机构是通过回测(而非交叉验证)来选超参数。回测更易解读,也与策略评估方式一致。代价是过拟合:如果你测试 100 组超参数,必然挑到一组”恰好在过去有效”的。

诚实的做法:把数据切分为训练、验证、测试三段。在验证段上调参。最终只在测试段评估一次,且只评估一次。把测试段当成只能考一次的期末考试。

为什么这篇文章重要

只要你打算运行任何 MVO 变体,就必须理解估计误差问题。数学不可省。仿真结果不可省。修复方法不可省。

本模块接下来的 11 篇文章在某种意义上都是对本文的回应。我们要讨论的每种方法(Black-Litterman、风险平价、HRP、CVaR、稳健 MVO)都是在应对 (μ,Σ)(\mu, \Sigma) 未知这一事实。

要点回顾

Markowitz 优化在数学上优美、在实践上不稳定。不稳定性来源于 μ\mu 和 Σ\Sigma 的估计误差,被优化器对这些估计的敏感性进一步放大。

“误差放大器”效应是 MVO 的结构性特征,而非 bug。仿真显示,使用样本估计的 MVO 在平均误差上高于等权。这正是 Michaud 在 1989 年抱怨的事。

存在三族修复方法:收缩(对输入做正则化)、重采样(平均掉优化器的不稳定性)、稳健优化(针对最坏情形优化)。贝叶斯推断是第四种思路,它把前三者统一起来。这四种都有效。

最站得住脚的生产配置是把它们和合理的约束组合起来:对 Σ\Sigma 做 Ledoit-Wolf,对 μ\mu 做 Black-Litterman,用重采样得到最终权重,全程不允许做空。

下一篇文章:Black-Litterman,让 MVO 的贝叶斯升级,把 μ\mu 估计从缺陷变成特性。