Here is my capstone comparing a few stocks. This should work in realtime to generate the efficient frontier. Had to improvise a few bits since some of the codeacademy tools weren’t available.
Feedback appreciated!
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from yahooquery import Ticker
stocks = ['JPM', 'HD', 'MSFT', 'CVX', 'RNG', 'JNJ']
start_date = '2010-01-01'
end_date = '2020-01-01'
# this selects the stocks to compare and the dates to use
tickers = Ticker(stocks)
df = tickers.history(start=start_date, end=end_date)
pivoted = df.reset_index().pivot(index = 'date', columns = 'symbol', values = 'close')
cov_matrix = pivoted.pct_change().apply(lambda x: np.log(1 + x)).cov()
#for reference: this is the covariance matrix between the selected stocks
e_r = pivoted.resample('Y').last().pct_change().mean()
#here is where we annualize the expected returns
s_d = pivoted.pct_change().apply(lambda x: np.log(1 + x)).std().apply(lambda x: x*np.sqrt(250))
#produces the standard deviations
assets = pd.concat([e_r, s_d], axis = 1)
assets.columns = ['Returns', 'Volatility']
#this produces a table comparing the average returns and their volatility of each stock
p_ret = []
p_vol = []
p_weight = []
num_assets = len(pivoted.columns)
num_port = 1000 # number of portfolio combinations to test
for p in range(num_port):
weights = np.random.random(num_assets)
weights = weights / np.sum(weights)
p_weight.append(weights)
returns = np.dot(weights, e_r)
p_ret.append(returns)
var= cov_matrix.mul(weights, axis = 0).mul(weights, axis = 1).sum().sum()
sd= np.sqrt(var)
ann_sd = sd * np.sqrt(250)
p_vol.append(ann_sd)
#this is how we test for the different combos
data = {'Returns': p_ret, 'Volatility': p_vol}
for counter, symbol in enumerate(pivoted.columns.tolist()):
data[symbol +' weight'] = [w[counter] for w in p_weight]
portfolios = pd.DataFrame(data).sort_values('Returns', ascending = False)
#we can print portfolios to see the list of combination weights and their returns/volatility
portfolios.plot.scatter(x = 'Volatility', y = 'Returns', grid = False)
plt.savefig('plot.png')
print(portfolios.head())