Python中使用PuLP最小化平方差求解指数最优权重拟合个股收益
问题修正与实现方案
原代码存在的核心问题
- 工具适配错误:PuLP为线性规划求解库,仅支持线性目标与线性约束,你定义的平方项属于二次目标,PuLP原生不支持,运行直接报错。
- 目标函数逻辑错误:当前写法先对所有日度收益率求和再乘权重,计算的是总收益率的偏差平方,若需求是日度收益走势贴合,应计算每日收益偏差的平方和,二者逻辑完全不同。
- 约束缺失:漏了核心约束
wSPY + wSHY = 1,不符合你要求的权重和为1的规则。 - 冗余约束:定义变量时已经指定了
lowBound=0、upBound=1,后续额外添加的四个上下界约束属于重复内容,可以删除。
方案1:使用scipy实现最小化平方差(最贴合你的需求)
scipy的优化工具原生支持二次目标,实现更简单:
import numpy as np from scipy.optimize import minimize # 传入你的日度收益率列表 SPYretls = np.array(SPYretls) SHYretls = np.array(SHYretls) NOCretls = np.array(NOCretls) # 定义目标函数:最小化每日偏差的平方和 def objective(weights): wSPY, wSHY = weights daily_predict = wSPY * SPYretls + wSHY * SHYretls return np.sum((daily_predict - NOCretls)**2) # 约束:权重和为1 constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1}) # 权重范围[0,1] bounds = ((0,1), (0,1)) # 初始猜测值 x0 = [0.5, 0.5] # 求解 result = minimize(objective, x0, bounds=bounds, constraints=constraints) wSPY_opt, wSHY_opt = result.x print(f"最优SPY权重:{wSPY_opt:.4f},最优SHY权重:{wSHY_opt:.4f}")
方案2:改用线性目标适配PuLP(最小化绝对偏差)
如果必须使用PuLP,可以将目标改为最小化每日偏差的绝对值之和,属于线性优化问题,PuLP可直接求解:
from pulp import * import numpy as np SPYretls = np.array(SPYretls) SHYretls = np.array(SHYretls) NOCretls = np.array(NOCretls) n_days = len(SPYretls) model = LpProblem("Style", LpMinimize) wSPY = LpVariable("SPYw", lowBound=0,upBound=1, cat ='Continuous') wSHY = LpVariable("SHYw", lowBound=0,upBound=1, cat ='Continuous') # 定义每日偏差的绝对值辅助变量 dev = [LpVariable(f"dev_{i}", lowBound=0) for i in range(n_days)] # 目标:最小化总偏差 model += lpSum(dev) # 约束1:权重和为1 model += wSPY + wSHY == 1 # 约束2:每日偏差的绝对值约束 for i in range(n_days): model += wSPY * SPYretls[i] + wSHY * SHYretls[i] - NOCretls[i] <= dev[i] model += -(wSPY * SPYretls[i] + wSHY * SHYretls[i] - NOCretls[i]) <= dev[i] # 求解 model.solve() print(f"最优SPY权重:{value(wSPY):.4f},最优SHY权重:{value(wSHY):.4f}")
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

