14 Fama-MacBeth Regressions

Part 1: CAPM Review

Last class, we learned about the Capital Asset Pricing Model (CAPM). In short, it says:

  • People are generally risk-averse.
  • Therefore, investors demand compensation for bearing risk.
  • You can measure how risky an asset (stock) is by running the CAPM regression ret_a - rf ~ ret_m - rf, where:
    • ret_a is the return for stock A
    • ret_m is the return for the market overall (or the S&P 500 return)
    • rf is the risk-free rate (the return on a very safe asset like a US Treasury bill)
  • We subtract rf from both ret_a and ret_m to measure excess returns: how much extra return the stock and the market earned beyond what an investor could have earned from a risk-free investment.
  • The CAPM regression yields estimates for the intercept and the slope of the line of best fit. The intercept is called “alpha” and the slope is called “beta”.
  • If a stock’s beta is 1.3, that means when the market goes up by 1%, that stock generally goes up by 1.3%. And when the market goes down by 1%, that stock can be expected to go down by 1.3%. A beta of more than 1 indicates the stock is riskier than the market. And a beta of less than 1 indicates the stock is less risky than the market.
  • Under CAPM, alpha should always be zero. If it isn’t, that indicates that the stock tends to earn returns in excess of the market, controlling for how risky it is. That means one of two things is happening:
    • 1: investors have a profit opportunity: they should rush to buy this stock, which will make its price rise, and the future expected return fall. Alpha comes back to 0.
    • or 2: there are more types of risk than just market-level risk. The stock may be exposed to technology-sector risk, oil price risk, interest rate risk, etc. CAPM doesn’t help us account for these, and if we leave them out, they can create omitted variable bias: neither alpha nor beta are being measured correctly.

Today, we’ll work with Fama-MacBeth Regressions, which extend CAPM by asking whether riskier stocks actually earn higher returns across the market.

CAPM Review Questions

1.1) Suppose a stock has a beta of 1.8. If the market increases by 1% this month, what would CAPM predict happens to this stock’s return (assume the risk-free rate is 0)? What does this beta tell you about the stock’s risk relative to the market?

1.2) Why do we subtract the risk-free rate (rf) from both the stock return and the market return in the CAPM regression?

1.3) Suppose a stock has a beta of 1.8. If the market increases by 2% and the risk-free rate is 1%, what should we expect happens to the stock?

1.4) In the CAPM regression, what does the intercept (alpha) measure? What does the slope (beta) measure?

1.5) What are two possible explanations for a positive alpha?

Part 2: The Fama-MacBeth Big Idea

The CAPM predicts that stocks with higher betas should earn higher average returns. For example:

# 2.1) Apple's beta is ____.

joined_data %>%
  filter(permno == 14593) %>%
  lm(ret - rf_return ~ I(sp500_ret - rf_return), data = .) %>%
  broom::tidy()


# 2.2) Apple is (choose one: riskier/safer) than the market in
# general. It also earns a (choose one: higher/lower) return on
# average than the S&P500. This is consistent with CAPM, because
# CAPM says that riskier stocks should earn higher average returns.
# But it also is not consistent with CAPM because we can reject
# the null hypothesis that alpha is 0. Even controlling for how
# risky Apple is, it earns a higher return.

joined_data %>%
  filter(permno == 14593) %>%
  summarize(apple = mean(ret), sp500 = mean(sp500_ret))
# A tibble: 2 × 5
  term                     estimate std.error statistic  p.value
  <chr>                       <dbl>     <dbl>     <dbl>    <dbl>
1 (Intercept)                0.0168   0.00537      3.13 1.91e- 3
2 I(sp500_ret - rf_return)   1.34     0.117       11.5  1.30e-25
# A tibble: 1 × 2
   apple   sp500
   <dbl>   <dbl>
1 0.0259 0.00695

2.3) Fama-MacBeth asks the question: in general, does a higher beta predict a higher return? Write down the linear regression you could use to answer this question. How could you interpret the intercept and the slope of that model?

Part 3: Fama-MacBeth in Practice

Fama-MacBeth regressions are estimated in 2 steps:

  1. Time Series Regressions: Estimate each stock’s CAPM beta
  2. Cross-Sectional Regressions: For one time period at a time, run the linear regression you identified in 2.3 to ask: in general, does a higher CAPM beta predict higher returns?

