在cvxpy中定义软约束

时间:2018-03-29 20:31:26

标签: optimization constraints convex-optimization cvxpy

我正在使用cvxpy进行简单的投资组合优化。

我实现了以下虚拟代码

from cvxpy import *
import numpy as np

np.random.seed(1)
n = 10

Sigma = np.random.randn(n, n) 
Sigma = Sigma.T.dot(Sigma)

orig_weight = [0.15,0.25,0.15,0.05,0.20,0,0.1,0,0.1,0]
w = Variable(n)

mu = np.abs(np.random.randn(n, 1))
ret = mu.T*w

lambda_ = Parameter(sign='positive')
lambda_ = 5

risk = quad_form(w, Sigma)

constraints = [sum_entries(w) == 1, w >= 0, sum_entries(abs(w-orig_weight)) <= 0.750]

prob = Problem(Maximize(ret - lambda_ * risk), constraints)

prob.solve()

print 'Solver Status : ',prob.status

print('Weights opt :', w.value)

我正在限制完全投资,只是长期并且营业额<= 75%。但是我想将周转作为一个“软”约束,因为求解器将尽可能少地使用但是尽可能多地使用,目前求解器几乎完全可以最大化周转率。

我基本上想要这样的东西,它是凸的并且不违反DCP规则

sum_entries(abs(w-orig_weight)) >= 0.05

我认为这应该设置一个最小阈值(此处为5%),然后使用尽可能多的周转率,直到找到可行的解决方案。

我尝试将目标函数重写为

prob = Problem(Maximize(lambda_ * ret - risk - penalty * max(sum_entries(abs(w-orig_weight))+0.9,0))  , constraints)

罚款例如2,我的约束对象仍然看起来像

constraints = [sum_entries(w) == 1, w >= 0, sum_entries(abs(w-orig_weight)) <= 0.9]

我从未使用过软限制,任何解释都会受到高度赞赏。

编辑:中级解决方案

from cvxpy import *
import numpy as np

np.random.seed(1)
n = 10

Sigma = np.random.randn(n, n) 
Sigma = Sigma.T.dot(Sigma)
w = Variable(n)

mu = np.abs(np.random.randn(n, 1))
ret = mu.T*w

risk = quad_form(w, Sigma)

orig_weight = [0.15,0.2,0.2,0.2,0.2,0.05,0.0,0.0,0.0,0.0]

min_weight = [0.35,0.0,0.0,0.0,0.0,0,0.0,0,0.0,0.0]
max_weight = [0.35,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]

lambda_ret = Parameter(sign='positive')
lambda_ret = 5

lambda_risk = Parameter(sign='positive')
lambda_risk = 1

penalty = Parameter(sign='positive')
penalty = 100

penalized = True

if penalized == True:
    print '-------------- RELAXED ------------------'
    constraints = [sum_entries(w) == 1, w >= 0, w >= min_weight, w <= max_weight]
    prob = Problem(Maximize(lambda_ * ret - lambda_ * risk - penalty * max_entries(sum_entries(abs(w-orig_weight)))-0.01), constraints)
else:
    print '--------------   HARD  ------------------'
    constraints = [sum_entries(w) == 1, w >= 0, w >= min_weight, w <= max_weight, sum_entries(abs(w-orig_weight)) <= 0.40]
    prob = Problem(Maximize(lambda_ret * ret - lambda_risk * risk ),constraints)

prob.solve()

print 'Solver Status : ',prob.status
print('Weights opt :', w.value)

all_in = []
for i in range(n):
    all_in.append(np.abs(w.value[i][0] - orig_weight[i]))

print 'Turnover : ', sum(all_in)

以上代码将强制项目[0]的权重特定增加,此处为+ 20%,以保持sum()= 1约束必须抵消-20%的减少,因此我知道它需要至少40%的营业额才能做到这一点,如果一个运行代码,惩罚= False,&lt; = 0.4必须硬编码,任何小于此的东西都将失败。惩罚=真实案例将找到40%的最低要求营业额并解决优化问题。我还没想到的是如何在宽松的情况下设置最低阈值,即至少达到45%(如果需要的话,或者更多)。

我在第4.6章第37页找到了解决这个问题的一些解释。

Boyed Paper

0 个答案:

没有答案