
blog 中级 · ~1 min read
用 scipy 计算有效前沿与最优权重
用 scipy 计算有效前沿和最优组合权重,涵盖约束、切线组合和常见优化陷阱。
#portfolio-theory#money-management
本文为英文。需要查看中文翻译吗?
交互工具在翻译视图中可能无法使用。
用 scipy 计算有效前沿与最优权重
有效前沿是在每个风险水平下最大化预期收益的组合集合。算它是个约束优化问题——约束比目标更重要。
准备输入
需要三个数组:预期收益(历史均值或前瞻估计)、协方差矩阵、无风险利率。用 3–5 年月度收益;日收益让相关性过稳,周度是合理折中。
最小方差组合
最简单的最优组合是在权重和为 1 的约束下最小化方差:
import numpy as np
from scipy.optimize import minimize
def portfolio_var(w, cov):
return w @ cov @ w
n = len(mu)
cons = [{"type": "eq", "fun": lambda w: np.sum(w) - 1}]
bounds = [(0, 1)] * n
w0 = np.ones(n) / n
res = minimize(portfolio_var, w0, args=(cov,), method="SLSQP",
bounds=bounds, constraints=cons)
w_minvar = res.x
切线(最大 Sharpe)组合
切线组合最大化 Sharpe 比率——从无风险利率出发的直线与前沿相切的点:
def neg_sharpe(w, mu, cov, rf):
return -(w @ mu - rf) / np.sqrt(w @ cov @ w)
res = minimize(neg_sharpe, w0, args=(mu, cov, rf), method="SLSQP",
bounds=bounds, constraints=cons)
w_tan = res.x
描出前沿
对每个目标收益水平,最小化方差:
def min_var_for_target(target, mu, cov):
cons = [{"type": "eq", "fun": lambda w: np.sum(w) - 1},
{"type": "eq", "fun": lambda w: w @ mu - target}]
res = minimize(portfolio_var, w0, args=(cov,), method="SLSQP",
bounds=bounds, constraints=cons)
return res
目标从最小方差收益循环到单资产最大收益,画出曲线。
为什么朴素优化会失败
马科维茨优化不稳定:输入小变动产生权重剧烈摆动。两个防御:
- 约束权重。 单一权重封顶 30%–40%,即使优化器想要 70%。只做多加上限的权重远比无约束稳定。
- 收缩协方差。 用收缩估计量(Ledoit-Wolf)替换样本协方差,向对角矩阵混合。这大幅削减估计误差。
实操陷阱
- 垃圾收益进、垃圾权重出。 均值收益估计误差巨大;协方差估计更可靠。先优化风险,再优化收益。
- 没交易成本。 真实再平衡每轮 10–30 bp 成本;忽略这点的优化器会折腾组合。
- 点估计。 前沿是云不是线。用重采样输入重跑,每次得到不同曲线。
诚实的用法
用优化器找合理权重的邻域,再施加判断。原始历史数据的切线组合很少是你该持有的;稳健、约束、收缩平滑后的版本更接近。
实时行情
打开完整图表 →相关市场数据由 TradingView 提供。
📝
我的笔记
登录后可在本文保存笔记并与社区分享。
由 Marcus Cole 起草 · 由 Timi Chen 于 2026-07-01 审核 · 最后检查于 2026-07-01
相关内容
下一篇推荐
portfolio-theorymoney-management 2026-07-01
Risk Parity Implementation and Calibration in Practice
Practical risk parity implementation covers weight solving, volatility targeting, leverage calibration, and rebalancing rules with concrete numeric thresholds.
阅读更多 →Smart Recommendations