Data Bootcamp "Group Project"

Analysis of historical stock return and volatility by industries using Fama-French Data

Sung Kim / Arthur Hong / Kevin Park

Contents:

  1. Background
  2. About the Data
  3. Key Data
    • 3.1 | Slicing the Key Data
    • 3.2 | Joining the Key Data
  4. Beta Calculation
  5. Creating Visual Output

In [74]:
# import packages 
import pandas as pd                   # data management
import matplotlib.pyplot as plt       # graphics 
import datetime as dt                 # check today's date 
import sys                            # check Python version 
import numpy as np

# IPython command, puts plots in notebook 
%matplotlib inline

print('Today is', dt.date.today())
print('Python version:\n', sys.version, sep='')


Today is 2017-04-25
Python version:
3.6.0 |Anaconda 4.3.0 (64-bit)| (default, Dec 23 2016, 11:57:41) [MSC v.1900 64 bit (AMD64)]

1 | Background

Designed by Eugene Fama and Kenneth French, Fama-French factor model is a widely used tool in finance created by employing statistical techniques to estimate returns of stocks. Within this project, we attempted to analyze stock returns and risks by calculating betas of different industries over the past seven year period.

Source: Fama-French Website

2 | About the Data

We collected our data by using PANDAS DataReader to get a direct feed to Kenneth French's data, where numerous equity market data are available online. Among them, we used the "30 Industry Portfolio" dataset to compare stock returns and risks of different industries.

Links to data:

3 | Key Data

We first imported the 30 industry portfolio data set. There are different categories: value or equal weighted, monthly or annual, etc. Detailed breakdown and description are shown below.

3.1 | Slicing the Key Data

Among many different types of data, we will extract value-weighted monthly return (dataframe: 0 in 30 Industry Portfolios) since 2010 to run our analysis and store it in a dataframe ind.

We also imported Fama-French 3-factor data with the same time frame, which contain:

  • Mkt-RF (market return - risk free rate)
  • SMB (Small-Minus-Big, the average return on the three small portfolios minus the average return on the three big portfolios)
  • HML (High-Minus-Low, the average return on the two value portfolios minus the average return on the two growth portfolios)

Because we need market return rather than equity risk premium we add "Mkt" column in the dataframe by combining "Mkt-RF" and "RF". Finally, we set this 3-factor market data (Mkt-RF, SMB, HML, RF, and Mkt) in dataframe mkt1.


In [75]:
# importing 30 industry portfolio data set
import pandas_datareader.data as web

ff=web.DataReader("30_Industry_Portfolios", "famafrench")

In [76]:
print(ff['DESCR'])


30 Industry Portfolios
----------------------

This file was created by CMPT_IND_RETS using the 201702 CRSP database. It contains value- and equal-weighted returns for 30 industry portfolios. The portfolios are constructed at the end of June. The annual returns are from January to December. Missing data are indicated by -99.99 or -999. Copyright 2017 Kenneth R. French

  0 : Average Value Weighted Returns -- Monthly (86 rows x 30 cols)
  1 : Average Equal Weighted Returns -- Monthly (86 rows x 30 cols)
  2 : Average Value Weighted Returns -- Annual (7 rows x 30 cols)
  3 : Average Equal Weighted Returns -- Annual (7 rows x 30 cols)
  4 : Number of Firms in Portfolios (86 rows x 30 cols)
  5 : Average Firm Size (86 rows x 30 cols)
  6 : Sum of BE / Sum of ME (7 rows x 30 cols)
  7 : Value-Weighted Average of BE/ME (7 rows x 30 cols)

In [77]:
# extracting value-weighted return only
ff[0]


