So I fixed some problems with my capstone and it works a lot better now. I have a small issue where the line that is supposed to plot the optimal variances doesn’t plot when I pull monthly stock data. Was hoping someone could help shed some light on my problem so I can get this working even better! Thanks!
ps: I’ve commented out the line that causes the problem. To see what I’m dealing with just uncomment the line pulling monthly stock data and comment out the line pulling daily stock data.
import pandas_datareader.data as web
import datetime
from datetime import date
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import minimize
start = datetime.datetime(2019, 6, 1)
end = date.today()
symbols = ['AAPL', 'GOOGL', 'NIO']
daily_stock_data = web.DataReader(symbols, 'yahoo', start, end)
# ** The line below leads to the issue.
# Once the line below is uncommented the optimal volatility line stops showing up "(plotted by plt.plot(volatility_opt, returns, '--')")
#daily_stock_data = web.get_data_yahoo(symbols,start,end,interval='m')
print(daily_stock_data.head(-5).round(2))
daily_returns = daily_stock_data['Close']/daily_stock_data['Close'].shift(1)
print(daily_returns.round(2))
log_returns = np.log(daily_returns)
print(log_returns)
num_portfolios = 10000
weight = np.zeros((num_portfolios, len(symbols)))
expectedreturn = np.zeros(num_portfolios)
expectedvolatility = np.zeros(num_portfolios)
sharperatio = np.zeros(num_portfolios)
mean_log_return = log_returns.mean()
Sigma = log_returns.cov()
for k in range(num_portfolios):
# Generate random weight vector
w = np.array(np.random.random(len(symbols)))
w = w / np.sum(w)
weight[k,:] = w
# Expected log return
expectedreturn[k] = np.sum(mean_log_return * w)
# Expected volatility
expectedvolatility[k] = np.sqrt(np.dot(w.T, np.dot(Sigma, w)))
# Sharpe Ratio
sharperatio[k] = expectedreturn[k]/expectedvolatility[k]
maxIndex = sharperatio.argmax()
print(mean_log_return.round(5))
def negativeSR(w):
w = np.array(w)
R = np.sum(mean_log_return*w)
V = np.sqrt(np.dot(w.T, np.dot(Sigma, w)))
SR = R/V
return -1*SR
def checkSumToOne(w):
return np.sum(w)-1
#w0 = [0.20,0.20,0.20,0.20,0.20]
w0 = [1/len(symbols)] * len(symbols)
#bounds = ((0,1),(0,1),(0,1),(0,1),(0,1))
bounds = ((0,1),) * len(symbols)
constraints = ({'type':'eq', 'fun':checkSumToOne})
w_opt = minimize(negativeSR,w0,method='SLSQP',bounds=bounds,constraints=constraints)
w_opt
returns = np.linspace(0,0.01,50)
volatility_opt = []
def minimizeMyVolatility(w):
w = np.array(w)
V = np.sqrt(np.dot(w.T, np.dot(Sigma, w)))
return V
def getReturn(w):
w = np.array(w)
R = np.sum(mean_log_return*w)
return R
for R in returns:
# Find best volatilities
constraints = ({'type':'eq', 'fun':checkSumToOne}, {'type':'eq', 'fun': lambda w: getReturn(w) - R})
opt = minimize(minimizeMyVolatility,w0,method='SLSQP',bounds=bounds,constraints=constraints)
# Save my optimal volatility
volatility_opt.append(opt['fun'])
plt.figure(figsize=(16, 16))
plt.scatter(expectedvolatility, expectedreturn, c=sharperatio) # 'c=sharperatio' passes in the color map ratios indexed by 'sharperatio'
plt.xlabel('Expected Volatility')
plt.ylabel('Expected Log Returns')
plt.colorbar(label='Sharpe Ratio')
plt.scatter(expectedvolatility[maxIndex], expectedreturn[maxIndex], c='red')
plt.plot(volatility_opt, returns, '--')
plt.show()