1
$\begingroup$

I am having trouble coming up with a function to optimize the weights to be as equal as possible.

It is a long-short portfolio with 6 positions weights is a cvx variable: [long, long, short, short, long/short, long/short]

There are some constraints such as gross exposure cannot exceed 2, gross long cannot exceed 1.5.

To get portfolio weights as close to equal weight as possible, one way is to minimize the variance of the absolute value of weights.

cvxpy.Minimize(cvx.sum_squares(cvx.sum(cvx.abs(weights)) - cvx.abs(weights)/6))

But this throws "does not follow DCP rules".

What's the problem in this line that causes the violation of DCP rules?

More importantly, any thoughts on how to write an objective function to push weights to as equal weight as possible?

Thanks!


Clarification on my question:

Here's the problem I need to solve:

I have a portfolio with 6 stocks, with the following beta: [0.7, 1.5, 0.4, 0.8, 0.5, 1]

Constraints:

  1. the first two must be long, the second two must be short, the 5th and 6th stock can be long and short.

  2. gross exposure cannot exceed 2

  3. leveraged long exposure cannot exceed 1.5

  4. beta adjusted net long or short exposure cannot exceed 0.5

  5. Objective: portfolio as close to equal weight as possible.

Code

betas = [0.7, 1.5, 0.4, 0.8, 0.5, 1]
weight_longs = cvx.Variable(2)
weight_shorts = cvx.Variable(2)
weight_longorshort = cvx.Variable(2)
weights = cvx.hstack([weight_longs, weight_shorts, weight_longorshort])

# Constraints:
bounds = [w_longs>=0.0, w_shorts<=-0.0]
gross_exp = [cvx.sum(cvx.abs(weights)) <=2]
lev_long = [cvx.sum(w_longs) + cvx.sum(cvx.pos(w_longorshort)) <= 1.5]
beta_net_exp = [cvx.abs(cvx.sum(np.array(betas) * weights)) <= 0.5]

constraints = bounds + gross_exp + lev_long + beta_net_exp

# Minimize the variance of absolute value of weights to achieve close to equal weight
obj_func = cvx.sum_squares(cvx.abs(weights) - cvs.abs(weights/6))

cvx.Problem(obj_func, constraints)
$\endgroup$
  • $\begingroup$ is cvs.abs(weights) a vector? so you are subtracting a vector from a scalar and then doing sum_of_squares? Does cvx have broadcasting capabilities - if it doesn't that wont work. And also note that you are missing a closing bracket.. $\endgroup$ – Attack68 Mar 18 at 9:11
  • $\begingroup$ Thanks. I added that closing bracket back in the code above. (That bracket is in my code so it wasn't the reason to throw error). I believe cvx can do broadcasting (I tried some other code to broadcast and it works). $\endgroup$ – Jamulive Mar 18 at 17:39
2
$\begingroup$

Without knowing the exact data behind your code, it is hard to say exactly where the error may be. However, DCP errors seem to be thrown when the underlying equation is not convex - and therefore unable to minimize.

Here is a great resource for troubleshooting. It walks through an example of discovering whether a specific problem is convex and/or where it breaks DCP rules.

There is also a function which allows for the testing of each component of the problem:

You can test whether a problem, objective, constraint, or expression satisfies the DCP rules by calling object.is_dcp(). If the function returns False, there is a DCP error in that object.

$\endgroup$
  • $\begingroup$ Thank you so much Daniel. That's a really really helpful resource to troubleshoot. I have also updated the question with specific data and constraints. The objective function I wrote originally is not convex. I am struggling to know how to write a convex function that can push the portfolio weights to as equal as possible.... $\endgroup$ – Jamulive Mar 18 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.