2017-11-12 24 views
0

私は10株のポートフォリオの効率的なフロンティアを見つけようとしています。私は最初に、104の期間にわたって10株の週間リターンを含むデータ(データ)をロードする。そして、私はこのコードを使用して、任意のポートフォリオをプロットするために重みをランダム:scowy最適化を使用してPythonでのMarkowitz平均分散最適化

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の毎週リターンのポートフォリオの分散を最小化することにより、効率的なフロンティアを見つけたいです。これは、出力がすべて同じとすべて同一であり、重みのセット1000 ofcourseのある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) 

私が持っているコードです。私は何かが不足していることを知っているが、私はそれが何であるか把握できない。私はargs引数を他の人が使っているminimize関数で見ていますが、私は正直なところ、どのように手がかりを持っていないのでしょうか?誰かがPythonでの最適化の経験が特に平均分散の最適化であれば、私は本当に助けに感謝します。

+0

「frontier_var.append(calc_var(w、S))」のように見えるのは、常に同じ計算を実行することです。 'w'は1の配列であり、' S'は 'returns'の共分散行列です。 'mus 'に依存しないので、ループのすべての反復で同じ結果が得られます。 –

答えて

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)

+0

また、optimal_w.xをfrontier_stdに追加する必要があります。すべてのループに最初の重み(w)を追加するだけです。 – Ananya