# Beta Constrained Markowitz Minimum Variance Portfolio - Closed Form Solution

This question is related to recent rule changes in the Quantopian Open.

I am trying to figure out a closed form solution to a beta constrained minimum variance portfolio problem but it doesn't seem particularly tractable. Has anyone else tried this? So far, I have set up the problem

\begin{align} \min_w \quad& w^\prime \Sigma w \\ s.t. \quad& w^\prime\vec 1 = 1 \\ \text{and} \quad & w^\prime \beta = c \end{align}

where

• $w$ is the vector of portfolio weights, our control
• $\Sigma$ is the total covariance matrix
• $\beta$ is the vector of CAPM-type market betas
• $c$ a constant that the portfolio beta should be equal to

Changing constraints to Lagrange multipliers the objective becomes

$$\min_w \quad w^\prime\Sigma w - \lambda_1(w^\prime\vec 1 - 1) - \lambda_2(w^\prime\beta - c)$$

the first order conditions are

\begin{align} 0 &= 2w^\prime\Sigma - \lambda_1\vec 1 - \lambda_2 \beta\\ 1 &= w^\prime\vec 1\\ c &= w^\prime\beta \end{align}

I cannot seem to get the equations to work out nicely, perhaps no closed form solution exists but I wanted to check here and see if anyone could get something reasonable before I go to numerical optimization.

• The constraints can be grouped together to something like $Aw=b$, so that the lambdas are a vector. This set-up is actually pretty common. I typically refer to the derivation in edoc.hu-berlin.de/master/jiao-wei-2003-12-16/PDF/jiao.pdf – John Jun 4 '15 at 18:44
• @John I like this reference but I would suggest pointing interested readers to page 7 (pdf page 15) when making it – user25064 Jun 5 '15 at 13:43

Assuming that $\Sigma$ is invertible, then \begin{align} 2\omega' = \lambda_1\overrightarrow{1}'\Sigma^{-1}+\lambda_2\beta'\Sigma^{-1}. \end{align} We can then solve $\lambda_1$ and $\lambda_2$ from the system of equations \begin{align*} 2 &= \lambda_1\overrightarrow{1}'\Sigma^{-1}\overrightarrow{1}+\lambda_2\beta'\Sigma^{-1}\overrightarrow{1}\\ 2c &= \lambda_1\overrightarrow{1}'\Sigma^{-1}\beta+\lambda_2\beta'\Sigma^{-1}\beta. \end{align*} Consequently, $\omega$ can be obtained from the above equation.

• I was hoping for some cute $w = \ldots$ reduced form type equation but this certainly answers the question. edit - I bet mathematica could help but I don't own it – user25064 Jun 4 '15 at 16:37
• @user25064, I believe this can be done in Excel 2010. – Gordon Jun 4 '15 at 17:24
• I was referring to symbolic manipulation... – user25064 Jun 4 '15 at 17:25

This is an interesting problem. I don't think the problem is set up correctly quite yet. I rewrote it slightly to correspond to how it's generally written as a quadratic program.

The optimization problem you write down fixes betas to be a certain value. That could make sense but instead I wondered if we could simply minimize beta across the portfolio while minimizing correlations. In that case, the optimization problem becomes:

\begin{align} \min_w \quad& w^\prime \Sigma w + w^\prime\lvert\beta\rvert\\ s.t. \quad& w^\prime\vec 1 = 1 \\ \text{and} \quad & w > 0 \end{align}

I don't think a closed-form solution exists to this problem. But it's quite easy (and fast) to solve this with a quadratic optimizer such as provided by cvxopt. Here is some example code:



import numpy as np
import matplotlib.pyplot as plt
import cvxopt as opt
from cvxopt import blas, solvers
import pandas as pd

np.random.seed(123)

# Turn off progress printing
solvers.options['show_progress'] = False

## NUMBER OF ASSETS
n_assets = 4

## NUMBER OF OBSERVATIONS
n_obs = 1000

# Generate returns
return_vec = np.random.randn(n_assets, n_obs)

betas = np.array([.1, .8, .2, .05])

def markowitz_beta(returns, betas):
n = len(returns)
returns = np.asmatrix(returns)

# Convert to cvxopt matrices
# minimize: w * mu*S * w + betas * x
S = opt.matrix(np.cov(returns))

# Minimize betas, can add mean returns here if desired
pbar = opt.matrix(np.abs(betas))

# Create constraint matrices
# Gx < h: Every item is positive
G = opt.matrix(-np.eye(n))   # negative n x n identity matrix
h = opt.matrix(np.zeros(n))
# Ax = b sum of all items = 1
A = opt.matrix(1.0, (1, n))
b = opt.matrix(1.0)

# CALCULATE THE OPTIMAL PORTFOLIO
wt = solvers.qp(S, pbar, G, h, A, b)['x']
return np.asarray(wt).ravel()

weights = markowitz_beta(return_vec, betas)
print weights
print betas.ravel()
print np.dot(weights, betas)

Output:

[  3.50677883e-01   3.34638307e-07   2.50326847e-01   3.98994936e-01]
[ 0.1   0.8   0.2   0.05]
0.105083172131


As you can see, the highest betas receive very low weights.

We also wrote a blog post on this (and the code is a version from there) which you can find here: https://www.quantopian.com/posts/the-efficient-frontier-markowitz-portfolio-optimization-using-cvxopt-repost-cloning-of-nb-now-enabled

Disclaimer: I work at Quantopian.

• You just wrote down a different problem which is totally fine. The problem I was trying to solve has a closed form solution because my constraint is an equality constraint (I happen to use $c=0$) and I allow long/short portfolios. Still interesting and illustrative, thanks – user25064 Aug 5 '15 at 12:51
• Ah, you're probably right in that case. I wonder in which cases you would want to target a specific beta value for your portfolio though. – twiecki Aug 5 '15 at 12:54
• Separately, I posted this NB on our forums: quantopian.com/posts/… – twiecki Aug 5 '15 at 12:54