我已经尝试了3天了解如何在python中使用cvxopt模块来计算有效边界。我在https://github.com/markharley/Markowitz/blob/master/markowitz.py
找到的代码段可能是说明我的问题的最佳方式,我已在此帖的底部全部包含。
使用维基百科页面上的现代Portoflio理论公式:
https://en.wikipedia.org/wiki/Modern_portfolio_theory#Efficient_frontier_with_no_risk-free_asset
我理解为什么第一次使用solvers.qp使用:
solvers.qp(S, -q*pbar, G, h, A, b)['x']
其中q是风险容忍因子。 然后代码继续使用polyfit计算最佳夏普比率的点,我也理解,但我迷失的地方是为什么代码现在是:
# Calculate the optimal portfolio
wt = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
其中x1是最佳夏普比率点的回报。我迷失了为什么突然间我们可以将S(协方差矩阵)乘以x1并且在-pbar项中除去q。
有人可以对此有所了解吗?如果我没有正确解释这一点,请道歉,任何澄清请求都可能有助于我使问题更清楚。
谢谢!
def optimal_portfolio(returns):
n = len(returns)
returns = np.asmatrix(returns)
N = 100
qs = [10**(-5.0 * t/N + 1.0) for t in range(N)]
# Convert to cvxopt matrices
S = opt.matrix(np.cov(returns))
# np.mean computes vector of means along
# as mean of each row
pbar = opt.matrix(np.mean(returns, axis=1))
# Create constraint matrices
# -- documentation at http://cvxopt.org/userguide/coneprog.html#quadratic-programming
G = -opt.matrix(np.eye(n)) # negative nxn id
h = opt.matrix(0.0, (n, 1)) # n x 1 zero vector
A = opt.matrix(1.0, (1, n)) # 1 x n 1-vector
b = opt.matrix(1.0) # [1.0]
## Calculate efficient frontier weights using quadratic programming
## https://en.wikipedia.org/wiki/Quadratic_programming
# Minimizes (1/2) w^T * S * w - q pbar^T * w for weights w
# subject to the constrains:
# G * w <= h (component-wise) -- positive weights
# and A*w = b -- Sum of weights == 1
# where S is the covariance matrix,
# pbar are the mean returns,
# q is a measure of risk tolerance
portfolios = [solvers.qp(S, -q*pbar, G, h, A, b)['x'] for q in qs]
## Could replace above with Lagrange multiplier (or convex hull)
# Calculate risks and mean returns for frontier
returns = [blas.dot(pbar, x) for x in portfolios]
risks = [np.sqrt(blas.dot(x, S * x)) for x in portfolios]
# Calculate quadratic for the frontier curve
m1 = np.polyfit(returns, risks, 2)
x1 = np.sqrt(m1[2] / m1[0])
# Calculate the optimal portfolio
wt = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
return np.asarray(wt), returns, risks