In this post, I will explain the methods of measuring risk in finance. One of the widely used concepts to measue the risk of an asset is the Sharpe Ratio. I have implemented a code in Python to compute the Sharpe Ratio for some assets.

from pandas_datareader import data  # You will need to run "pip install pandas_datareader"
import holidays   # You will need to run "pip install holidays"
import datetime 
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

Useful resources:

https://readthedocs.org/projects/pandas-datareader/downloads/pdf/latest/

https://www.investopedia.com/terms/c/consumerpriceindex.asp

https://www.investopedia.com/insights/understanding-consumer-confidence-index/

https://fred.stlouisfed.org/series

ONE_DAY = datetime.timedelta(days=1)
HOLIDAYS_US = holidays.US()

def previous_business_day(specific_date):
    previous_day = specific_date 
    while previous_day.weekday() in holidays.WEEKEND or previous_day in HOLIDAYS_US:
        previous_day -= ONE_DAY
    return previous_day

def next_business_day(specific_date):
    next_day = specific_date
    while next_day.weekday() in holidays.WEEKEND or next_day in HOLIDAYS_US:
        next_day += ONE_DAY
    return next_day
def get_historical_data(share, start_date='2019-01-01', end_date='2020-01-01', source='yahoo'):
    try:
        panel_data = data.DataReader(share, source, start_date, end_date)
    except: 
        panel_data = pd.DataFrame()
    return panel_data
def compute_average_annual_return(share, start_date='2019-01-02', end_date='2019-12-31', source='yahoo'):
    panel_data = get_historical_data(share, start_date, end_date, source)
    if panel_data.empty:
        return None, None, None, None, None
    
    adj_close = panel_data['Adj Close']
    
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    
    while start_date.strftime('%Y-%m-%d') not in adj_close.index: 
        start_date = next_business_day(start_date)
    
    while end_date.strftime('%Y-%m-%d') not in adj_close.index: 
        end_date = previous_business_day(end_date)
    
    delta = end_date - start_date
    years = delta.days / 365
    
    start_price = adj_close.loc[start_date.strftime('%Y-%m-%d')]
    end_price = adj_close.loc[end_date.strftime('%Y-%m-%d')]
    
    return_value = (end_price/start_price)**(1/years) - 1
    return round(return_value, 4), start_date, end_date, delta, years
def compute_daily_return_std_per_year(share, start_date='2019-01-02', end_date='2020-01-02', source='yahoo'):
    panel_data = get_historical_data(share, start_date, end_date, source)
    if panel_data.empty:
        return None
    last_day_price = None
    daily_returns = [] 
    for index, row in panel_data.iterrows():
        if last_day_price:
            daily_returns.append(row['Adj Close']/last_day_price - 1)
        last_day_price = row['Adj Close']
    return round(np.std(daily_returns)*np.sqrt(252), 4)
def compute_sharpe(share, start_date='2019-01-02', end_date='2020-01-02', source='yahoo'):
    avg, _, _, _, _ = compute_average_annual_return(share, start_date, end_date, source)
    std = compute_daily_return_std_per_year(share, start_date, end_date, source)
    if not avg or not std:
        return
    return round(avg/std, 4)
SP_500 = pd.read_excel('SP_500.xlsx', index_col=0)
SP_500_symbol_list = SP_500.index.to_list()[:-2]
iTickers = {}
iTickers["SPY"] = "SPDR S&P 500 ETF Trust"
iTickers["VOO"] = "Vanguard S&P 500 ETF"
iTickers["VTI"] = "Vanguard Total Stock Market ETF"
iTickers["BRK-B"] = "Berkshire Hathaway Inc."
iTickers["AAPL"] = "Apple Inc."
iTickers["BAC"] = "Bank of America"
iTickers["MSFT"] = "Microsoft"
iTickers["IVV"] = "iShares Core S&P 500 ETF"
iTickers["NFLX"] = "Netflix"
for symb in SP_500_symbol_list:  
    print("---------------\n", symb)
    sharpe_ratio = compute_sharpe(symb)
    print(SP_500.loc[symb]['Name'], sharpe_ratio)
