Betting Against Beta in the S&P 500

Silverio J. Vasquez
December 12, 2017

Betting Against Beta Project

Buy low-beta (< 1) stocks and sell short high-beta (> 1) stocks in the S&P 500. Inspired by paper from Andrea Frazzini and Lasse H. Pedersen titled “Betting Against Beta”

  • Source current and historical stock names in the S&P 500 index from Wikipedia
  • Download daily stock prices from Yahoo Finance via quantmod package and Quandl.com
  • Risk-free rate from a CSV file stored on my GitHub but originally from Fama and French's website
  • Calculate beta by regressing S&P 500 returns on stock returns
  • Save prices and betas to SQLite database
  • Backtest strategy and show results

Packages Used

  • zoo/xts
  • dplyr/tidyr
  • curl
  • readr
  • stringr
  • data.table
  • rvest
  • statar (to winsorize data)
  • RSQLite
  • PerformanceAnalytics
  • ggplot2
  • Quantmod

Data

Data was sourced from:

  • Scraped current and historical stock names in the S&P 500 index from Wikipedia using rvest package
  • Current stock prices from Yahoo Finance via quantmod package
  • Historical stock prices from Quandl.com. This required downloading a 1.7gbs file (took a few seconds, read_csv crashed RStudio every time), reading it into RStudio efficiently via data.table, subsetting only desired stocks, and converting data format from long to wide
  • Risk-free rate from a CSV file stored on my GitHub but originally from Fama and French's website

Beta

Beta was calculated on a rolling 2-year basis using CAPM and Blume's beta adjustment:

CAPM Formula

\[ \scriptstyle Return = Riskfree Rate + \beta * (Market Return - Riskfree Rate) \]

CAPM Rearranged

\[ \scriptstyle (Return - Riskfree Rate) = \beta * (Market Return - Riskfree Rate) \]

Blume's Beta Adjustment

\[ \small \bar\beta = \frac{2}{3} * \beta + \frac{1}{3} * 1 \]

Construct Portfolios

Two dataframes representing two portfolios:

  • Long portfolio has betas less than 1
  • Short portfolio has betas higher than 1
  • Ranked betas from highest difference from 1 and selected top 30% from each portfolio
  • Initially, the portfolio was rebalanced (i.e., stocks were bought, sold, and weights recalculated) on a weekly basis. Whole process was then converted into a function where user can select rebalancing period (e.g., weekly, monthly, quarterly, or annually).

Results - Weekly

Rebalancing on a weekly basis resulted in the following performance:

plot of chunk unnamed-chunk-1

Results - Monthly

Rebalancing on a monthly basis resulted in the following performance:

plot of chunk unnamed-chunk-2

Results - Quarterly

Rebalancing on a quarterly basis resulted in the following performance:

plot of chunk unnamed-chunk-3

Results - Annually

Rebalancing on an annual basis resulted in the following performance:

plot of chunk unnamed-chunk-4

Conclusion

Clearly the only time this strategy made money was when rebalancing was done on an annual basis. This differs from the results of the authors where they found this strategy to make money more often than not.

Reasons for differences are due to my limited dataset and computational power of R (authors used daily timeseries to calculate betas, while I did it on a weekly basis - this takes 30-60mins).