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