plt.figure(figsize=(16,8))
start_date='2000-01-31' 
for symb in iTickers:
    print(iTickers[symb])
    daa = get_historical_data(symb, start_date=start_date)
    sharpe_ratio = compute_sharpe(symb)
    #print(SP_500.loc[symb]['Name'], sharpe_ratio)
    print(iTickers[symb], sharpe_ratio)
    plt.plot(daa['Adj Close'])
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
plt.legend([iTickers[sym] for sym in iTickers])
plt.savefig('well-known-tickers.png')
SPDR S&P 500 ETF Trust
SPDR S&P 500 ETF Trust 2.5004
Vanguard S&P 500 ETF
Vanguard S&P 500 ETF 2.5269
Vanguard Total Stock Market ETF
Vanguard Total Stock Market ETF 2.4393
Berkshire Hathaway Inc.
Berkshire Hathaway Inc. 0.7833
Apple Inc.
Apple Inc. 3.42
Bank of America
Bank of America 1.9287
Microsoft
Microsoft 2.9596
iShares Core S&P 500 ETF
iShares Core S&P 500 ETF 2.5012
Netflix
Netflix 0.6069

Some SP 500 tickers

plt.figure(figsize=(16,6))
start_date='2010-01-02' 
end_date='2020-01-07' 
for symb in ['BRK-B','SPY']:
    daa = get_historical_data(symb, start_date=start_date, end_date=end_date)
    plt.plot(daa['Adj Close'])
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
plt.legend(['BRK-B','SPY'])
plt.savefig('BRK_vs_SPY.png')

Berkshire Hathaway vs SP 500

def plot_stock_price(stock, start_date='2019-01-02', end_date='2019-12-31', source='yahoo'):
    plt.figure(figsize=(16,6))
    daa = get_historical_data(stock, start_date=start_date, end_date=end_date, source=source)
    sharpe_ratio = compute_sharpe(stock)
    plt.plot(daa['Adj Close'])
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
    plt.legend([stock])
    plt.savefig('{}_{}_{}.png'.format(stock, start_date, end_date))
plot_stock_price('GOOG', start_date='2007-01-02', end_date='2010-01-02')

Google AT&T

plot_stock_price('T', start_date='1980-01-01', end_date='2020-01-01')

T

plot_stock_price('VTIP', start_date='1990-01-01', end_date='2020-01-01')

VTIP Vanguard 500 Index Fund Admiral Shares

plot_stock_price('VFIAX', start_date='1990-01-01', end_date='2020-01-01')

VFIAX iShares 20+ Year Treasury Bond ETF (TLT)

plot_stock_price('TLT', start_date='1900-01-01', end_date='2020-01-01')

TLT 13 Week treasury bill

plot_stock_price('^IRX', start_date='1900-01-01', end_date='2020-01-01')

IRX 30 Year Treasury bill

plot_stock_price('^TYX', start_date='2000-01-01', end_date='2020-01-01')

TYX Vanguard Target Retirement 2045 Fund Investor Shares

plot_stock_price('VTIVX', start_date='2000-01-01', end_date='2020-01-01')

VTIVX

def compute_avg_annual_return_between_2_periods(shares, start_date='2000-01-02', end_date='2019-12-31', source='yahoo'):
    shares_data = get_historical_data(shares, start_date=start_date, end_date=end_date, source=source)
    adj_close = shares_data['Adj Close']
    
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    
    while start_date.strftime('%Y-%m-%d') not in adj_close.index: 
        start_date = next_business_day(start_date)
    
    while end_date.strftime('%Y-%m-%d') not in adj_close.index: 
        end_date = previous_business_day(end_date)
    
    start_prices = adj_close.loc[start_date.strftime('%Y-%m-%d')]
    end_prices = adj_close.loc[end_date.strftime('%Y-%m-%d')]
    #print(end_prices, start_prices)
    return (end_prices/start_prices)**(1/(end_date.year - start_date.year)) - 1
SP500_rate_of_return_all = compute_avg_annual_return_between_2_periods(SP_500_symbol_list)
SP500_rate_of_return = {x:round(SP500_rate_of_return_all.loc[x],2) for x in SP500_rate_of_return_all.index \
                        if not pd.isnull(SP500_rate_of_return_all.loc[x])}
SP500_rate_of_return_clean = {k: v for k, v in sorted(SP500_rate_of_return.items(), key=lambda item: item[1])}
compute_avg_annual_return_between_2_periods('BRK-B')

