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