先说结论:8 资产配置问题、10 年月度数据估计参数,在 150 个平行世界的模拟里,经典均值方差优化选出的中风险组合,真实参数下的夏普比率中位数 0.680、最差 5% 只有 0.492;同样的输入换成 Michaud 重抽样(每个世界内部做 200 次参数扰动、把 200 条前沿的权重逐点平均),夏普中位数升到 0.745、最差 5% 抬到 0.630——不但中枢更高,尾部风险更小。附带的礼物是稳定性:输入数据微变时,经典优化的组合权重中位双边换手 110.6%,重抽样只有 48.9%,砍掉一半以上。 重抽样没有发明新信息,它做的事情只有一件:承认输入参数是带误差的随机变量,然后把优化器对误差的过度反应平均掉。
这篇是Ledoit-Wolf 收缩估计的姊妹篇。收缩修的是协方差的估计误差,重抽样对付的是更凶的敌人——期望收益的估计误差,以及优化器把这些误差原样放大的坏习惯。
问题:均值方差优化是误差最大化器#
Markowitz 优化在数学上无懈可击,问题出在输入。期望收益 μ 的估计误差远大于协方差:10 年月度数据估一个年化 8%、波动 20% 的资产的均值,标准误是 ——置信区间宽到覆盖从 1.7% 到 14.3%,而资产之间的真实差异往往只有两三个百分点。
优化器对这种噪声的反应是灾难性的:它会把误差当信号,给”碰巧被高估”的资产满仓,给”碰巧被低估”的资产零仓。角点解、锯齿状的权重过渡、输入变 1% 权重翻 40%,全是这一个机制的表现。Michaud 称之为 “error maximization”:优化器系统性地偏爱估计误差最大的方向。
先看它有多丑。8 个资产(A股大盘/小盘、港股、美股、发达债、信用债、黄金、商品),真实参数已知,用一次 10 年样本估计 μ 和 Σ,做 long-only 有效前沿:
import numpy as np
from scipy.optimize import minimize
def mv_frontier_lo(mu_, Sigma_, N, n_pts=30):
"""long-only 均值方差前沿:目标收益网格 + SLSQP"""
rets = np.linspace(mu_.min()+1e-4, mu_.max()-1e-4, n_pts)
ws = []
for R in rets:
cons = [{'type': 'eq', 'fun': lambda w: w.sum() - 1},
{'type': 'eq', 'fun': lambda w, R=R: w @ mu_ - R}]
res = minimize(lambda w: w @ Sigma_ @ w, np.ones(N)/N,
bounds=[(0, 1)]*N, constraints=cons, method='SLSQP')
ws.append(res.x)
return rets, np.array(ws)
# 一次样本估计
T = 120 # 月
X = rng.multivariate_normal(mu_true / 12, Sigma_true / 12, size=T)
mu_hat, Sigma_hat = X.mean(0) * 12, np.cov(X, rowvar=False) * 12
rets, W_classic = mv_frontier_lo(mu_hat, Sigma_hat, N=8)pythonMichaud 的处方:把前沿变成平均值#
Richard Michaud(1998)的 Resampled Efficiency 流程:
- 用样本估计 (这是你唯一的信息);
- 从 再抽 B 组同长度的伪历史,每组重新估计 ;
- 对每组参数解一条完整的有效前沿,得到 B 条前沿;
- 把 B 条前沿在对应等级点上的权重逐点平均(本文用前沿位置的分位对齐),归一化后得到重抽样前沿。
B, n_pts = 200, 30
W_resampled = np.zeros((B, n_pts, 8))
frac = np.linspace(0.02, 0.98, n_pts) # 用分位位置对齐各条前沿
for b in range(B):
Xb = rng.multivariate_normal(mu_hat / 12, Sigma_hat / 12, size=T)
mu_b, Sig_b = Xb.mean(0) * 12, np.cov(Xb, rowvar=False) * 12
lo, hi = mu_b.min()+1e-4, mu_b.max()-1e-4
for k, R in enumerate(lo + frac * (hi - lo)):
W_resampled[b, k] = solve_one_point(mu_b, Sig_b, R) # 同上的 SLSQP
W_michaud = W_resampled.mean(axis=0)
W_michaud /= W_michaud.sum(1, keepdims=True)python平均为什么有用?因为估计误差引起的极端权重在不同抽样中方向随机:这次样本里 A股小盘碰巧被高估、满仓,下次样本里可能变成商品满仓。平均把这些随机的满仓/清仓互相抵消,留下的是在大多数抽样里都稳定出现的配置结构。它本质上是组合权重空间里的 bagging——和随机森林用同一个统计原理。
结果一:真实参数下的前沿位置#
用真实参数评估三条前沿(这是模拟实验才有的奢侈——现实中你永远不知道真实参数):