3.1) Explain how the code below does step 1 of the Fama-MacBeth procedure:

  • What do we give map() for the .x, and why?
  • In map’s .f, what does the function take, what does it do, and what does it return?
# Step 1: estimate each stock's beta
betas <- map(
  .x = joined_data %>% count(permno) %>% filter(n >= 50) %>% pull(permno) %>% unique(),
  .f = function(p) {
    joined_data %>%
      filter(permno == p) %>%
      lm(ret - rf_return ~ I(sp500_ret - rf_return), data = .) %>%
      broom::tidy() %>%
      select(beta = estimate) %>%
      slice(2) %>%
      mutate(permno = p)
  }
) %>%
  bind_rows()

betas
# A tibble: 13,468 × 2
      beta permno
     <dbl>  <dbl>
 1  0.120   10001
 2 -0.0621  10002
 3  2.74    10012
 4  0.811   10025
 5  0.591   10026
 6  0.753   10028
 7  1.58    10032
 8  0.344   10037
 9  0.422   10042
10  0.718   10044
# ℹ 13,458 more rows
# add beta to joined_data:
joined_data <- joined_data %>%
  left_join(betas, join_by(permno))

joined_data
# A tibble: 2,284,479 × 7
   permno date           ret comnam          sp500_ret rf_return  beta
    <dbl> <date>       <dbl> <chr>               <dbl>     <dbl> <dbl>
 1  10001 2000-02-01 -0.0441 ENERGY WEST INC   -0.0396   0.00451 0.120
 2  10001 2000-03-01  0.0154 ENERGY WEST INC    0.0318   0.00462 0.120
 3  10001 2000-04-01 -0.0158 ENERGY WEST INC    0.0535   0.00460 0.120
 4  10001 2000-05-01  0.0117 ENERGY WEST INC   -0.0595   0.00470 0.120
 5  10001 2000-06-01 -0.0232 ENERGY WEST INC   -0.0389   0.00462 0.120
 6  10001 2000-07-01  0.0277 ENERGY WEST INC    0.0516   0.00484 0.120
 7  10001 2000-08-01 -0.0156 ENERGY WEST INC   -0.0177   0.00494 0.120
 8  10001 2000-09-01  0.0476 ENERGY WEST INC    0.0750   0.00487 0.120
 9  10001 2000-10-01  0.0758 ENERGY WEST INC   -0.0512   0.00495 0.120
10  10001 2000-11-01  0.0286 ENERGY WEST INC   -0.0245   0.00500 0.120
# ℹ 2,284,469 more rows

3.2) Fill in the blanks to complete Step 2 of the Fama-MacBeth procedure.

# Step 2: Use a regression to answer: does a higher 
# beta predict higher returns?
# We'll run this regression cross-sectionally (for each
# time period separately, and then take the average).

fama_macbeth <- map(
  .x = seq.Date(from = ymd(20000201), to = ymd(20241201), by = "month"),
  .f = function(________) {
    joined_data %>%
      filter(date == t) %>%
      lm(________ - rf_return ~ ________, data = .) %>%
      broom::tidy() %>%
      select(risk_premium = estimate) %>%
      slice(2)
  }
) %>%
  bind_rows()

fama_macbeth
# A tibble: 299 × 1
   risk_premium
          <dbl>
 1       0.0364
 2       0.190 
 3      -0.0208
 4      -0.0922
 5      -0.0649
 6       0.109 
 7      -0.0426
 8       0.0559
 9      -0.0572
10      -0.0518
# ℹ 289 more rows
fama_macbeth %>%
  summarize(
    risk_premium_estimate = mean(risk_premium), 
    t_statistic = mean(risk_premium) / (sd(risk_premium) / sqrt(n()))
    )
# A tibble: 1 × 2
  risk_premium_estimate t_statistic
                  <dbl>       <dbl>
1               0.00352        1.17

3.3) Compare the t-statistic to 1.96. If we get a large positive t-statistic, that would imply higher-beta stocks tend to earn higher returns. If we get a t-statistic near 0, there’s little evidence beta predicts returns: if omitted variable bias in CAPM gives us betas with a lot of measurement error, that will bias our Fama-MacBeth risk premium measurement toward 0. What’s our interpretation in this case?