· 6 years ago · Sep 09, 2019, 11:20 PM
1# import needed modules
2import quandl
3import pandas as pd
4import numpy as np
5import matplotlib.pyplot as plt
6
7# get adjusted closing prices of 5 selected companies with Quandl
8quandl.ApiConfig.api_key = 'INSERT YOUR API KEY HERE'
9selected = ['CNP', 'F', 'WMT', 'GE', 'TSLA']
10data = 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
16clean = data.set_index('date')
17table = clean.pivot(columns='ticker')
18
19# calculate daily and annual returns of the stocks
20returns_daily = table.pct_change()
21returns_annual = returns_daily.mean() * 250
22
23# get daily and covariance of returns of the stock
24cov_daily = returns_daily.cov()
25cov_annual = cov_daily * 250
26
27# empty lists to store returns, volatility and weights of imiginary portfolios
28port_returns = []
29port_volatility = []
30sharpe_ratio = []
31stock_weights = []
32
33# set the number of combinations for imaginary portfolios
34num_assets = len(selected)
35num_portfolios = 50000
36
37#set random seed for reproduction's sake
38np.random.seed(101)
39
40# populate the empty lists with each portfolios returns,risk and weights
41for 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
53portfolio = {'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
58for 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
62df = pd.DataFrame(portfolio)
63
64# get better labels for desired arrangement of columns
65column_order = ['Returns', 'Volatility', 'Sharpe Ratio'] + [stock+' Weight' for stock in selected]
66
67# reorder dataframe columns
68df = df[column_order]
69
70# plot frontier, max sharpe & min Volatility values with a scatterplot
71plt.style.use('seaborn-dark')
72df.plot.scatter(x='Volatility', y='Returns', c='Sharpe Ratio',
73 cmap='RdYlGn', edgecolors='black', figsize=(10, 8), grid=True)
74plt.xlabel('Volatility (Std. Deviation)')
75plt.ylabel('Expected Returns')
76plt.title('Efficient Frontier')
77plt.show()