\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