优化器就是函数加规则
scipy.optimize.minimize(fun, x0, method='SLSQP', bounds=..., constraints=...) 找出使 fun 最小的向量。你给它三类信息。目标 fun(w) 返回要最小化的数:最小方差组合是 w @ cov @ w,要最大化某个量就最小化它的相反数。边界是每个权重一个 (下限, 上限) 的列表:(0, cap) 表示不做空且单个仓位不超过上限。约束是字典:{'type': 'eq', 'fun': lambda w: w.sum() - 1} 强制权重之和为一,因为 eq 函数必须等于零,而 ineq 函数必须大于或等于零。起点 x0 也重要:等权重是合理且可行的起点。
有两个细节决定答案对不对。第一是量纲:日方差是 0.0001 这样的数,SLSQP 在目标函数的变化小于容差 ftol(默认 1e-6)时停止,所以用原始日度数字时它可能停在起点不动。把输入年化(乘 252),传入 options={'ftol': 1e-12, 'maxiter': 500},并始终检查 result.success 以及权重是否遵守规则。第二是表述:最大化夏普比率是个比值,所以最小化 -(w @ mu) / sqrt(w @ cov @ w);风险平价要求风险份额相等 wᵢ(Σw)ᵢ/ wᵀΣw,所以最小化与 1/n 的平方差;有效前沿是每个目标收益一个最小方差问题,再加第二个 eq 约束 w @ mu - target。
真实数据的信息取十只股票、公用事业 DUK 和黄金 ETF GLD,使用最近 2,500 天的数据,单个资产最多 25%。等权重的波动率是 14.6%。最小方差组合通过持有 25% 黄金、18% JNJ 和 14% KO(不持有 AAPL 和 HD)把它降到 11.9%。最大夏普组合靠黄金、WMT 和 CAT 获得年化 21.3% 的收益、14.3% 的波动率,夏普比率 1.48:这个数字反映的是过去十年,而不是未来十年。风险平价在每个资产上持有 5.8% 到 19.6%,黄金最多,每个资产承担 8.3% 的风险。
- 量纲与容差:把输入年化并收紧
ftol,否则 SLSQP 可能停在起点。 - 检查答案:权重之和必须为一并遵守边界;查看
result.success。 - 一个工具,四类问题:最小方差、负夏普比率、等风险份额和每个目标收益一个问题,都是目标和约束不同的
minimize调用。
实验:评分内容
- 年化输入8 分
- 组合的收益与风险8 分
- 带上限的最小方差18 分
- 最大夏普比率18 分
- 风险贡献10 分
- 风险平价16 分
- 逐点构造前沿10 分
- 三个组合12 分