import numpy as np import pandas as pd import pandas_datareader.data as web import matplotlib.pyplot as plt #list of stocks in profilo stocks=['BTC-USD','SPY'] #download daily price data for each of the stocks in the portfolio data = web.DataReader(stocks,data_source='yahoo',start='07/16/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 range(num_portfolios): #select random weights for portfolio holdings weights = np.array(np.random.random(2)) #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]]) #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)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) in 8 stocks=['BTC-USD','SPY'] 9 #download daily price data for each of the stocks in the portfolio ---> 10 data = web.DataReader(stocks,data_source='yahoo',start='07/16/2010')['Adj Close'] 11 12 data.sort_index(inplace=True) ~\Anaconda3\lib\site-packages\pandas_datareader\data.py in DataReader(name, data_source, start, end, retry_count, pause, session, access_key) 308 adjust_price=False, chunksize=25, 309 retry_count=retry_count, pause=pause, --> 310 session=session).read() 311 312 elif data_source == "google": ~\Anaconda3\lib\site-packages\pandas_datareader\base.py in read(self) 213 df = self._dl_mult_symbols(self.symbols.index) 214 else: --> 215 df = self._dl_mult_symbols(self.symbols) 216 return df 217 ~\Anaconda3\lib\site-packages\pandas_datareader\base.py in _dl_mult_symbols(self, symbols) 240 for sym in failed: 241 stocks[sym] = df_na --> 242 result = concat(stocks).unstack(level=0) 243 result.columns.names = ['Attributes', 'Symbols'] 244 return result ~\Anaconda3\lib\site-packages\pandas\core\frame.py in unstack(self, level, fill_value) 5532 """ 5533 from pandas.core.reshape.reshape import unstack -> 5534 return unstack(self, level, fill_value) 5535 5536 _shared_docs['melt'] = (""" ~\Anaconda3\lib\site-packages\pandas\core\reshape\reshape.py in unstack(obj, level, fill_value) 493 if isinstance(obj, DataFrame): 494 if isinstance(obj.index, MultiIndex): --> 495 return _unstack_frame(obj, level, fill_value=fill_value) 496 else: 497 return obj.T.stack(dropna=False) ~\Anaconda3\lib\site-packages\pandas\core\reshape\reshape.py in _unstack_frame(obj, level, fill_value) 513 value_columns=obj.columns, 514 fill_value=fill_value, --> 515 constructor=obj._constructor) 516 return unstacker.get_result() 517 ~\Anaconda3\lib\site-packages\pandas\core\reshape\reshape.py in __init__(self, values, index, level, value_columns, fill_value, constructor) 135 136 self._make_sorted_values_labels() --> 137 self._make_selectors() 138 139 def _make_sorted_values_labels(self): ~\Anaconda3\lib\site-packages\pandas\core\reshape\reshape.py in _make_selectors(self) 173 174 if mask.sum() len(self.index): --> 175 raise ValueError('Index contains duplicate entries, ' 176 'cannot reshape') 177 ValueError: Index contains duplicate entries, cannot reshape