黑线是理论上限(真实参数的经典前沿)。红虚线是一次样本估计的经典前沿在真实参数下的实际位置——注意它整体塌陷:样本内看起来光鲜的前沿,真实收益/风险坐标里全面缩水,中风险点的真实期望收益 5.29%、波动 7.48%。蓝线是重抽样前沿:真实收益 4.75%、波动 6.26%——收益低一点,但波动低更多,风险调整后更优(这正是下面夏普分布要系统验证的)。
结果二:权重从锯齿变平滑#
前沿上 30 个等级点的权重过渡图,是重抽样最直观的卖点:

左边经典优化:色块边界锯齿状跳动,很多资产在相邻等级点之间从 0 直接跳到 30%+ 再跳回 0——这是角点解在换班,每一次换班都是实盘里一笔莫名其妙的大额调仓。右边重抽样:所有资产的权重随风险等级平滑过渡,低风险端由债券主导、高风险端逐步换成权益,没有任何资产在相邻点之间突变。给投资委员会看,右边这张图是唯一能通过的。
结果三:150 个平行世界的夏普分布与换手#
单次对比可能是运气,所以做系统实验:150 个”世界”,每个世界独立生成 10 年月度数据 → 经典优化和重抽样(世界内部 B=50)各选中风险组合 → 用真实参数算夏普:
| 指标 | 经典优化 | Michaud 重抽样 |
|---|---|---|
| 真实夏普 中位数 | 0.680 | 0.745 |
| 真实夏普 最差 5% | 0.492 | 0.630 |
| 相邻世界双边换手 中位数 | 110.6% | 48.9% |

左图:重抽样的夏普分布整体右移且明显更窄——不是偶尔赢,是分布性地赢,而且赢得最多的地方在左尾(0.630 vs 0.492,差 28%)。经典优化的左尾就是那些”优化器把噪声当信号、满仓了错误资产”的世界。右图:输入数据换一组(等价于每月滚动重估参数),经典优化的组合要双边换手 110%——几乎推倒重来,交易成本会把纸面优势吃光;重抽样 48.9%,因为平均权重对输入扰动天然低敏感。
实践备注与已知争议#
重抽样不是万能的,争议真实存在。Scherer(2002)指出:重抽样前沿的平均操作在 long-only 约束下有一个微妙的偏差——权重下界 0 是单边的,平均会系统性地把”经常贴 0”的资产抬离 0,高风险端的组合被拉向中间。这就是图 1 里蓝线比黑线短的原因:重抽样前沿到不了最激进的角落。如果你的目标就是最大化期望收益,重抽样会拖后腿;它的甜区是中低风险、多资产配置、重视稳定性的场景。
与收缩估计不冲突,应该叠加。重抽样处理的是”优化器对给定估计误差的过度反应”,收缩处理的是”减少估计误差本身”。实操顺序:先用 Ledoit-Wolf 收缩协方差、用 Bayes-Stein 收缩期望收益,再在收缩后的参数上做重抽样。两层保险各管一段。
计算成本。B=200 条前沿 × 30 个点 = 6000 次 QP,8 资产规模下单机十几秒;几百资产时改用更快的 QP 求解器(OSQP/ECOS)或减少前沿点数。注意专利问题:Michaud 的 Resampled Efficiency 在美国有专利(已于 2019 年到期),现在可以自由使用。
已知偏差:本文的平行世界从多元正态抽样,真实收益有厚尾和自相关,参数抽样应改用块自助(block bootstrap)从真实历史抽,结论的方向不变但数值会更保守;对齐 200 条前沿用的是分位位置法,Michaud 原版用目标风险对齐,两者在中段几乎无差、在两端略有出入。
一句话带走:优化器不知道你的输入是估出来的——重抽样替它知道。把 200 个可能世界的最优解平均,好过把一个噪声世界的最优解满仓。