Out[77]:
Food Beer Smoke Games Books Hshld Clths Hlth Chems Txtls ... Telcm Servs BusEq Paper Trans Whlsl Rtail Meals Fin Other
Date
2010-01 -0.92 -3.70 -3.15 1.12 1.23 0.85 -3.11 0.00 -4.04 -8.66 ... -6.70 -7.09 -7.88 -5.50 -4.04 -2.55 -1.92 -0.99 -1.18 2.24
2010-02 2.92 0.25 5.00 6.02 -1.78 3.69 6.07 0.37 5.46 15.68 ... 2.85 2.85 6.30 3.04 7.25 5.89 4.32 4.56 2.70 1.87
2010-03 4.44 6.11 6.36 12.06 5.53 2.13 11.39 3.61 7.34 8.42 ... 7.60 5.20 8.12 5.86 8.11 5.99 6.14 8.40 8.14 9.07
2010-04 -1.46 -1.76 -3.03 10.96 2.32 1.21 4.23 -2.23 3.08 11.43 ... 3.59 0.47 3.89 4.22 3.82 3.20 1.85 7.36 0.95 3.86
2010-05 -5.37 -3.88 -7.71 -7.05 -10.12 -4.35 -5.67 -8.01 -9.99 -9.87 ... -5.81 -8.29 -7.08 -8.89 -5.98 -4.01 -5.83 -4.88 -9.12 -10.05
2010-06 -1.97 -1.63 3.54 -8.80 -8.70 -3.24 -9.31 -1.63 -7.79 -14.55 ... -3.98 -6.74 -5.99 -2.29 -7.66 -5.20 -10.56 -5.29 -7.31 -7.58
2010-07 5.04 8.37 11.12 7.85 5.29 4.22 8.34 2.15 14.24 6.81 ... 9.58 8.22 6.82 7.64 10.84 3.20 4.65 7.04 6.62 8.03
2010-08 -0.46 -0.01 -0.05 -1.32 -10.04 -3.96 -7.41 -1.66 -0.11 -5.50 ... -2.13 -5.18 -8.21 -6.06 -4.65 -7.55 -4.18 0.38 -8.38 -7.12
2010-09 1.57 4.95 10.04 14.16 12.91 3.98 17.54 9.00 9.96 13.39 ... 7.97 11.60 13.48 9.16 9.87 9.90 13.59 7.13 7.46 10.01
2010-10 5.85 1.93 5.27 12.57 7.13 4.51 3.34 2.01 8.18 3.28 ... 4.51 7.90 4.14 3.48 5.35 4.95 1.32 6.06 1.97 -0.11
2010-11 -1.86 2.01 -3.77 7.31 -3.16 -2.36 9.27 -3.33 0.84 -1.01 ... -1.89 -2.42 1.12 0.32 2.42 0.29 4.95 4.16 -0.34 -1.17
2010-12 5.68 3.57 4.30 -0.66 8.37 5.79 1.08 5.41 7.49 4.19 ... 6.57 7.13 5.26 4.78 3.19 6.83 3.50 0.11 10.51 11.82
2011-01 -0.62 -3.62 -2.94 1.52 2.56 -1.00 -3.32 -0.71 1.60 -3.65 ... 0.03 2.40 4.94 3.06 -0.48 2.80 -1.28 -2.43 2.24 7.55
2011-02 5.25 0.60 8.98 2.15 3.06 1.66 8.88 3.33 4.92 7.10 ... 7.47 2.46 2.82 3.34 1.42 2.97 1.38 3.95 2.65 3.59
2011-03 1.71 3.35 5.25 -0.53 -0.09 0.23 -4.40 2.29 2.01 4.50 ... 1.60 0.07 -2.62 1.62 3.01 1.47 0.48 1.80 -1.48 -1.44
2011-04 4.27 3.90 4.90 6.04 0.12 4.93 8.00 6.37 4.48 4.95 ... 3.35 2.59 3.29 1.76 2.93 4.06 5.20 1.41 0.64 2.18
2011-05 2.37 0.49 4.11 -0.56 2.34 3.05 0.34 1.96 -3.75 2.89 ... 0.91 -2.30 -1.17 0.34 -0.44 1.20 0.21 4.07 -2.49 -2.94
2011-06 -0.32 0.62 -5.60 -1.55 -1.31 -2.52 4.50 -1.84 -0.22 -6.35 ... -1.34 -1.09 -3.32 -0.62 -0.47 -2.10 -1.41 1.52 -2.18 -1.91
2011-07 -0.61 -2.97 3.29 4.04 -3.78 -2.74 2.26 -3.65 -1.83 -6.29 ... -4.87 0.46 -1.65 -6.65 -5.09 -4.58 -0.10 -0.29 -3.91 -4.53
2011-08 -1.80 2.24 -0.11 -5.72 -7.19 0.37 -5.51 -3.09 -7.99 -7.01 ... -5.22 -6.82 -7.33 -5.71 -6.98 -4.05 -3.37 -0.79 -9.12 -3.65
2011-09 -4.60 -3.84 -5.27 -19.22 -8.41 -3.96 -5.10 -3.96 -16.45 -14.41 ... -5.79 -4.89 -5.51 -10.21 -9.34 -8.14 -2.86 -5.41 -11.02 -4.37
2011-10 5.65 1.93 8.26 15.33 9.86 4.51 16.51 5.54 18.21 14.26 ... 7.58 12.10 12.22 10.83 15.28 13.76 9.14 10.14 13.43 9.34
2011-11 0.50 0.52 7.57 -2.59 -0.69 1.21 -3.84 1.28 -1.14 -1.08 ... 0.29 -1.74 -1.90 1.07 1.49 1.17 0.85 2.31 -2.91 -0.39
2011-12 0.65 3.98 3.72 -4.64 3.58 1.91 -2.24 3.53 -0.05 0.82 ... 3.18 -1.32 -1.06 1.08 1.19 -0.02 0.34 3.75 1.76 1.34
2012-01 2.84 -2.33 -4.58 12.14 0.61 -0.99 9.89 3.38 11.26 6.96 ... 2.44 5.48 10.56 4.50 6.62 6.07 4.04 3.32 7.15 3.48
2012-02 1.25 0.77 9.62 5.76 3.28 6.40 6.51 1.23 2.19 5.73 ... 4.78 5.21 7.48 3.62 -1.24 1.58 3.51 2.94 6.50 1.35
2012-03 2.02 6.04 5.42 3.98 2.30 1.71 1.67 3.96 2.66 4.53 ... 2.50 3.57 5.37 1.65 1.00 2.98 5.21 3.76 6.88 3.57
2012-04 0.61 1.33 1.63 -2.05 -2.56 -1.82 0.12 0.61 1.00 -0.06 ... 1.73 -0.75 -3.08 -0.62 1.24 -0.30 1.36 1.04 -2.42 -1.21
2012-05 -2.17 -0.25 -3.34 -11.89 -8.60 -5.06 -5.68 -3.28 -8.44 -2.83 ... -1.07 -7.49 -8.24 -5.65 -2.08 -6.12 -2.12 -4.77 -9.01 -2.64
2012-06 2.15 5.74 5.86 0.48 7.12 0.04 -10.76 6.80 3.46 2.22 ... 7.09 4.29 1.62 2.63 4.04 2.58 3.02 -2.21 4.52 6.01
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2014-09 -0.53 0.83 2.15 -4.45 -7.31 0.84 4.44 -0.08 -2.14 -2.38 ... -1.68 -1.18 -1.91 -3.51 0.71 -2.29 -1.50 -0.60 -0.65 0.15
2014-10 1.70 3.28 6.13 0.64 3.30 3.71 1.57 5.76 -1.09 2.08 ... 1.41 0.41 2.83 6.42 6.22 3.32 3.32 1.28 3.88 1.58
2014-11 5.68 4.35 0.76 -0.39 1.12 3.23 8.89 2.68 2.20 7.53 ... 3.09 2.13 6.47 4.80 5.88 1.83 8.91 5.57 1.99 4.55
2014-12 -2.48 -4.30 -3.11 -4.57 1.82 0.02 -0.82 -0.89 0.85 -0.31 ... -1.82 -0.61 -1.87 2.07 1.09 0.26 2.25 -0.43 1.95 0.17
2015-01 -1.64 0.90 2.95 0.06 -2.16 -4.92 -3.75 1.56 -2.06 2.02 ... -4.78 -4.28 -2.14 -2.43 -4.53 -2.37 -0.29 0.66 -7.49 -4.11
2015-02 4.44 4.40 5.47 5.80 9.00 3.83 5.43 4.31 8.10 13.34 ... 9.09 7.78 8.43 6.68 3.10 5.37 5.58 6.82 7.86 4.63
2015-03 -0.72 -2.07 -8.82 -2.63 0.59 -1.98 1.23 0.86 -3.55 3.33 ... -2.25 -1.50 -3.12 -1.73 -3.62 0.57 1.00 -0.29 0.06 -1.77
2015-04 -0.17 -0.52 5.94 3.69 -4.12 -2.41 -1.53 -1.39 1.11 -5.95 ... 3.35 2.24 0.10 -2.64 -1.14 -1.23 -2.88 0.51 0.76 -0.23
2015-05 2.03 2.00 1.28 0.78 1.95 0.39 0.04 4.89 1.24 4.37 ... 0.76 -0.09 4.02 1.33 -3.06 1.44 0.54 1.56 2.99 0.92
2015-06 -1.95 -1.71 -2.57 1.26 -0.77 -0.11 4.17 0.07 -2.72 4.09 ... -0.45 -1.90 -4.92 -2.84 -3.25 -2.82 -0.49 0.29 1.33 -3.58
2015-07 4.03 3.51 9.59 6.03 -2.93 0.69 5.96 3.66 -4.90 -0.72 ... 1.45 5.28 -0.91 -0.56 3.27 -1.32 5.79 4.17 1.97 3.17
2015-08 -4.37 -3.12 -4.06 -7.27 -8.60 -6.94 -3.86 -8.37 -7.15 -3.11 ... -8.34 -5.30 -6.50 -5.69 -6.37 -4.13 -5.44 -6.48 -6.44 -5.21
2015-09 -1.19 2.58 2.37 -9.89 -5.39 -0.55 1.18 -7.28 -8.38 -5.92 ... -2.74 -1.43 -1.72 -2.65 -0.71 -6.04 -1.75 0.44 -3.17 -1.87
2015-10 5.81 8.06 10.90 14.54 12.20 5.86 0.98 7.74 16.62 7.96 ... 8.90 11.30 8.16 10.19 6.48 5.07 4.56 5.05 6.05 6.97
2015-11 0.11 -0.71 -3.00 -0.37 -1.16 -1.09 -1.08 0.71 1.68 -2.59 ... -2.04 1.97 0.11 -0.01 -1.10 2.67 0.61 -1.01 2.08 0.05
2015-12 1.97 0.31 1.60 -1.76 -6.11 1.88 -4.37 0.40 -4.81 -2.64 ... -2.99 -1.15 -4.63 -3.75 -5.01 -1.87 0.83 -0.94 -2.85 0.26
2016-01 -1.66 -0.22 4.29 -8.16 -5.35 0.14 1.53 -9.42 -11.09 -5.32 ... -0.41 -5.02 -7.94 -5.26 -8.52 -8.67 -4.44 -0.93 -9.42 -3.19
2016-02 0.97 -2.32 0.95 4.25 -0.89 0.35 0.83 -1.07 6.81 0.65 ... 1.11 -2.45 1.47 3.01 6.91 3.87 -0.34 1.05 -2.76 2.73
2016-03 4.71 5.63 5.06 8.60 6.85 4.67 2.32 2.92 8.35 3.60 ... 6.02 7.73 8.88 8.20 6.88 6.20 6.01 5.38 6.76 6.70
2016-04 0.64 0.32 -0.24 -6.15 1.82 -0.41 -2.26 3.56 3.78 1.56 ... 0.62 -2.59 -5.45 0.81 -1.07 0.50 -0.37 -2.37 3.90 0.68
2016-05 2.07 -0.90 0.84 5.59 -0.52 -0.08 -4.95 2.47 -1.41 -1.69 ... 0.26 4.73 5.65 1.81 -2.17 1.79 1.20 -1.47 2.17 -2.01
2016-06 4.77 5.33 6.89 -4.28 -0.18 3.18 1.65 0.13 -1.12 -4.65 ... 3.17 -2.09 -1.61 2.08 -2.51 1.83 0.73 1.18 -4.86 3.63
2016-07 -0.53 1.84 -2.76 6.08 5.68 2.60 1.64 6.03 4.31 8.41 ... 2.36 7.35 8.22 2.54 5.41 3.67 3.80 2.20 3.91 -0.23
2016-08 -0.51 -0.88 -1.19 1.06 -0.54 1.38 1.39 -3.23 2.51 1.05 ... -3.50 1.14 2.36 2.48 1.11 -1.02 -1.67 -0.22 4.65 2.24
2016-09 -2.91 1.65 -2.72 4.66 -2.60 0.23 -6.90 0.36 -1.74 -4.85 ... 0.48 0.77 4.36 -0.62 2.89 -2.54 -0.16 -2.26 -1.34 -3.52
2016-10 -0.22 -1.63 4.55 5.53 -10.29 -2.98 -5.74 -7.43 -1.93 -4.15 ... -2.75 -0.48 -2.21 -5.47 -0.62 -8.15 -3.57 -1.90 1.37 -0.50
2016-11 -4.45 -5.75 -5.06 3.88 8.72 -3.78 1.81 1.37 7.57 1.59 ... 6.01 0.08 2.36 4.22 12.76 9.27 3.00 8.46 12.02 8.26
2016-12 4.42 3.03 5.44 -3.23 1.26 1.57 -0.41 0.86 0.35 -1.24 ... 4.71 -0.11 2.09 1.89 0.87 2.37 -0.95 0.64 3.77 2.58
2017-01 0.77 -0.98 5.58 4.94 2.23 2.61 0.03 2.21 3.83 6.95 ... 3.38 5.55 3.26 2.32 1.74 1.71 0.97 0.79 0.64 -0.81
2017-02 1.77 6.17 7.94 0.66 1.10 5.01 3.85 7.07 3.14 -2.08 ... -0.02 3.22 7.03 3.25 2.60 2.78 2.83 2.44 4.68 3.75

