Last active
June 5, 2021 14:44
-
-
Save PyDataBlog/851d0d146d15b3231f090ba332a159dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import needed modules | |
import quandl | |
import pandas as pd | |
import numpy as np | |
import matplotlib.pyplot as plt | |
# get adjusted closing prices of 5 selected companies with Quandl | |
quandl.ApiConfig.api_key = 'INSERT YOUR API KEY HERE' | |
selected = ['CNP', 'F', 'WMT', 'GE', 'TSLA'] | |
data = quandl.get_table('WIKI/PRICES', ticker = selected, | |
qopts = { 'columns': ['date', 'ticker', 'adj_close'] }, | |
date = { 'gte': '2014-1-1', 'lte': '2016-12-31' }, paginate=True) | |
# reorganise data pulled by setting date as index with | |
# columns of tickers and their corresponding adjusted prices | |
clean = data.set_index('date') | |
table = clean.pivot(columns='ticker') | |
# calculate daily and annual returns of the stocks | |
returns_daily = table.pct_change() | |
returns_annual = returns_daily.mean() * 250 | |
# get daily and covariance of returns of the stock | |
cov_daily = returns_daily.cov() | |
cov_annual = cov_daily * 250 | |
# empty lists to store returns, volatility and weights of imiginary portfolios | |
port_returns = [] | |
port_volatility = [] | |
sharpe_ratio = [] | |
stock_weights = [] | |
# set the number of combinations for imaginary portfolios | |
num_assets = len(selected) | |
num_portfolios = 50000 | |
#set random seed for reproduction's sake | |
np.random.seed(101) | |
# populate the empty lists with each portfolios returns,risk and weights | |
for single_portfolio in range(num_portfolios): | |
weights = np.random.random(num_assets) | |
weights /= np.sum(weights) | |
returns = np.dot(weights, returns_annual) | |
volatility = np.sqrt(np.dot(weights.T, np.dot(cov_annual, weights))) | |
sharpe = returns / volatility | |
sharpe_ratio.append(sharpe) | |
port_returns.append(returns) | |
port_volatility.append(volatility) | |
stock_weights.append(weights) | |
# a dictionary for Returns and Risk values of each portfolio | |
portfolio = {'Returns': port_returns, | |
'Volatility': port_volatility, | |
'Sharpe Ratio': sharpe_ratio} | |
# extend original dictionary to accomodate each ticker and weight in the portfolio | |
for counter,symbol in enumerate(selected): | |
portfolio[symbol+' Weight'] = [Weight[counter] for Weight in stock_weights] | |
# make a nice dataframe of the extended dictionary | |
df = pd.DataFrame(portfolio) | |
# get better labels for desired arrangement of columns | |
column_order = ['Returns', 'Volatility', 'Sharpe Ratio'] + [stock+' Weight' for stock in selected] | |
# reorder dataframe columns | |
df = df[column_order] | |
# plot frontier, max sharpe & min Volatility values with a scatterplot | |
plt.style.use('seaborn-dark') | |
df.plot.scatter(x='Volatility', y='Returns', c='Sharpe Ratio', | |
cmap='RdYlGn', edgecolors='black', figsize=(10, 8), grid=True) | |
plt.xlabel('Volatility (Std. Deviation)') | |
plt.ylabel('Expected Returns') | |
plt.title('Efficient Frontier') | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
what are returns from snippets below % or number?
returns = np.dot(weights, returns_annual) and returns = np.dot(weights, returns_annual)