如何在CVXPY中编写复杂约束?投资组合优化约束添加求助
解决CVXPY投资组合优化中的权重变动约束问题
嘿,我来帮你搞定这个约束添加的问题!首先提个小细节:你定义的w是一维的CVXPY变量(cvx.Variable(38)),所以在约束里访问单个权重应该用w[i],而不是w[1][i]——虽然求解后w.value会以二维列向量的形式返回,但变量本身是一维的,直接用索引访问就可以啦。
接下来,要实现“每个权重与初始权重的绝对值差大于0.005”的约束,你有两种简洁的方式:
方式1:循环逐个添加约束
这种方式直观,适合新手理解:
import cvxpy as cvx import numpy as np # 假设你的initial_weights和rets已经定义好 initial_weights = [0.045, 0.035, 0.024, 0.028] + [0.0]*34 # 补全到38个元素 data = ... # 你的原始数据 rets = np.log(data/data.shift(1)) w = cvx.Variable(38) ret = np.sum(rets.mean()*w)*252 # 初始化约束列表 constraints = [ cvx.sum_entries(w) == 1, w >= 0.02, # 这里建议用>=而非>,CVXPY对严格不等式的处理有限 w <= 0.06 ] # 遍历每个索引,添加绝对值差约束 for i in range(len(initial_weights)): constraints.append(cvx.abs(initial_weights[i] - w[i]) >= 0.005) # 构建并求解问题 prob = cvx.Problem(cvx.Maximize(ret), constraints) result = prob.solve()
方式2:向量化添加约束(更高效)
CVXPY支持向量化操作,不用循环就能批量添加约束,代码更简洁,尤其当变量数量大的时候效率更高:
import cvxpy as cvx import numpy as np initial_weights = [0.045, 0.035, 0.024, 0.028] + [0.0]*34 data = ... rets = np.log(data/data.shift(1)) w = cvx.Variable(38) ret = np.sum(rets.mean()*w)*252 # 用向量化方式构建所有约束 constraints = [ cvx.sum_entries(w) == 1, w >= 0.02, w <= 0.06, # 直接对整个向量做绝对值差约束 cvx.abs(cvx.Constant(initial_weights) - w) >= 0.005 ] prob = cvx.Problem(cvx.Maximize(ret), constraints) result = prob.solve()
小提示
注意我把原来的w>0.02和w<0.06改成了w>=0.02和w<=0.06——这是因为CVXPY(以及大多数凸优化求解器)对严格不等式的支持有限,通常建议用非严格不等式来替代,这样求解器能更稳定地处理问题。
内容的提问来源于stack exchange,提问作者Ray234
相关产品推荐
相关产品推荐