86 rows × 30 columns


In [78]:
ind=ff[0]

In [79]:
ind.shape


Out[79]:
(86, 30)

In [80]:
# importing mkt data from 3 factors model

mkt=web.DataReader("F-F_Research_Data_Factors", "famafrench")

In [81]:
mkt


Out[81]:
{0:          Mkt-RF   SMB   HML    RF
 Date                             
 2010-01   -3.36  0.37  0.30  0.00
 2010-02    3.40  1.19  3.18  0.00
 2010-03    6.31  1.49  2.15  0.01
 2010-04    2.00  4.99  2.83  0.01
 2010-05   -7.89  0.00 -2.41  0.01
 2010-06   -5.56 -2.01 -4.52  0.01
 2010-07    6.93  0.21 -0.21  0.01
 2010-08   -4.77 -2.99 -1.96  0.01
 2010-09    9.54  3.92 -3.12  0.01
 2010-10    3.88  1.14 -2.52  0.01
 2010-11    0.60  3.68 -0.91  0.01
 2010-12    6.82  0.68  3.78  0.01
 2011-01    1.99 -2.48  0.82  0.01
 2011-02    3.49  1.53  1.10  0.01
 2011-03    0.45  2.58 -1.57  0.01
 2011-04    2.90 -0.31 -2.53  0.00
 2011-05   -1.27 -0.72 -2.09  0.00
 2011-06   -1.75 -0.20 -0.33  0.00
 2011-07   -2.36 -1.34 -1.16  0.00
 2011-08   -5.99 -3.03 -2.40  0.01
 2011-09   -7.59 -3.54 -1.37  0.00
 2011-10   11.35  3.44 -0.22  0.00
 2011-11   -0.28 -0.18 -0.42  0.00
 2011-12    0.74 -0.67  1.71  0.00
 2012-01    5.05  2.15 -1.11  0.00
 2012-02    4.42 -1.72  0.11  0.00
 2012-03    3.11 -0.63  0.89  0.00
 2012-04   -0.85 -0.54 -0.46  0.00
 2012-05   -6.19  0.00 -0.52  0.01
 2012-06    3.89  0.79  0.41  0.00
 ...         ...   ...   ...   ...
 2014-09   -1.97 -3.80 -1.19  0.00
 2014-10    2.52  4.28 -1.68  0.00
 2014-11    2.55 -2.05 -2.98  0.00
 2014-12   -0.06  2.59  2.12  0.00
 2015-01   -3.11 -0.51 -3.47  0.00
 2015-02    6.13  0.51 -1.73  0.00
 2015-03   -1.12  3.07 -0.45  0.00
 2015-04    0.59 -3.01  1.84  0.00
 2015-05    1.36  0.90 -1.32  0.00
 2015-06   -1.53  2.85 -0.80  0.00
 2015-07    1.54 -4.07 -4.21  0.00
 2015-08   -6.04  0.52  2.71  0.00
 2015-09   -3.08 -2.61  0.58  0.00
 2015-10    7.75 -1.93 -0.11  0.00
 2015-11    0.56  3.62 -0.57  0.00
 2015-12   -2.17 -2.81 -2.46  0.01
 2016-01   -5.77 -3.36  2.26  0.01
 2016-02   -0.07  0.83 -0.48  0.02
 2016-03    6.96  0.86  1.11  0.02
 2016-04    0.92  0.68  3.25  0.01
 2016-05    1.78 -0.27 -1.79  0.01
 2016-06   -0.05  0.61 -1.49  0.02
 2016-07    3.95  2.90 -0.98  0.02
 2016-08    0.50  0.94  3.18  0.02
 2016-09    0.25  2.00 -1.34  0.02
 2016-10   -2.02 -4.41  4.15  0.02
 2016-11    4.86  5.68  8.44  0.01
 2016-12    1.81 -0.04  3.52  0.03
 2017-01    1.94 -1.00 -2.69  0.04
 2017-02    3.57 -1.79 -1.80  0.04
 
 [86 rows x 4 columns], 1:       Mkt-RF    SMB    HML    RF
 Date                            
 2010   17.37  13.77  -5.17  0.12
 2011    0.44  -6.04  -8.41  0.04
 2012   16.28  -1.22   9.89  0.06
 2013   35.20   7.35   1.54  0.02
 2014   11.70  -7.75  -1.65  0.02
 2015    0.07  -3.74  -9.48  0.02
 2016   13.30   6.66  23.33  0.20, 'DESCR': 'F-F Research Data Factors\n-------------------------\n\nThis file was created by CMPT_ME_BEME_RETS using the 201702 CRSP database. The 1-month TBill return is from Ibbotson and Associates, Inc. Copyright 2017 Kenneth R. French\n\n  0 : (86 rows x 4 cols)\n  1 : Annual Factors: January-December (7 rows x 4 cols)'}

