$$
\begin{align}
\text{minimize}& w^\T \Sigma w \\
\text{s.t.}& w_i \geq 0 \\
& \sum w_i = 1 \\
& \sum \mu_i w_i = \mu^*
\end{align}
$$
This is a quadratic programming (QP) problem which can easily be solved in Python using the cvxopt library.
def markowitz(mu, sigma, mu_p): def iif(cond, iftrue=1.0, iffalse=0.0): if cond: return iftrue else: return iffalse from cvxopt import matrix, solvers #solvers.options['show_progress'] = False d = len(sigma) # P and q determine the objective function to minimize # which in cvxopt is defined as $.5 x^T P x + q^T x$ P = matrix(sigma) q = matrix([0.0 for i in range(d)]) # G and h determine the inequality constraints in the # form $G x \leq h$. We write $w_i \geq 0$ as $-1 \times x_i \leq 0$ # and also add a (superfluous) $x_i \leq 1$ constraint G = matrix([ [ (-1.0)**(1+j%2) * iif(i == j/2) for i in range(d) ] for j in range(2*d) ]).trans() h = matrix([ iif(j % 2) for j in range(2*d) ]) # A and b determine the equality constraints defined # as A x = b A = matrix([ [ 1.0 for i in range(d) ], mu ]).trans() b = matrix([ 1.0, float(mu_p) ]) sol = solvers.qp(P, q, G, h, A, b) if sol['status'] != 'optimal': raise Exception("Could not solve problem.") w = list(sol['x']) f = 2.0*sol['primal objective'] return {'w': w, 'f': f, 'args': (P, q, G, h, A, b), 'result': sol }Using my ExcelPython library to call the function from a spreadsheet, I tried calculating the portfolio weights and efficient frontier with parameters
$$
\begin{align}
\mu &= \paren{ \begin{matrix} 4\% \\ 5\% \\ 6\% \end{matrix} } &
\Sigma &= \paren{ \begin{matrix}
20\% & -9\% & 12\% \\
-9\% & 15\% & -11\% \\
12\% & -11\% & 30\%
\end{matrix} }
\end{align}
$$
with $\mu^*$ varying from 4% to 6%. Here's the result
No comments:
Post a Comment