Markowitz使用scipy优化来表示python中的方差优化

时间:2017-11-12 21:57:25

标签: python optimization

我正在努力寻找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中有任何优化经验,尤其是在均值方差优化方面,我真的很感激帮助。

1 个答案:

答案 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)