Проблема с инструментом оптимизации портфеля - IndexError - PullRequest
0 голосов
/ 05 июля 2019

Я пытаюсь разработать собственную реализацию Оптимизатора Porfolio, которую я нашел здесь: https://pythonforfinance.net/2017/01/21/investment-portfolio-optimisation-with-python/

import numpy as np
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
#list of stocks in portfolio
stocks = ['AAPL','AMZN','MSFT','YHOO']
#download daily price data for each of the stocks in the portfolio
data = web.DataReader(stocks,data_source='yahoo',start='01/01/2010')['Adj Close']
data.sort_index(inplace=True)
#convert daily stock prices into daily returns
returns = data.pct_change()
#calculate mean daily return and covariance of daily returns
mean_daily_returns = returns.mean()
cov_matrix = returns.cov()
#set number of runs of random portfolio weights
num_portfolios = 25000
#set up array to hold results
#We have increased the size of the array to hold the weight values for each stock
results = np.zeros((4+len(stocks)-1,num_portfolios))
for i in xrange(num_portfolios):
    #select random weights for portfolio holdings
    weights = np.array(np.random.random(4))
    #rebalance weights to sum to 1
    weights /= np.sum(weights)

    #calculate portfolio return and volatility
    portfolio_return = np.sum(mean_daily_returns * weights) * 252
    portfolio_std_dev = np.sqrt(np.dot(weights.T,np.dot(cov_matrix, weights))) * np.sqrt(252)

    #store results in results array
    results[0,i] = portfolio_return
    results[1,i] = portfolio_std_dev
    #store Sharpe Ratio (return / volatility) - risk free rate element excluded for simplicity
    results[2,i] = results[0,i] / results[1,i]
    #iterate through the weight vector and add data to results array
    for j in range(len(weights)):
        results[j+3,i] = weights[j]
#convert results array to Pandas DataFrame
results_frame = pd.DataFrame(results.T,columns=['ret','stdev','sharpe',stocks[0],stocks[1],stocks[2],stocks[3]])
#locate position of portfolio with highest Sharpe Ratio
max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()]
#locate positon of portfolio with minimum standard deviation
min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()]
#create scatter plot coloured by Sharpe Ratio
plt.scatter(results_frame.stdev,results_frame.ret,c=results_frame.sharpe,cmap='RdYlBu')
plt.xlabel('Volatility')
plt.ylabel('Returns')
plt.colorbar()
#plot red star to highlight position of portfolio with highest Sharpe Ratio
plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker=(5,1,0),color='r',s=1000)
#plot green star to highlight position of minimum variance portfolio
plt.scatter(min_vol_port[1],min_vol_port[0],marker=(5,1,0),color='g',s=1000)

При запуске этого кода я сталкиваюсь со следующей IndexError:

Traceback (most recent call last):
  File "C:/PythonTraining/Portfolio_analysis/test.py", line 72, in <module>
    results[j + 3 , i] = weights[j]
IndexError: too many indices for array

Автор этого кода не очень отзывчив, и я не могу самостоятельно устранить неполадки.

1 Ответ

0 голосов
/ 09 июля 2019

Я являюсь автором этого кода, и я ответил вам в течение полутора дней с момента размещения вашего комментария на сайте. Я ответил вам там, к вашему сведению.

Ниже приведена рабочая версия вышеприведенного кода - n.b. "YHOO" не возвращает цены из Yahoo Finance, поэтому вам придется удалить или заменить ее.

Проблема возникла из-за того, что матрица "результатов" настроена на неправильные измерения - я заменил код ошибки с помощью

len(stocks)

для правильной установки размеров для вектора «весов» и матрицы «результатов».

import numpy as np
import pandas as pd
from pandas_datareader import data as d
import matplotlib.pyplot as plt
#list of stocks in portfolio
stocks = ['AAPL','AMZN','MSFT']#,'YHOO']
#download daily price data for each of the stocks in the portfolio
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2018, 12, 31)
data = pd.DataFrame([d.DataReader(ticker, 'yahoo', start, end)['Adj Close'] for ticker in stocks]).T
data.columns = stocks

#convert daily stock prices into daily returns
returns = data.pct_change()
#calculate mean daily return and covariance of daily returns
mean_daily_returns = returns.mean()
cov_matrix = returns.cov()
#set number of runs of random portfolio weights
num_portfolios = 25000
#set up array to hold results
#We have increased the size of the array to hold the weight values for each stock
results = np.zeros((3+len(stocks),num_portfolios))
for i in range(num_portfolios):
    #select random weights for portfolio holdings
    weights = np.array(np.random.random(len(stocks)))
    #rebalance weights to sum to 1
    weights /= np.sum(weights)

    #calculate portfolio return and volatility
    portfolio_return = np.sum(mean_daily_returns * weights) * 252
    portfolio_std_dev = np.sqrt(np.dot(weights.T,np.dot(cov_matrix, weights))) * np.sqrt(252)

    #store results in results array
    results[0,i] = portfolio_return
    results[1,i] = portfolio_std_dev
    #store Sharpe Ratio (return / volatility) - risk free rate element excluded for simplicity
    results[2,i] = results[0,i] / results[1,i]
    #iterate through the weight vector and add data to results array
    for j in range(len(weights)):
        results[j+3,i] = weights[j]
#convert results array to Pandas DataFrame
results_frame = pd.DataFrame(results.T,columns=['ret','stdev','sharpe'] + [ticker for ticker in stocks])
#locate position of portfolio with highest Sharpe Ratio
max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()]
#locate positon of portfolio with minimum standard deviation
min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()]
#create scatter plot coloured by Sharpe Ratio
plt.scatter(results_frame.stdev,results_frame.ret,c=results_frame.sharpe,cmap='RdYlBu')
plt.xlabel('Volatility')
plt.ylabel('Returns')
plt.colorbar()
#plot red star to highlight position of portfolio with highest Sharpe Ratio
plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker=(5,1,0),color='r',s=1000)
#plot green star to highlight position of minimum variance portfolio
plt.scatter(min_vol_port[1],min_vol_port[0],marker=(5,1,0),color='g',s=1000)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...