In [82]:
print(mkt['DESCR'])


F-F Research Data Factors
-------------------------

This file was created by CMPT_ME_BEME_RETS using the 201702 CRSP database. The 1-month TBill return is from Ibbotson and Associates, Inc. Copyright 2017 Kenneth R. French

  0 : (86 rows x 4 cols)
  1 : Annual Factors: January-December (7 rows x 4 cols)

In [83]:
# Dropping annual result
mkt1=mkt[0]

In [84]:
mkt1


Out[84]:
Mkt-RF SMB HML RF
Date
2010-01 -3.36 0.37 0.30 0.00
2010-02 3.40 1.19 3.18 0.00
2010-03 6.31 1.49 2.15 0.01
2010-04 2.00 4.99 2.83 0.01
2010-05 -7.89 0.00 -2.41 0.01
2010-06 -5.56 -2.01 -4.52 0.01
2010-07 6.93 0.21 -0.21 0.01
2010-08 -4.77 -2.99 -1.96 0.01
2010-09 9.54 3.92 -3.12 0.01
2010-10 3.88 1.14 -2.52 0.01
2010-11 0.60 3.68 -0.91 0.01
2010-12 6.82 0.68 3.78 0.01
2011-01 1.99 -2.48 0.82 0.01
2011-02 3.49 1.53 1.10 0.01
2011-03 0.45 2.58 -1.57 0.01
2011-04 2.90 -0.31 -2.53 0.00
2011-05 -1.27 -0.72 -2.09 0.00
2011-06 -1.75 -0.20 -0.33 0.00
2011-07 -2.36 -1.34 -1.16 0.00
2011-08 -5.99 -3.03 -2.40 0.01
2011-09 -7.59 -3.54 -1.37 0.00
2011-10 11.35 3.44 -0.22 0.00
2011-11 -0.28 -0.18 -0.42 0.00
2011-12 0.74 -0.67 1.71 0.00
2012-01 5.05 2.15 -1.11 0.00
2012-02 4.42 -1.72 0.11 0.00
2012-03 3.11 -0.63 0.89 0.00
2012-04 -0.85 -0.54 -0.46 0.00
2012-05 -6.19 0.00 -0.52 0.01
2012-06 3.89 0.79 0.41 0.00
... ... ... ... ...
2014-09 -1.97 -3.80 -1.19 0.00
2014-10 2.52 4.28 -1.68 0.00
2014-11 2.55 -2.05 -2.98 0.00
2014-12 -0.06 2.59 2.12 0.00
2015-01 -3.11 -0.51 -3.47 0.00
2015-02 6.13 0.51 -1.73 0.00
2015-03 -1.12 3.07 -0.45 0.00
2015-04 0.59 -3.01 1.84 0.00
2015-05 1.36 0.90 -1.32 0.00
2015-06 -1.53 2.85 -0.80 0.00
2015-07 1.54 -4.07 -4.21 0.00
2015-08 -6.04 0.52 2.71 0.00
2015-09 -3.08 -2.61 0.58 0.00
2015-10 7.75 -1.93 -0.11 0.00
2015-11 0.56 3.62 -0.57 0.00
2015-12 -2.17 -2.81 -2.46 0.01
2016-01 -5.77 -3.36 2.26 0.01
2016-02 -0.07 0.83 -0.48 0.02
2016-03 6.96 0.86 1.11 0.02
2016-04 0.92 0.68 3.25 0.01
2016-05 1.78 -0.27 -1.79 0.01
2016-06 -0.05 0.61 -1.49 0.02
2016-07 3.95 2.90 -0.98 0.02
2016-08 0.50 0.94 3.18 0.02
2016-09 0.25 2.00 -1.34 0.02
2016-10 -2.02 -4.41 4.15 0.02
2016-11 4.86 5.68 8.44 0.01
2016-12 1.81 -0.04 3.52 0.03
2017-01 1.94 -1.00 -2.69 0.04
2017-02 3.57 -1.79 -1.80 0.04

