In [1]:
import numpy as np
import pandas as pd
import edhec_risk_kit as erk
import matplotlib.pyplot as plt
%matplotlib inline

Load industry returns from 1980 to 2015

  • Consider the Finance, Utility, Telecom, and Health industries
In [6]:
cols = ['Fin', 'Util', 'Telcm', 'Hlth']
ind = erk.get_ind_returns().loc['1980':'2015', cols]

Build the Maxiumum Sharpe Ratio (MSR) portfolio

Calculate the portfolio weight for each asset

In [7]:
er = erk.annualize_rets(ind, periods_per_year=12)
cov = ind.cov()
w_msr = erk.msr(riskfree_rate=0.02, er=er, cov=cov)
pd.DataFrame(w_msr, index=cols, columns=['Shape Ratio Weight'])
Out[7]:
Shape Ratio Weight
Fin 0.000000
Util 0.454315
Telcm 0.061605
Hlth 0.484080

Build the Global Minimum Variance (GMV) portfolio

Calculate the portfolio weight for each asset

In [8]:
w_gmv = erk.gmv(cov=cov)
pd.DataFrame(w_gmv, index=cols, columns=['GMV Weight'])
Out[8]:
GMV Weight
Fin 0.000000
Util 0.581040
Telcm 0.169712
Hlth 0.249248

Compare the annualized volatility of the MSR and GMV portfolios (weights calculated from data from 1980 to 2015) from 2016 to 2018

In [9]:
ind = erk.get_ind_returns().loc[:, cols]

er = erk.annualize_rets(
    ind['1980':'2015'], 
    periods_per_year=12
)

cov = ind['1980':'2015'].cov()
w_msr = erk.msr(riskfree_rate=0.02, er=er, cov=cov)
w_gmv = erk.gmv(cov=cov)

vol_msr = np.sqrt(12)*erk.portfolio_vol(
    weights=w_msr, 
    covmat=ind['2016':'2018'].cov()
)
vol_gmv = np.sqrt(12)*erk.portfolio_vol(
    weights=w_gmv, 
    covmat=ind['2016':'2018'].cov()
)

print('MSR 2016-2018 variance:', vol_msr)
print('GMV 2016-2018 variance:', vol_gmv)
MSR 2016-2018 variance: 0.0968449984016509
GMV 2016-2018 variance: 0.08990557036497361

Calculate the annualized returns of the these two portfolios from 2016 to 2018

In [10]:
r = erk.annualize_rets(
    ind['2016':'2018'], 
    periods_per_year=12
)

r_msr = erk.portfolio_return(
    weights = w_msr, 
    returns = r
)

r_gmv = erk.portfolio_return(
    weights = w_gmv,
    returns = r
)

print('MSR 2016-2018 return:', r_msr)
print('GMV 2016-2018 return:', r_gmv)
MSR 2016-2018 return: 0.08369298270843524
GMV 2016-2018 return: 0.08893150684183913

Plot the efficient frontier given a set of assets

Plot the efficient frontier for a portfolio considering 2 assets, Finance and Utilities stocks, based on evaluation from 1980 to 2015

In [14]:
er = erk.annualize_rets(
    ind['1980':'2015'], 
    periods_per_year=12
)

erk.plot_ef2(
    100,
    er=er[['Fin', 'Util']],
    cov=ind.loc['1980':'2015', ['Fin', 'Util']].cov()
)
Out[14]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a41f934308>

Plot the efficient frontier for a portfolio considering 4 assets: Finance, Utilities, Telecom, and Health stocks, based on evaluation from 1980 to 2015

In [19]:
er = erk.annualize_rets(
    ind['1980':'2015'], 
    periods_per_year=12
)

erk.plot_ef(
    300, 
    er=er, 
    cov=ind.loc['1980':'2015', cols].cov(), 
    show_ew=True,
    show_gmv=True
)
Out[19]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a4200121c8>

Calculate portfolio weights to achieve a target return while minimizing volatility

Considering the industries in the 30 industry returns data from 1960 to 2015, calculating the asset weights that minimize volatility which achieving a target return of 12%

In [28]:
ind = erk.get_ind_returns(n_inds=30)

er = erk.annualize_rets(
    ind['1960':'2015'], 
    periods_per_year=12
)

weights = erk.minimize_vol(
    target_return=0.12,
    er=er,
    cov=ind['1960':'2015'].cov()
)

weights_df = pd.DataFrame(weights, index=ind.columns, columns=['Weights'])
weights_df.sort_values('Weights', ascending=False).plot.bar()
Out[28]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a4212ff488>
In [ ]: