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
    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$ 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

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .