Trying to optimize a portfolio weight allocation here which maximize my return function by limit risk using cvxopt module. My codes are as below:
from cvxopt import matrix, solvers, spmatrix, sparse
from cvxopt.blas import dot
import numpy
import pandas as pd
import numpy as np
from datetime import datetime
solvers.options['show_progress'] = False
# solves the QP, where x is the allocation of the portfolio:
# minimize x'Px + q'x
# subject to Gx <= h
# Ax == b
#
# Input: n - # of assets
# avg_ret - nx1 matrix of average returns
# covs - nxn matrix of return covariance
# r_min - the minimum expected return that you'd
# like to achieve
# Output: sol - cvxopt solution object
dates = pd.date_range('2000-01-01', periods=6)
industry = ['industry', 'industry', 'utility', 'utility', 'consumer']
symbols = ['A', 'B', 'C', 'D', 'E']
zipped = list(zip(industry, symbols))
index = pd.MultiIndex.from_tuples(zipped)
noa = len(symbols)
data = np.array([[10, 11, 12, 13, 14, 10],
[10, 11, 10, 13, 14, 9],
[10, 10, 12, 13, 9, 11],
[10, 11, 12, 13, 14, 8],
[10, 9, 12, 13, 14, 9]])
market_to_market_price = pd.DataFrame(data.T, index=dates, columns=index)
rets = market_to_market_price / market_to_market_price.shift(1) - 1.0
rets = rets.dropna(axis=0, how='all')
# covariance of asset returns
P = matrix(rets.cov().values)
n = len(symbols)
q = matrix(np.zeros((n, 1)), tc='d')
G = matrix(-np.eye(n), tc='d')
h = matrix(-np.zeros((n, 1)), tc='d')
A = matrix(1.0, (1, n))
b = matrix(1.0)
sol = solvers.qp(P, q, G, h, A, b)
Should I use Monte Carlo simulation to get the target risk while maximize return? what's the best method for solving this problem? Thank you.
It is not as straightforward as one may think. The typical portfolio optimization problem is to minimize risk subject to a target return which is a linearly-constrained problem with a quadratic objective; ie, a quadratic program (QP).
minimize x^T.P.x
subject to sum(x_i) = 1
avg_ret^T.x >= r_min
x >= 0 (long-only)
What you want here, to maximize return subject to a target risk, is a quadraticaly constrained quadratic program (QCQP), looking like:
maximize avg_ret^T.x
subject to sum(x_i) = 1
x^T.P.x <= risk_max
x >= 0 (long-only)
With a convex quadratic constraint, optimization happens over a more complicated cone containing a second-order cone factor. If you want to proceed with cvxopt, you have to convert the QCQP to a second-order cone program (SOCP), as cvxopt does not have an explicit solver for QCQPs. SOCP with cvxopt has a different matrix syntax than the typical QP as you can see from the documentation. This blog post has a very nice walk-through on how to do this for this specific problem.