Calculating Beta (with Python)

IBM BetaAutomating beta calculations is a straightforward process given that market inputs (i.e. historical stock prices) are readily available on the web. This Python script uses monthly returns over 5 years to calculate a company’s beta. Rolling 60-month betas are graphed adjacent to the scatter plot to examine any systematic changes in the stock’s risk over time.

from pandas_datareader import data
import pandas as pd
import numpy as np
from pandas.stats.api import ols
import time
import matplotlib.pyplot as plt

# stock and market index tickers
stock_symbol = raw_input(
    stock_symbol = raw_input(
'Enter ticker symbol for stock: ').upper()
mrkt_symbol = raw_input(
    mrkt_symbol = raw_input( '''Enter ticker symbol
for market index (e.g., ^GSPC): ''').upper()

# set time period for historical prices
end_time = time.strftime('%m/%d/%Y')
start_time = end_time[:6] + str(int(end_time[-4:]) - 20)

# retreive historical prices for stock
stock = data.DataReader(stock_symbol,
data_source='google', start=start_time, end=end_time)

# retrieve historical prices for market index
mrkt = data.DataReader(mrkt_symbol,
data_source='google', start=start_time, end=end_time)

# simplify data sets
stock_simple = stock.rename(columns={'Close':'Stock'})
mrkt_simple = mrkt.rename(columns={'Close':'Mrkt'})
# combine stock and market index closing prices
data_simple = pd.concat([mrkt_simple, stock_simple],
    axis=1, join='inner')[['Mrkt', 'Stock']]

# keep only values by month
data_month = data_simple.asfreq('M', method='ffill')

# calculate percent change of closing prices
data_month['MrktPctChg'] = (data_month.Mrkt /
    data_month.Mrkt.shift(1) - 1)
data_month['StockPctChg'] = (data_month.Stock /
    data_month.Stock.shift(1) - 1)

# plot monthly returns
scat_data = data_month.tail(59)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
    label='Monthly Returns', color='blue',
    edgecolors='none', alpha=0.5)

# set x and y coordinate limits
x_corr = (-0.05, 0.05)
y_corr = (-0.05, 0.05)

# draw lines for x and y axes
ax1.plot(x_corr, (0, 0), color='black', alpha=0.4)
ax1.plot((0, 0), y_corr, color='black', alpha=0.4)

# reset x and y coordinate limits back to original
ax1.set_xlim(x_corr[0], x_corr[1])
ax1.set_ylim(y_corr[0], y_corr[1])

# set axis labels
ax1.set_xlabel('Market Index Monthly Returns')
ax1.set_ylabel(stock_symbol + ' Monthly Returns')

# create an array of x (i.e. market index) values
x = np.linspace(x_corr[0] + 0.005, x_corr[1] - 0.005)

# run regression to calculate beta
reg_month = ols(y=scat_data['StockPctChg'],

# define function for regression equation
def month(x):
    return reg_month.beta[1] + reg_month.beta[0] * x

# plot beta for monthly returns
ax1.plot(x, month(x), color='magenta', linestyle='-',
    linewidth=2, label='Beta', alpha=0.8)

# add legend
ax1.legend(loc='upper center',
    bbox_to_anchor=(0.5, -0.075), ncol=2, fontsize='large')

# add Beta and R2 stats to plot
ax1.text(-0.038, 0.042,
    'Beta: ' + str(np.round(reg_month.beta[0], 3)),
ax1.text(-0.038, 0.035,
    'R2: ' + str(np.round(reg_month.r2, 3)),

# calculate rolling betas
for date in data_month.index[1:]:
data = data_month.loc[:date].tail(59)
reg = ols(y=data['StockPctChg'], x=data['MrktPctChg'])
    data_month.loc[date, 'Beta'] = reg.beta[0]

# plot only betas with 60 data points
if len(data_month) > 60:
    to_plot = data_month[data_month.index[60]:]
    to_plot = data_month
ax2.plot(to_plot.index, to_plot.Beta, color='blue',
    linewidth=2, alpha=0.5, label='5-year Rolling Beta')

# get x coordinate limits
x_corr = ax2.get_xlim()

# draw lines for x axis
ax2.plot(x_corr, (1, 1), color='black', alpha=0.4)

# add y label
ax2.set_ylabel(stock_symbol + ' Beta')

# add legend
ax2.legend(loc='upper center',
    bbox_to_anchor=(0.5, -0.075), ncol=1, fontsize='large')

# display plot

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s