I am using cvxpy to do a simple portfolio optimization.
I implemented the following dummy code
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)
I am constraining on being fully invested, long only and to have a turnover of <= 75%. However I would like to use turnover as a "soft" constraint in the sense that the solver will use as little as possible but as much as necessary, currently the solver will almost fully max out turnover.
I basically want something like this which is convex and doesn't violate the DCP rules
sum_entries(abs(w-orig_weight)) >= 0.05
I would assume this should set a minimum threshold (5% here) and then use as much turnover until it finds a feasible solution.
I tried rewriting my objective function to
prob = Problem(Maximize(lambda_ * ret - risk - penalty * max(sum_entries(abs(w-orig_weight))+0.9,0)) , constraints)
where penalty is e.g. 2 and my constraint object still looks like
constraints = [sum_entries(w) == 1, w >= 0, sum_entries(abs(w-orig_weight)) <= 0.9]
I have never used soft-constraints and any explanation would be highly appreciated.