86 rows × 4 columns


In [85]:
mkt1['Mkt']=mkt1['Mkt-RF']+mkt1['RF']

3.2 | Joining the Key Data

Now we add market return column ("Mkt" in dataframe mkt1) to ind dataframe.

Then key statistics, including means and standard deviations, are calculated to further derive betas of different industries. Since such statistics will be used in our beta calculation, we store it to a new dataframe ind_stat.


In [86]:
# Adding mkt data to 30 industry data set
ind['Mkt']=mkt1['Mkt']

In [87]:
ind.tail()


Out[87]:
Food Beer Smoke Games Books Hshld Clths Hlth Chems Txtls ... Servs BusEq Paper Trans Whlsl Rtail Meals Fin Other Mkt
Date
2016-10 -0.22 -1.63 4.55 5.53 -10.29 -2.98 -5.74 -7.43 -1.93 -4.15 ... -0.48 -2.21 -5.47 -0.62 -8.15 -3.57 -1.90 1.37 -0.50 -2.00
2016-11 -4.45 -5.75 -5.06 3.88 8.72 -3.78 1.81 1.37 7.57 1.59 ... 0.08 2.36 4.22 12.76 9.27 3.00 8.46 12.02 8.26 4.87
2016-12 4.42 3.03 5.44 -3.23 1.26 1.57 -0.41 0.86 0.35 -1.24 ... -0.11 2.09 1.89 0.87 2.37 -0.95 0.64 3.77 2.58 1.84
2017-01 0.77 -0.98 5.58 4.94 2.23 2.61 0.03 2.21 3.83 6.95 ... 5.55 3.26 2.32 1.74 1.71 0.97 0.79 0.64 -0.81 1.98
2017-02 1.77 6.17 7.94 0.66 1.10 5.01 3.85 7.07 3.14 -2.08 ... 3.22 7.03 3.25 2.60 2.78 2.83 2.44 4.68 3.75 3.61

5 rows × 31 columns


In [88]:
# calculating historical average return and standard deviation
ind_stat=ind.describe()
ind_stat


Out[88]:
Food Beer Smoke Games Books Hshld Clths Hlth Chems Txtls ... Servs BusEq Paper Trans Whlsl Rtail Meals Fin Other Mkt
count 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 ... 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000 86.000000
mean 1.055814 1.234419 1.769419 1.694419 0.839186 0.887791 1.316047 1.248023 1.289767 1.775465 ... 1.211860 1.218953 1.195465 1.377674 1.187326 1.249884 1.415116 1.204070 1.259186 1.135233
std 3.049519 3.093921 4.730284 6.326911 5.499421 3.144038 5.245716 3.840663 5.718435 6.089188 ... 4.364645 4.963212 4.258059 4.652760 4.128541 3.806922 3.447848 4.954903 4.205391 3.770003
min -5.830000 -5.750000 -8.820000 -19.220000 -10.290000 -6.940000 -10.760000 -9.420000 -16.450000 -14.550000 ... -8.290000 -8.240000 -10.210000 -9.340000 -8.670000 -10.560000 -6.480000 -11.020000 -10.050000 -7.880000
25% -0.870000 -0.895000 -2.735000 -1.992500 -2.430000 -1.067500 -1.777500 -0.845000 -1.807500 -2.537500 ... -1.680000 -1.907500 -1.505000 -1.480000 -1.297500 -0.942500 -0.742500 -1.855000 -1.382500 -1.252500
50% 1.095000 1.040000 2.775000 1.770000 0.855000 0.975000 1.205000 1.440000 1.225000 2.050000 ... 1.045000 1.545000 1.900000 1.245000 1.645000 0.985000 1.460000 1.970000 1.290000 1.325000
75% 3.657500 3.470000 5.207500 5.717500 5.250000 3.217500 4.132500 3.647500 4.370000 5.625000 ... 3.567500 4.712500 3.525000 3.985000 3.612500 3.780000 3.757500 4.075000 3.645000 3.582500
max 6.560000 8.370000 11.120000 15.330000 12.910000 8.690000 17.540000 9.000000 18.210000 15.680000 ... 12.100000 13.480000 10.830000 15.280000 13.760000 13.590000 10.140000 13.430000 11.820000 11.350000

8 rows × 31 columns

4 | Beta Calculation

In order to facilitate matrix calculation, we altered the form of ind_stat to a inverse matrix and stored it as ind_stat_inv. By definition, industry betas are calculated as:

Beta = (covariance between market and an industry) / (variance of market)

Once we found industry betas, we created a new column "Beta" to our ind_stat_inv and sorted by beta in ascending order.


