Simulating Beta Hedging in Python


import datetime as dt
import numpy as np 
import pandas as pd 
import pandas_datareader.data as web 
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt 
from matplotlib import style
%matplotlib inline

style.use('ggplot')
def get_return(tickers, start, end, log_return=True):
    data = web.DataReader(tickers, 'yahoo', start, end)['Adj Close']
    data = data.sort_index()
    
    if log_return:
        daily_return = np.log(data.pct_change()+1)
    else:
        daily_return = data.pct_change()
    
    daily_return.fillna(0, inplace=True)

    return daily_return
start = dt.datetime(2016,1,1)
end = dt.datetime(2016, 12, 31)

#list of stocks in portfolio
tickers = ['AMZN','SPY']
daily_return = get_return(tickers, start, end, log_return=True)
daily_return.head()
AMZN SPY
Date
2016-01-04 0.000000 0.000000
2016-01-05 -0.005036 0.001690
2016-01-06 -0.001800 -0.012695
2016-01-07 -0.039841 -0.024284
2016-01-08 -0.001465 -0.011037
daily_return.plot(figsize=(14,8))
plt.ylabel("Daily Return")
plt.legend()
plt.show()

png

# Import the OLS model
# Set SPY as my dependent variable, AMZN return as my independent variables
# Print out my OLS model stats result
results = smf.ols('AMZN ~ SPY', data=daily_return).fit()
print(results.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                   AMZN   R-squared:                       0.230
Model:                            OLS   Adj. R-squared:                  0.226
Method:                 Least Squares   F-statistic:                     74.47
Date:                Sat, 02 Sep 2017   Prob (F-statistic):           7.29e-16
Time:                        22:50:25   Log-Likelihood:                 684.04
No. Observations:                 252   AIC:                            -1364.
Df Residuals:                     250   BIC:                            -1357.
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      0.0001      0.001      0.105      0.917      -0.002       0.002
SPY            1.0706      0.124      8.629      0.000       0.826       1.315
==============================================================================
Omnibus:                       67.661   Durbin-Watson:                   2.012
Prob(Omnibus):                  0.000   Jarque-Bera (JB):             2053.016
Skew:                          -0.070   Prob(JB):                         0.00
Kurtosis:                      16.982   Cond. No.                         122.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
plt.figure(figsize=(14,8))
plt.xlabel('SPY daily return')
plt.ylabel('AMZN daily return')
plt.title('Linear Model & Scatter Plot')
plt.plot(daily_return['SPY'], daily_return['AMZN'], '.',
         daily_return['SPY'], results.predict(daily_return['SPY']), '-')
[<matplotlib.lines.Line2D at 0x1145f80b8>,
 <matplotlib.lines.Line2D at 0x1145f8278>]

png

results.params
Intercept    0.000106
SPY          1.070623
dtype: float64
alpha = results.params[0]
beta = results.params[1]

print ('alpha: ' + str(alpha))
print ('beta: ' + str(beta))
alpha: 0.00010619636426
beta: 1.07062267236

Construct a portfolio with beta hedging

  1. Alpha = actual return - [Beta(rm - rf) + rf]
  2. In this case I assume risk free rate is 0, so the Alpha is just the intercept in the Linear Model
  3. Beta is the hedge ratio, so I simply added a hedge into the AMZN return, then get the pure alpha
portfolio = -1*beta*daily_return['SPY'] + daily_return['AMZN']
portfolio.name = "AMZN + Beta Hedge"

daily_return['AMZN'].plot(figsize=(14,8)) 
daily_return['SPY'].plot(figsize=(14,8))
portfolio.plot(figsize=(14,8))
plt.ylabel("Daily Return")
plt.legend()
plt.show()

png

daily_return['AMZN + Beta Hedge'] = portfolio
daily_return.head()
AMZN SPY AMZN + Beta Hedge
Date
2016-01-04 0.000000 0.000000 0.000000
2016-01-05 -0.005036 0.001690 -0.006846
2016-01-06 -0.001800 -0.012695 0.011791
2016-01-07 -0.039841 -0.024284 -0.013842
2016-01-08 -0.001465 -0.011037 0.010352
cum_daily_return = (1 + daily_return).cumprod()
cum_daily_return.tail()
AMZN SPY AMZN + Beta Hedge
Date
2016-12-23 1.145322 1.137326 0.998392
2016-12-27 1.161486 1.140144 1.009833
2016-12-28 1.162584 1.130682 1.019761
2016-12-29 1.152027 1.130430 1.010744
2016-12-30 1.128788 1.126291 0.994317
cum_daily_return.plot(grid = True, figsize=(14,10)).axhline(y = 1, color = "black", lw = 1)
plt.ylabel("Cumulative Returns")
plt.legend()
plt.show()

png