Skip to content

Commit bc617f8

Browse files
authored
Efficient Frontier with Quandl (Part 2)
1 parent d8c4627 commit bc617f8

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# import needed modules
2+
import quandl
3+
import pandas as pd
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
7+
# get adjusted closing prices of 5 selected companies with Quandl
8+
quandl.ApiConfig.api_key = 'zcfJ6696mcZScjzsyeta'
9+
selected = ['CNP', 'F', 'WMT', 'GE', 'TSLA']
10+
data = quandl.get_table('WIKI/PRICES', ticker = selected,
11+
qopts = { 'columns': ['date', 'ticker', 'adj_close'] },
12+
date = { 'gte': '2014-1-1', 'lte': '2016-12-31' }, paginate=True)
13+
14+
# reorganise data pulled by setting date as index with
15+
# columns of tickers and their corresponding adjusted prices
16+
clean = data.set_index('date')
17+
table = clean.pivot(columns='ticker')
18+
19+
# calculate daily and annual returns of the stocks
20+
returns_daily = table.pct_change()
21+
returns_annual = returns_daily.mean() * 250
22+
23+
# get daily and covariance of returns of the stock
24+
cov_daily = returns_daily.cov()
25+
cov_annual = cov_daily * 250
26+
27+
# empty lists to store returns, volatility and weights of imiginary portfolios
28+
port_returns = []
29+
port_volatility = []
30+
sharpe_ratio = []
31+
stock_weights = []
32+
33+
# set the number of combinations for imaginary portfolios
34+
num_assets = len(selected)
35+
num_portfolios = 50000
36+
37+
#set random seed for reproduction's sake
38+
np.random.seed(101)
39+
40+
# populate the empty lists with each portfolios returns,risk and weights
41+
for single_portfolio in range(num_portfolios):
42+
weights = np.random.random(num_assets)
43+
weights /= np.sum(weights)
44+
returns = np.dot(weights, returns_annual)
45+
volatility = np.sqrt(np.dot(weights.T, np.dot(cov_annual, weights)))
46+
sharpe = returns / volatility
47+
sharpe_ratio.append(sharpe)
48+
port_returns.append(returns)
49+
port_volatility.append(volatility)
50+
stock_weights.append(weights)
51+
52+
# a dictionary for Returns and Risk values of each portfolio
53+
portfolio = {'Returns': port_returns,
54+
'Volatility': port_volatility,
55+
'Sharpe Ratio': sharpe_ratio}
56+
57+
# extend original dictionary to accomodate each ticker and weight in the portfolio
58+
for counter,symbol in enumerate(selected):
59+
portfolio[symbol+' Weight'] = [Weight[counter] for Weight in stock_weights]
60+
61+
# make a nice dataframe of the extended dictionary
62+
df = pd.DataFrame(portfolio)
63+
64+
# get better labels for desired arrangement of columns
65+
column_order = ['Returns', 'Volatility', 'Sharpe Ratio'] + [stock+' Weight' for stock in selected]
66+
67+
# reorder dataframe columns
68+
df = df[column_order]
69+
70+
# plot frontier, max sharpe & min Volatility values with a scatterplot
71+
plt.style.use('seaborn-dark')
72+
df.plot.scatter(x='Volatility', y='Returns', c='Sharpe Ratio',
73+
cmap='RdYlGn', edgecolors='black', figsize=(10, 8), grid=True)
74+
plt.xlabel('Volatility (Std. Deviation)')
75+
plt.ylabel('Expected Returns')
76+
plt.title('Efficient Frontier')
77+
plt.show()

0 commit comments

Comments
 (0)