In [89]:
# inverse matrix
ind_stat_inv = pd.DataFrame(np.linalg.pinv(ind_stat.values), ind_stat.columns, ind_stat.index)
ind_stat_inv


Out[89]:
count mean std min 25% 50% 75% max
Food 0.003066 -0.190092 -0.099425 -0.005297 0.031880 -0.003946 0.119478 -0.001557
Beer 0.003109 0.080256 -0.036212 0.003230 -0.041608 -0.110700 0.002342 -0.003899
Smoke -0.002745 -0.005173 -0.098081 0.010678 -0.170987 0.220630 0.062432 -0.000807
Games -0.005237 0.082219 0.044579 -0.042517 0.142660 0.005999 0.073072 -0.025430
Books -0.002754 -0.170448 0.077162 0.035191 0.106827 -0.053044 0.192201 -0.004133
Hshld 0.005481 -0.212505 -0.176291 -0.016944 -0.011582 0.024886 0.063523 0.011324
Clths -0.001131 0.228893 0.156873 0.027005 -0.001781 -0.119093 -0.104524 -0.000033
Hlth 0.001536 -0.038620 0.044805 -0.015552 0.070336 0.017098 -0.021332 -0.017453
Chems -0.000172 0.067451 -0.011609 -0.030063 0.066029 -0.030811 -0.041460 0.002283
Txtls -0.005650 0.252605 0.121610 0.006250 -0.013366 -0.010123 -0.007140 -0.020291
Cnstr -0.000163 -0.330409 -0.268161 -0.028424 0.029554 0.183561 0.135689 0.047331
Steel 0.002742 0.523826 0.139463 -0.001725 -0.195451 -0.143862 -0.332858 -0.020853
FabPr -0.000294 -0.099268 -0.274283 -0.018338 -0.091124 0.094021 0.088957 0.045213
ElcEq -0.000350 -0.021089 0.163399 0.010160 0.103311 0.010595 -0.087745 -0.002930
Autos -0.004788 0.039412 0.132046 0.041265 0.097295 -0.107643 0.055696 0.022107
Carry -0.002012 0.088271 0.164574 0.011472 0.070139 -0.030754 -0.019032 -0.022632
Mines 0.001059 0.232688 -0.232239 -0.021242 -0.173084 -0.226871 0.109134 0.004537
Coal -0.000125 -0.348547 0.081083 -0.001417 0.084385 0.104198 0.040830 -0.009765
Oil 0.002936 -0.121629 -0.019752 0.017050 -0.076294 0.094919 -0.052686 0.011392
Util 0.003890 -0.186122 0.005105 -0.008084 0.068298 0.050676 -0.006891 -0.007557
Telcm 0.001675 0.202150 -0.000959 0.000750 -0.088140 -0.089317 -0.046928 -0.013136
Servs 0.001399 0.444627 0.230798 0.029952 -0.088878 -0.204184 -0.223105 -0.024950
BusEq -0.002740 -0.110370 0.099685 0.037943 0.053443 0.033869 0.091037 0.000480
Paper 0.002321 -0.070258 0.018085 -0.014825 -0.011630 0.152933 -0.098419 -0.010467
Trans -0.000368 0.208926 0.109162 0.020978 -0.015575 -0.116377 -0.079483 -0.000921
Whlsl 0.002025 -0.230423 -0.094579 -0.004114 0.014588 0.136233 0.028946 0.019354
Rtail 0.003230 -0.163293 -0.256194 -0.036313 0.028917 -0.023926 0.121442 0.026131
Meals 0.000890 -0.053163 -0.025110 0.003541 0.023698 -0.010898 0.050898 0.001996
Fin -0.000043 -0.147844 0.042014 -0.000329 0.027334 0.178970 -0.033559 -0.003061
Other 0.002046 0.162005 0.045054 -0.006505 -0.028924 -0.061627 -0.103471 -0.011308
Mkt 0.002794 -0.114078 -0.082603 -0.003776 -0.010271 0.034589 0.022955 0.009038

In [90]:
# beta calculation

def calc_beta(n):
    np_array = ind.values
    m = np_array[:,30] # market returns are column zero from numpy array
    s = np_array[:,n] # stock returns are column one from numpy array
    covariance = np.cov(s,m) # Calculate covariance between stock and market
    beta = covariance[0,1]/covariance[1,1]
    beta = covariance[0,1]/covariance[1,1]
    return beta

In [91]:
numlist=range(0,31,1)

In [92]:
beta=[calc_beta(i) for i in numlist]
beta


Out[92]:
[0.55916894058164057,
 0.4480120547381532,
 0.64000860244778091,
 1.2878834409809214,
 1.2430406211982077,
 0.58872829284028005,
 0.90026180666886013,
 0.79738353567566511,
 1.3619602564590942,
 1.2724172598468011,
 1.4206888986567519,
 1.637188084232104,
 1.4705301931278507,
 1.3209627971699354,
 1.5107128268891814,
 1.0552670733586162,
 1.2765590519568235,
 1.7408191863495055,
 1.1652674233319913,
 0.39375745557657971,
 0.86927877184406743,
 1.0516962111098531,
 1.1635736805926991,
 1.0511587366666271,
 1.0311431557530157,
 0.9858406071869521,
 0.85022960774196532,
 0.70446322524846272,
 1.197254954219817,
 0.9396045303169368,
 1.0]

In [93]:
# Adding beta result
ind_stat_inv['Beta']=beta
ind_stat_inv


