In [1]:
# Stefano Ciccarelli
import pandas as pd
import yfinance as yf
from yahoofinancials import YahooFinancials
import datetime
import numpy as np
In [2]:
# Taking from Wikipedia the list of the Companies inside the SP500 Index
SP_500_Data = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')[0]

SP_500_Data.head()
Out[2]:
Symbol Security SEC filings GICS Sector GICS Sub Industry Headquarters Location Date first added CIK Founded
0 MMM 3M Company reports Industrials Industrial Conglomerates St. Paul, Minnesota 1976-08-09 66740 1902
1 ABT Abbott Laboratories reports Health Care Health Care Equipment North Chicago, Illinois 1964-03-31 1800 1888
2 ABBV AbbVie Inc. reports Health Care Pharmaceuticals North Chicago, Illinois 2012-12-31 1551152 2013 (1888)
3 ABMD ABIOMED Inc reports Health Care Health Care Equipment Danvers, Massachusetts 2018-05-31 815094 1981
4 ACN Accenture plc reports Information Technology IT Consulting & Other Services Dublin, Ireland 2011-07-06 1467373 1989
In [3]:
#Initializing the dataframe 
SP500_adj_Close = pd.DataFrame()



# For each stock ticker we download the stock close price daily data starting from 1st January 2017 until today 
for symbol in  SP_500_Data["Symbol"]:
    
    SP500_adj_Close[symbol] = yf.download(symbol, 
                      start='2017-01-01', 
                      end=datetime.datetime.today(), 
                      progress=False)["Adj Close"]
1 Failed download:
- BRK.B: No data found, symbol may be delisted

1 Failed download:
- BF.B: No data found for this date range, symbol may be delisted
In [4]:
#Initializing the dataframe 
SP500_Returns = pd.DataFrame()

# Generating the Daily Returns
SP500_Returns = np.log(SP500_adj_Close / SP500_adj_Close.shift(1)).iloc[1:]
        
    
SP500_Returns.head()
Out[4]:
MMM ABT ABBV ABMD ACN ATVI ADBE AMD AAP AES ... WYNN XEL XRX XLNX XYL YUM ZBRA ZBH ZION ZTS
Date
2017-01-04 0.001515 0.007907 0.014002 0.029638 0.002401 0.019460 0.006358 0.000000 0.008173 -0.008613 ... 0.031734 0.004422 0.037041 -0.007306 0.014794 0.003632 0.009003 0.009152 0.014256 0.009656
2017-01-05 -0.003427 0.008601 0.007556 -0.008068 -0.015104 0.015406 0.016854 -0.016763 -0.000698 -0.013061 ... 0.012767 0.000000 -0.004205 -0.012182 -0.009171 0.003305 -0.026547 0.006404 -0.016343 -0.003332
2017-01-06 0.002922 0.026841 0.000314 0.005299 0.011328 -0.000791 0.022315 0.007092 -0.013177 0.035303 ... 0.010768 0.002937 -0.015570 0.019149 -0.007034 0.012025 0.014176 0.000095 0.006477 0.003147
2017-01-09 -0.005401 -0.000981 0.006562 0.014536 -0.011241 -0.005555 0.002490 0.014906 -0.000589 -0.024841 ... 0.003456 -0.015267 -0.005723 0.000169 -0.004245 0.002790 0.000116 0.019249 -0.010896 -0.002776
2017-01-10 -0.003900 0.013410 -0.002183 -0.042474 0.000522 0.017876 -0.002859 -0.004361 0.002298 -0.017498 ... 0.022178 -0.000248 0.008572 -0.009014 -0.004669 0.005865 -0.006184 0.060471 0.015267 -0.000371

5 rows × 505 columns

In [5]:
df = pd.DataFrame()

df["Avg_Returns"] = SP500_Returns.mean()
df["Volatilities"] = SP500_Returns.std()
df["Sharpe_Ratios"] = df["Avg_Returns"]/df["Volatilities"]*(252**0.5)
df["Sharpe_Ratios"].nlargest(10)
Out[5]:
CARR    2.559158
OTIS    1.366332
AMZN    1.338054
AAPL    1.295516
NOW     1.270008
ADBE    1.258111
MSCI    1.247168
PYPL    1.228539
MSFT    1.217933
CDNS    1.211523
Name: Sharpe_Ratios, dtype: float64
In [7]:
df.plot(x='Volatilities', y='Avg_Returns', style='o', title='Average Daily Return vs Daily Volatility', legend = False)
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x1beb14e6788>