1
$\begingroup$

I am trying to implement a simple minimum variance portfolio optimisation with a few simple constraints:

  • long-only portfolio
  • fully invested (sums to one)
  • market-neutrality, i.e sum(betas) = 0.

I am not very experienced with cvxpy but I quite like it and want to implement my stuff with it going forward. Below is an example( from the cvxpy website), which uses

$$\min_x\;\; \frac{1}{2}x^T\Sigma x$$ Under the constraints $$x^T \mathbb{1}=1$$ $$\mu^Tx \geq \tau$$

I now want to add $B^Tx=0$, which will ensure that the portfolios beta is zero.

Here is the example:

from cvxpy import *
import numpy as np

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

betas = [np.random.uniform(-1,1) for _ in range(10)]

w = Variable(n)

risk = quad_form(w, Sigma)
constraints = [sum_entries(w) == 1, w >= 0]
prob = Problem(Minimize(risk), constraints)

for i in range(100):
    prob.solve()

print('Weights :', w.value)

How can I define the additional variable for beta and how do you alter your constraints list.

From the manual I assume we need something in the form a quad_form(), but does this have to be defined similarly to the risk variable in the example or inside the constraints object? how do you link it to the betas data vector?

I would have done something like

sum(quad_form(w, betas)) == 0 

inside the constraints object which unfortunately doesn't work.

$\endgroup$
2
  • $\begingroup$ I would compute the Betas outside of CVXOPT and use them as the coefficents in a linear equality constraint with 0 on the right hand side... Like $1.01*x_1+0.95*x_2+\cdots+1.20*x_n=0$ $\endgroup$
    – Alex C
    Commented Nov 5, 2016 at 1:20
  • $\begingroup$ I get the betas from a database I just use the calculated ones here as a working example $\endgroup$ Commented Nov 5, 2016 at 1:29

2 Answers 2

1
$\begingroup$

The constraint you suggest is wrong as it implies $x^T B x = 0$ which is not what you want.

The right way to express $B^T x = 0$ is w.T * beta == 0 and you should including this in the constraints list:

constraints = [sum_entries(w) == 1, w >= 0, w.T * beta == 0]

Also the following lines look wrong:

for i in range(100):
    prob.solve()

It seems you're solving a hundred times your problem. One call should be enough.

$\endgroup$
1
$\begingroup$

the constraint can simply be implemented by creating the following constraint

w.T*beta == 0
$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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