Python投资组合开发嵌套函数neg_sharpe_ratio缺失参数报错求解
问题原因
报错是scipy.optimize.minimize调用时传递的额外参数不匹配导致的,根因有两点:
- 你定义的嵌套函数
neg_sharpe_ratio声明了4个入参:weights、riskfree_rate、er、cov,但minimize调用时args参数仅传了(cov,)一个值,缺失另外两个必要参数 - 即使外层
msr已经定义了er、cov,只要你把这两个变量写在了neg_sharpe_ratio的入参列表里,Python就会要求调用时显式传值,不会自动复用外层的同名变量
修复方案
方案1:利用闭包特性简化代码(更推荐)
嵌套在msr内部的函数天然可以直接访问外层函数的所有局部变量,不需要把riskfree_rate、er、cov放到内层函数的入参列表里,修改后代码如下:
from scipy.optimize import minimize import numpy as np # 需提前导入你用到的erk模块 def msr(riskfree_rate, er, cov): n = er.shape[0] init_guess = np.repeat(1/n, n) bounds = ((0.0, 1.0),) * n weights_sum_to_1 = { 'type': 'eq', 'fun': lambda weights: np.sum(weights) - 1 } # 内层函数仅保留weights参数,直接复用外层变量 def neg_sharpe_ratio(weights): r = erk.portfolio_return(weights, er) vol = erk.portfolio_vol(weights, cov) return -(r - riskfree_rate) / vol results = minimize( neg_sharpe_ratio, init_guess, method="SLSQP", options={'disp': False}, constraints=(weights_sum_to_1), bounds=bounds ) return results.x
方案2:补全args参数传递
如果你需要保留内层函数的完整参数声明,就按参数顺序补全args里的所有值:
from scipy.optimize import minimize import numpy as np # 需提前导入你用到的erk模块 def msr(riskfree_rate, er, cov): n = er.shape[0] init_guess = np.repeat(1/n, n) bounds = ((0.0, 1.0),) * n weights_sum_to_1 = { 'type': 'eq', 'fun': lambda weights: np.sum(weights) - 1 } def neg_sharpe_ratio(weights, riskfree_rate, er, cov): r = erk.portfolio_return(weights, er) vol = erk.portfolio_vol(weights, cov) return -(r - riskfree_rate)/vol results = minimize( neg_sharpe_ratio, init_guess, # 按参数顺序补全三个额外参数 args=(riskfree_rate, er, cov), method="SLSQP", options={'disp': False}, constraints=(weights_sum_to_1), bounds=bounds ) return results.x
内容的提问来源于stack exchange,提问作者Roms
相关产品推荐
相关产品推荐

