Calculating rolling Beta

923 Views Asked by At

I'm trying to generate rolling betas for stocks and my rolling function is not working. What I have tried so far:

library(tidyquant)
library(tidyverse)
library(tibbletime)

ticker_data <- tq_get(c("AAPL", "SPY"))


daily_returns <- ticker_data %>% 
  group_by(symbol) %>%
  tq_transmute(select     = close, 
               mutate_fun = periodReturn, 
               period     = "daily", 
               col_rename = "daily_return") %>% 
  ungroup
  
all_returns_df <- left_join(daily_returns %>% filter(symbol == "AAPL"),
          daily_returns %>% filter(symbol == "SPY") %>% 
            select(-symbol) %>% 
            rename(mkt_daily_return = daily_return))



# Can generate one Beta for all dates
all_returns_df %>% 
  tq_performance(Ra = daily_return,
                 Rb = mkt_daily_return, 
                 scale = 252,
                 performance_fun = table.CAPM)


# Rolling Beta is not working

#Function that is not working
roll_beta <- rollify(.f = function(xy){ tq_performance(data = xy,
                                                       Ra = daily_return,
                                                       Rb = mkt_daily_return, 
                                                       scale = 252,
                                                       performance_fun = table.CAPM)},
                     window = 40)

# This fails
all_returns_df %>% roll_beta()

Any ideas on how to make this work for me?

My main aim is to do this in a "tidy" way.

1

There are 1 best solutions below

3
On

Note: tibbletime has been retired. You should look into timetk.

Now timetk has the slidify instead of rollify function. But I couldn't get it to work correctly as it keeps complaining about the period. But going back to zoo::rollapply does the trick. Also getting the whole table is for also an issue for some reason.

The code below will work for the example given and return the beta's. I'm using the function CAPM.beta to return the beta's.

CAPM_beta_roll <- function(data, width = 40) {
  data <- timetk::tk_xts(data, date_var = date)
  beta <- zoo::rollapply(data = data[, 1], 
                         FUN = CAPM.beta, 
                         Rb = data[, 2], 
                         width = width, 
                         by = 1, 
                         align = "right",
                         by.column = TRUE) 
  names(beta) <- "beta"
  out <- timetk::tk_tbl(beta, preserve_index = FALSE)
  out$beta
}

all_returns_df %>%
  mutate(beta = CAPM_beta_roll(.))

# A tibble: 2,680 x 5
   symbol date       daily_return mkt_daily_return  beta
   <chr>  <date>            <dbl>            <dbl> <dbl>
 1 AAPL   2011-01-03     0                0           NA
 2 AAPL   2011-01-04     0.00522         -0.000551    NA
 3 AAPL   2011-01-05     0.00818          0.00520     NA
 4 AAPL   2011-01-06    -0.000808        -0.00196     NA
 5 AAPL   2011-01-07     0.00716         -0.00196     NA
 6 AAPL   2011-01-10     0.0188          -0.00126     NA
 7 AAPL   2011-01-11    -0.00237          0.00354     NA
 8 AAPL   2011-01-12     0.00814          0.00902     NA
 9 AAPL   2011-01-13     0.00366         -0.00163     NA
10 AAPL   2011-01-14     0.00810          0.00724     NA
# ... with 2,670 more rows
Warning message:
Problem with `mutate()` column `beta`.
i `beta = CAPM.beta_roll(.)`.
i Non-numeric columns being dropped: symbol, date 

You can ignore the warning messages. These come from time_tk::tk_xts

For faster implementations of the function you can find several examples in this SO post.