我正在努力寻找10只股票组合的有效前沿。我首先加载数据(数据),其中包括104个期间10个股票的每周回报。然后我使用此代码随机化权重以绘制任意投资组合:
def random_weights(n):
a = np.random.rand(n)
return a/a.sum()
def initial_portfolio(data):
cov = data.cov()
expected_return = np.matrix(data.mean())
weights = np.matrix(random_weights(expected_return.shape[1]))
mu = weights.dot(expected_return.T)
sigma = np.sqrt(weights.dot(cov.dot(weights.T)))
var = weights.dot(cov.dot(weights.T))
return mu[0,0], sigma[0,0], var[0,0]#, cov, expected_return, weights
def initial_portfolio_other(data):
cov = np.cov(data)
expected_return = np.matrix(data.mean())
weights = np.matrix(random_weights(expected_return.shape[1]))
mu = weights.dot(expected_return.T)
sigma = np.sqrt(weights * cov.dot(weights.T))
var = weights * cov.dot(weights.T)
return cov, expected_return, weights
n_portfolios = 1000
means, stds, var = np.column_stack([
initial_portfolio(data)
for _ in range(n_portfolios)
])
plt.xlabel('Standard deviation')
plt.ylabel('Expected return')
plt.scatter(stds, means)
plt.axis([0.02, 0.035, 0.002,0.009])
plt.figure(figsize = (8,6))
plt.show()
到目前为止,代码工作正常,接下来我希望通过最小化1000周回报的投资组合差异来找到有效的前沿。这是我到目前为止的代码
def calc_var(w, c):
return np.dot(np.dot(w, c),w)
def optimal_portfolio(returns):
n = len(returns.mean())
returns = np.matrix(returns)
avg_returns = np.matrix(returns.mean())
#min_mu = min(returns.mean())
#max_mu = max(returns.mean())
mus = np.random.uniform(0.001,0.03,1000)
S = np.cov(returns, rowvar = False)
pbar = np.matrix(returns.mean())
var = lambda w: w.dot(S.dot(w.T))
frontier_mean, frontier_var, frontier_weights = [], [], []
for r in mus:
w = np.ones([n]) / n
w_bound = [(0, 1) for i in range(n)]
w_constraint = ({'type': 'eq', 'fun': lambda w: sum(w) - 1.})
optimal_w = scipy.optimize.minimize(var, w, method = 'SLSQP', constraints = w_constraint, bounds = w_bound)
frontier_mean.append(r)
frontier_var.append(calc_var(w, S))
frontier_weights.append(optimal_w.x)
return frontier_mean, frontier_var, frontier_weights
result = optimal_portfolio(data)
输出是1000个方差的列表,这些方差都是相同的,并且当然1000个权重集都是相同的。我知道缺少一些东西,但我无法弄清楚它是什么。我一直看到其他人使用的最小化函数中的args参数,但老实说我不知道如何或通过它传递什么。如果有人在python中有任何优化经验,尤其是在均值方差优化方面,我真的很感激帮助。
答案 0 :(得分:0)
限制太少了。优化还应包括将投资组合收益均衡为r的约束;像这样的东西:
w_constraint2 = ({'type': 'eq', 'fun': lambda w: np.dot(avg_returns,np.matrix(w).T) - r})
但是,为此,在将返回转换为numpy矩阵之前,必须编写语句avg_returns = np.matrix(returns.mean())
。否则,average_returns is a 1 x 1 matrix (instead of 1 x num_stocks)