Out[93]:
count mean std min 25% 50% 75% max Beta
Food 0.003066 -0.190092 -0.099425 -0.005297 0.031880 -0.003946 0.119478 -0.001557 0.559169
Beer 0.003109 0.080256 -0.036212 0.003230 -0.041608 -0.110700 0.002342 -0.003899 0.448012
Smoke -0.002745 -0.005173 -0.098081 0.010678 -0.170987 0.220630 0.062432 -0.000807 0.640009
Games -0.005237 0.082219 0.044579 -0.042517 0.142660 0.005999 0.073072 -0.025430 1.287883
Books -0.002754 -0.170448 0.077162 0.035191 0.106827 -0.053044 0.192201 -0.004133 1.243041
Hshld 0.005481 -0.212505 -0.176291 -0.016944 -0.011582 0.024886 0.063523 0.011324 0.588728
Clths -0.001131 0.228893 0.156873 0.027005 -0.001781 -0.119093 -0.104524 -0.000033 0.900262
Hlth 0.001536 -0.038620 0.044805 -0.015552 0.070336 0.017098 -0.021332 -0.017453 0.797384
Chems -0.000172 0.067451 -0.011609 -0.030063 0.066029 -0.030811 -0.041460 0.002283 1.361960
Txtls -0.005650 0.252605 0.121610 0.006250 -0.013366 -0.010123 -0.007140 -0.020291 1.272417
Cnstr -0.000163 -0.330409 -0.268161 -0.028424 0.029554 0.183561 0.135689 0.047331 1.420689
Steel 0.002742 0.523826 0.139463 -0.001725 -0.195451 -0.143862 -0.332858 -0.020853 1.637188
FabPr -0.000294 -0.099268 -0.274283 -0.018338 -0.091124 0.094021 0.088957 0.045213 1.470530
ElcEq -0.000350 -0.021089 0.163399 0.010160 0.103311 0.010595 -0.087745 -0.002930 1.320963
Autos -0.004788 0.039412 0.132046 0.041265 0.097295 -0.107643 0.055696 0.022107 1.510713
Carry -0.002012 0.088271 0.164574 0.011472 0.070139 -0.030754 -0.019032 -0.022632 1.055267
Mines 0.001059 0.232688 -0.232239 -0.021242 -0.173084 -0.226871 0.109134 0.004537 1.276559
Coal -0.000125 -0.348547 0.081083 -0.001417 0.084385 0.104198 0.040830 -0.009765 1.740819
Oil 0.002936 -0.121629 -0.019752 0.017050 -0.076294 0.094919 -0.052686 0.011392 1.165267
Util 0.003890 -0.186122 0.005105 -0.008084 0.068298 0.050676 -0.006891 -0.007557 0.393757
Telcm 0.001675 0.202150 -0.000959 0.000750 -0.088140 -0.089317 -0.046928 -0.013136 0.869279
Servs 0.001399 0.444627 0.230798 0.029952 -0.088878 -0.204184 -0.223105 -0.024950 1.051696
BusEq -0.002740 -0.110370 0.099685 0.037943 0.053443 0.033869 0.091037 0.000480 1.163574
Paper 0.002321 -0.070258 0.018085 -0.014825 -0.011630 0.152933 -0.098419 -0.010467 1.051159
Trans -0.000368 0.208926 0.109162 0.020978 -0.015575 -0.116377 -0.079483 -0.000921 1.031143
Whlsl 0.002025 -0.230423 -0.094579 -0.004114 0.014588 0.136233 0.028946 0.019354 0.985841
Rtail 0.003230 -0.163293 -0.256194 -0.036313 0.028917 -0.023926 0.121442 0.026131 0.850230
Meals 0.000890 -0.053163 -0.025110 0.003541 0.023698 -0.010898 0.050898 0.001996 0.704463
Fin -0.000043 -0.147844 0.042014 -0.000329 0.027334 0.178970 -0.033559 -0.003061 1.197255
Other 0.002046 0.162005 0.045054 -0.006505 -0.028924 -0.061627 -0.103471 -0.011308 0.939605
Mkt 0.002794 -0.114078 -0.082603 -0.003776 -0.010271 0.034589 0.022955 0.009038 1.000000

In [94]:
sort=ind_stat_inv = ind_stat_inv.sort_values(by='Beta', ascending=False)
sort


Out[94]:
count mean std min 25% 50% 75% max Beta
Coal -0.000125 -0.348547 0.081083 -0.001417 0.084385 0.104198 0.040830 -0.009765 1.740819
Steel 0.002742 0.523826 0.139463 -0.001725 -0.195451 -0.143862 -0.332858 -0.020853 1.637188
Autos -0.004788 0.039412 0.132046 0.041265 0.097295 -0.107643 0.055696 0.022107 1.510713
FabPr -0.000294 -0.099268 -0.274283 -0.018338 -0.091124 0.094021 0.088957 0.045213 1.470530
Cnstr -0.000163 -0.330409 -0.268161 -0.028424 0.029554 0.183561 0.135689 0.047331 1.420689
Chems -0.000172 0.067451 -0.011609 -0.030063 0.066029 -0.030811 -0.041460 0.002283 1.361960
ElcEq -0.000350 -0.021089 0.163399 0.010160 0.103311 0.010595 -0.087745 -0.002930 1.320963
Games -0.005237 0.082219 0.044579 -0.042517 0.142660 0.005999 0.073072 -0.025430 1.287883
Mines 0.001059 0.232688 -0.232239 -0.021242 -0.173084 -0.226871 0.109134 0.004537 1.276559
Txtls -0.005650 0.252605 0.121610 0.006250 -0.013366 -0.010123 -0.007140 -0.020291 1.272417
Books -0.002754 -0.170448 0.077162 0.035191 0.106827 -0.053044 0.192201 -0.004133 1.243041
Fin -0.000043 -0.147844 0.042014 -0.000329 0.027334 0.178970 -0.033559 -0.003061 1.197255
Oil 0.002936 -0.121629 -0.019752 0.017050 -0.076294 0.094919 -0.052686 0.011392 1.165267
BusEq -0.002740 -0.110370 0.099685 0.037943 0.053443 0.033869 0.091037 0.000480 1.163574
Carry -0.002012 0.088271 0.164574 0.011472 0.070139 -0.030754 -0.019032 -0.022632 1.055267
Servs 0.001399 0.444627 0.230798 0.029952 -0.088878 -0.204184 -0.223105 -0.024950 1.051696
Paper 0.002321 -0.070258 0.018085 -0.014825 -0.011630 0.152933 -0.098419 -0.010467 1.051159
Trans -0.000368 0.208926 0.109162 0.020978 -0.015575 -0.116377 -0.079483 -0.000921 1.031143
Mkt 0.002794 -0.114078 -0.082603 -0.003776 -0.010271 0.034589 0.022955 0.009038 1.000000
Whlsl 0.002025 -0.230423 -0.094579 -0.004114 0.014588 0.136233 0.028946 0.019354 0.985841
Other 0.002046 0.162005 0.045054 -0.006505 -0.028924 -0.061627 -0.103471 -0.011308 0.939605
Clths -0.001131 0.228893 0.156873 0.027005 -0.001781 -0.119093 -0.104524 -0.000033 0.900262
Telcm 0.001675 0.202150 -0.000959 0.000750 -0.088140 -0.089317 -0.046928 -0.013136 0.869279
Rtail 0.003230 -0.163293 -0.256194 -0.036313 0.028917 -0.023926 0.121442 0.026131 0.850230
Hlth 0.001536 -0.038620 0.044805 -0.015552 0.070336 0.017098 -0.021332 -0.017453 0.797384
Meals 0.000890 -0.053163 -0.025110 0.003541 0.023698 -0.010898 0.050898 0.001996 0.704463
Smoke -0.002745 -0.005173 -0.098081 0.010678 -0.170987 0.220630 0.062432 -0.000807 0.640009
Hshld 0.005481 -0.212505 -0.176291 -0.016944 -0.011582 0.024886 0.063523 0.011324 0.588728
Food 0.003066 -0.190092 -0.099425 -0.005297 0.031880 -0.003946 0.119478 -0.001557 0.559169
Beer 0.003109 0.080256 -0.036212 0.003230 -0.041608 -0.110700 0.002342 -0.003899 0.448012
Util 0.003890 -0.186122 0.005105 -0.008084 0.068298 0.050676 -0.006891 -0.007557 0.393757