0.10278063728967202

plot_stock_price('NVDA', start_date='2000-01-02', end_date='2019-12-31')

NVDA

Overall economic indicators

def plot_us_gdp(start_date = '1900-01-01', end_date = '2020-01-01'):
    plt.figure(figsize=(16,6))
    gdp_data = get_historical_data('GDP', start_date = start_date, end_date = end_date, source = 'fred')
    plt.plot(gdp_data)
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
    plt.legend(['US GDP'])
    plt.savefig('us_gdp.png')
def plot_us_inflation(start_date='1940-01-01', end_date='2020-01-01', index ='CPILFESL'):
    CPI  = get_historical_data(index, start_date = start_date, end_date = end_date, source = 'fred')
    CPI['CPI_Diff_monthly'] = CPI[index].diff()
    CPI['CPI_Diff_yearly'] = CPI[index].diff(12)
    CPI['CPI_monthly_inflation_rate'] = (CPI['CPI_Diff_monthly']/CPI[index])*100
    CPI['CPI_yearly_inflation_rate_pp'] = (CPI['CPI_Diff_yearly']/CPI[index])*100
    plt.figure(figsize=(16,6))
    plt.plot(CPI['CPI_monthly_inflation_rate'])
    plt.plot(CPI['CPI_yearly_inflation_rate_pp'])
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
    plt.legend(['US monthly inflation rate', 'US yearly point to point inflation rate'])
    plt.savefig('us_inflation_data_{}.png'.format(index))
    return CPI
def plot_index(index, start_date = '2010-01-02', end_date = '2020-01-02', source = 'fred'):
    indx  = get_historical_data(index, start_date, end_date, source)
    plt.figure(figsize=(16,6))
    plt.plot(indx)
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
    index_meaning = {'DGS30': '30-Year Treasury Constant Maturity Rate',
                     'DGS20': '20-Year Treasury Constant Maturity Rate',
                     'DGS10': '10-Year Treasury Constant Maturity Rate', 
                     'DGS7': '7-Year Treasury Constant Maturity Rate',
                     'DGS5': '5-Year Treasury Constant Maturity Rate',
                     'DGS3': '3-Year Treasury Constant Maturity Rate',
                     'DGS2': '2-Year Treasury Constant Maturity Rate',
                     'DGS1': '1-Year Treasury Constant Maturity Rate',
                     'DGS6MO': '6-Month Treasury Constant Maturity Rate',
                     'DGS3MO': '3-Month Treasury Constant Maturity Rate',
                     'DGS1MO': '1-Month Treasury Constant Maturity Rate', 
                     'FEDFUNDS': 'US Effective Federal Funds Rate',
                     'LIBOR': '3-Month London Interbank Offered Rate',
                     'NIKKEI225': 'Nikkei Stock Average, Nikkei 225',
                     'UNRATE': 'US Civilian Unemployment Rate',
                     'GFDEGDQ188S': 'Federal Debt: Total Public Debt as Percent of Gross Domestic Product',
                     'GDPC1': 'Real Gross Domestic Product percent change',
                     'A191RL1Q225SBEA': 'Real Gross Domestic Product dollars',
                     'CPIAUCSL': 'Consumer Price Index for All Urban Consumers: All Items',
                     'IRLTLT01JPM156N': 'Long-Term Government Bond Yields: 10-year: Japan'
                    }
    plt.legend([index_meaning[index]])
    plt.savefig('index_{}_{}_{}.png'.format(index, start_date, end_date))

Plotting the yield maturity curve

def plot_yield_curve(specific_date):
    next_date = next_business_day(datetime.datetime.strptime(specific_date, '%Y-%m-%d'))
    specific_date = next_date.strftime('%Y-%m-%d')
    syms = ['DGS1MO', 'DGS3MO', 'DGS6MO', 'DGS1', 'DGS2', 'DGS3', 'DGS5', 'DGS7', 'DGS10', 'DGS20', 'DGS30']
    yc = data.DataReader(syms, 'fred', specific_date, specific_date)
    names = dict(zip(syms, ['1m', '3m', '6m', '1yr', '2yr', '3yr', '5yr', '7yr', '10yr', '20yr', '30yr']))
    yc = yc.rename(columns=names)
    plt.figure(figsize=(16,6))
    #plt.plot([1, 3, 6, 12, 24, 36, 60, 84, 120, 240, 360], yc.loc[specific_date])
    plt.plot(yc.loc[specific_date])
    plt.grid(color='g', linestyle='-.', linewidth=0.5)
    plt.legend(['US Yield Curve on {}'.format(specific_date)])
    plt.savefig('yield_curve_{}.png'.format(specific_date))
    return yc.loc[specific_date]
