Reputation: 169
I am trying to solve a portfolio optimisation problem with the constraint that weights can be either zero or at least min
(a Nx1
vector).
import cvxpy as cp
w = cp.Variable(len(mu))
mins = np.ones(len(mu)) * 0.03
risk = cp.quad_form(w, S)
prob = cp.Problem(cp.Minimize(risk),
[cp.sum(w) == 1,
w >= 0,
w >= min OR w == 0 # pseudocode for my desired constraint]
This is equivalent to a constraint that the weights are NOT 0 < w <= min
, but I cannot find a way to express this in CVXPY (I have googled things like "cvxpy OR constraint" to no avail).
It feels like I'm missing something obvious. Perhaps there is a solution involving some boolean vector?
Upvotes: 2
Views: 2616
Reputation: 169
Based on Erwin's answer, this is the working code.
import cvxpy as cp
w = cp.Variable(n)
mins = np.ones(n) * 0.03
maxs = np.ones(n)
risk = cp.quad_form(w, S)
prob = cp.Problem(cp.Minimize(risk),
[cp.sum(w) == 1,
w >= 0,
w >= cp.multiply(k, mins),
w <= cp.multiply(k, maxs)])
prob.solve(solver="ECOS_BB")
EDIT: changed k @ mins
to cp.multiply(k, mins)
as per comment
Upvotes: 1
Reputation: 16724
This is called w
being a semi-continuous variable. Most advanced solvers support this type of variable directly. As CVXPY does not understand semi-continuous variables, we can use binary variables δ ∈ {0,1} and form the constraints:
δ⋅min ≤ w ≤ δ⋅max
where we can set max=1
.
This makes the problem a MIQP (Mixed-Integer Quadratic Programming) problem. This usually means that you need to use a high-end solver that supports this type of model.
Upvotes: 2