5 | Creating Visual Output

We created four visual presentations to help better understand how different betas can be shown in a given timeframe.


In [95]:
#Transpose industry returns table to make heatmap
ind_heatmap = ind.T
ind_heatmap.tail()


Out[95]:
Date 2010-01 2010-02 2010-03 2010-04 2010-05 2010-06 2010-07 2010-08 2010-09 2010-10 ... 2016-05 2016-06 2016-07 2016-08 2016-09 2016-10 2016-11 2016-12 2017-01 2017-02
Rtail -1.92 4.32 6.14 1.85 -5.83 -10.56 4.65 -4.18 13.59 1.32 ... 1.20 0.73 3.80 -1.67 -0.16 -3.57 3.00 -0.95 0.97 2.83
Meals -0.99 4.56 8.40 7.36 -4.88 -5.29 7.04 0.38 7.13 6.06 ... -1.47 1.18 2.20 -0.22 -2.26 -1.90 8.46 0.64 0.79 2.44
Fin -1.18 2.70 8.14 0.95 -9.12 -7.31 6.62 -8.38 7.46 1.97 ... 2.17 -4.86 3.91 4.65 -1.34 1.37 12.02 3.77 0.64 4.68
Other 2.24 1.87 9.07 3.86 -10.05 -7.58 8.03 -7.12 10.01 -0.11 ... -2.01 3.63 -0.23 2.24 -3.52 -0.50 8.26 2.58 -0.81 3.75
Mkt -3.36 3.40 6.32 2.01 -7.88 -5.55 6.94 -4.76 9.55 3.89 ... 1.79 -0.03 3.97 0.52 0.27 -2.00 4.87 1.84 1.98 3.61

5 rows × 86 columns


In [96]:
#heatmap of monthly returns since 2010 
import seaborn as sns
sns.set()
fig, ax = plt.subplots(figsize=(20,8)) 
sns.heatmap(ind_heatmap, annot=False, linewidths=.5)
ax.set_title("Monthly Returns by Industry (10 Years)")


Out[96]:
<matplotlib.text.Text at 0xa81c080>

On the heatmap of monthly returns by industry, we can see which industries have more extreme swings, and which have less variation. 'Coal' looks to be particularly volatile. 'Food' and 'Utilities' looks more stable.


In [97]:
#Sort a beta-only table to create beta bar chart 
beta_table = sort[['Beta']]
beta_table.head()


Out[97]:
Beta
Coal 1.740819
Steel 1.637188
Autos 1.510713
FabPr 1.470530
Cnstr 1.420689

In [98]:
#Bar chart of betas sorted from high to low
plt.style.use('seaborn-pastel')

ax = beta_table.plot(kind='bar', colormap = "Pastel2")
ax.set_title("Betas Across Industries")


Out[98]:
<matplotlib.text.Text at 0xa8619b0>

Sure enough, 'Coal' had the highest beta value (beta > 1 means that returns are more volatile than market returns), and 'Utilities' had the lowest beta


In [99]:
#Creating a dataframe just to see the most extreme values from the beta bar chart
industry_set = ind[['Coal ','Util ','Mkt']]
industry_set = industry_set.rename(columns={'Coal ':'Coal','Util ':'Utilities','Mkt':'Market'})
industry_set.tail()


Out[99]:
Coal Utilities Market
Date
2016-10 -8.67 -0.61 -2.00
2016-11 20.79 -2.84 4.87
2016-12 -9.65 3.64 1.84
2017-01 -5.32 1.09 1.98
2017-02 -9.39 4.02 3.61

In [100]:
#Line plot of the returns of Coal, Utilities, and the general market
import seaborn as sns
plt.style.use('seaborn-pastel')

ax = industry_set.plot(linestyle='-', colormap = "Accent", figsize = (16,5))
ax.set_title("Monthly Returns over 10 Years")


Out[100]:
<matplotlib.text.Text at 0xd693128>

By plotting 'Coal' and 'Utilities' returns against the market's returns, we can verify the amplitude each's returns... although the chart is a little hectic


In [101]:
#Calculating a new dataframe to look at excess returns
industry_diff = industry_set
industry_diff['Coal Excess Returns'] = industry_set['Coal'] - industry_set['Market']
industry_diff['Utilities Excess Returns'] = industry_set['Utilities'] - industry_set['Market']
industry_diff = industry_diff.drop(industry_diff.columns[[0,1,2]], 1)
industry_diff.tail()


Out[101]:
Coal Excess Returns Utilities Excess Returns
Date
2016-10 -6.67 1.39
2016-11 15.92 -7.71
2016-12 -11.49 1.80
2017-01 -7.30 -0.89
2017-02 -13.00 0.41

In [102]:
#Line plot of the excess returns
plt.style.use('seaborn-pastel')

ax = industry_diff.plot(linestyle='-', colormap = "Accent", figsize = (16,5))
ax.set_title("Market Excess Returns")


Out[102]:
<matplotlib.text.Text at 0xd9d8a90>

By comparing the excess returns (positive or negative) of each against the market, we get a clearer view of the stability of the Utilities industry's returns vs the volatility of the Coal industry's returns