yields = plot_yield_curve('2019-02-11')

yield_curve

yields = plot_yield_curve('2019-12-11')

yield_curve

plot_index('DGS6MO')

DGS6MO

SP-500 index plots over different decades.

plot_stock_price('^GSPC', start_date='1900-01-01', end_date='1960-01-01')

SP500_1900_1960

plot_stock_price('^GSPC', start_date='1960-01-01', end_date='1970-01-01')

SP500_1960_1970

plot_stock_price('^GSPC', start_date='1970-01-01', end_date='1980-01-01')

SP500_1970_1980

plot_stock_price('^GSPC', start_date='1980-01-01', end_date='1990-01-01')

SP500_1980_1990

plot_stock_price('^GSPC', start_date='1990-01-01', end_date='2000-01-01')

SP500_1990_2000

plot_stock_price('^GSPC', start_date='2000-01-01', end_date='2010-01-01')

SP500_2000_2010

plot_stock_price('^GSPC', start_date='2010-01-01', end_date='2020-01-01')

SP500_2010_2020

Consumer Price Index plot

plot_stock_price('CPI', start_date='1990-01-01', end_date='2020-01-01')

CPI

US GDP

gdp = plot_us_gdp()

usgdp

US inflation plots

cpi_u_inflation_data = plot_us_inflation(index = 'CPILFESL')

CPILFESL

cpi_u_inflation_data = plot_us_inflation(index = 'CPIAUCSL')

CPIAUCSL

Consumer Confidence Index plot

plot_stock_price('CCI', start_date='1960-01-01', end_date='2020-01-01')

CCI

Dow Jones Industrial Average

plot_stock_price('^DJI', start_date='1940-01-01', end_date='1990-01-01')

Dow Jones 1940

plot_stock_price('^DJI', start_date='1990-01-01', end_date='2020-01-01')

Dow Jones 1990

Plot of 10 year treasury bond interest rate

plot_index('DGS10', start_date = '1950-01-02')

Yield 1950

plot_index('DGS10', start_date = '2010-01-02')

Yield 2010

US Effective Federal Funds Rate

plot_index('FEDFUNDS')

Federal Funds

US unemployment rate

plot_index('UNRATE', start_date = '1910-01-02')

US Unemployment Rate

NIKKEI Index

plot_index('NIKKEI225')

NIKKEI

US Debt/GDP percentage plot

plot_index('GFDEGDQ188S', start_date = '1910-01-02')

Debt to GDP

US GDP

plot_index('GDPC1', start_date = '1910-01-02')

US GDP

plot_index('A191RL1Q225SBEA', start_date = '2010-01-02')

US GDP Dollars

Japenese interest rate plot

plot_index('IRLTLT01JPM156N', start_date = '1940-01-02')

Japanese interest rate

nasdaq = data.get_nasdaq_symbols()
print(nasdaq.shape)
nasdaq.head()
def compute_stats(symb):
    ticker = data.get_quote_yahoo(symb) 
    ticker['c1_marketCap_bn_calc'] = ticker['price'] * ticker['sharesOutstanding'] / 1e9
    ticker['c2_marketCap_bn_orig'] = ticker['marketCap'] / 1e9
    ticker['c3_price_calc'] = ticker['epsForward'] * ticker['trailingPE']
    ticker['c4_earnings_bn_calc'] = ticker['epsForward'] * ticker['sharesOutstanding'] / 1e9
    return ticker
compute_stats(['EXPE', 'GOOG', 'MSFT', 'AAPL', 'BB', 'JNPR', 'BRK-B', 'BRK-A'])

Getting historic stock dividends

get_historical_data('AAPL', start_date='2019-01-02', end_date='2019-12-31', source = 'yahoo-dividends')

A summary of this code is available in this notebook.