library(tidyverse)
library(tidyquant)
library(tidyr)
library(timetk)
FB <- FANG %>% filter(symbol == "FB")
# --- ROLLING MEAN (SINGLE ARG EXAMPLE) ---
# Turn the normal mean function into a rolling mean with a 5 row .period
mean_roll_5 <- slidify(mean, .period = 5, .align = "right")
FB %>%
mutate(rolling_mean_5 = mean_roll_5(adjusted))
# Use `partial = TRUE` to allow partial windows (those with less than the full .period)
mean_roll_5_partial <- slidify(mean, .period = 5, .align = "right", .partial = TRUE)
FB %>%
mutate(rolling_mean_5 = mean_roll_5_partial(adjusted))
# There's nothing stopping you from combining multiple rolling functions with
# different .period sizes in the same mutate call
mean_roll_10 <- slidify(mean, .period = 10, .align = "right")
FB %>%
select(symbol, date, adjusted) %>%
mutate(
rolling_mean_5 = mean_roll_5(adjusted),
rolling_mean_10 = mean_roll_10(adjusted)
)
# For summary operations like rolling means, we can accomplish large-scale
# multi-rolls with tk_augment_slidify()
FB %>%
select(symbol, date, adjusted) %>%
tk_augment_slidify(
adjusted, .period = 5:10, .f = mean, .align = "right",
.names = str_c("MA_", 5:10)
)
# --- GROUPS AND ROLLING ----
# One of the most powerful things about this is that it works with
# groups since `mutate` is being used
data(FANG)
mean_roll_3 <- slidify(mean, .period = 3, .align = "right")
FANG %>%
group_by(symbol) %>%
mutate(mean_roll = mean_roll_3(adjusted)) %>%
slice(1:5)
# --- ROLLING CORRELATION (MULTIPLE ARG EXAMPLE) ---
# With 2 args, use the purrr syntax of ~ and .x, .y
# Rolling correlation example
cor_roll <- slidify(~cor(.x, .y), .period = 5, .align = "right")
FB %>%
mutate(running_cor = cor_roll(adjusted, open))
# With >2 args, create an anonymous function with >2 args or use
# the purrr convention of ..1, ..2, ..3 to refer to the arguments
avg_of_avgs <- slidify(
function(x, y, z) (mean(x) + mean(y) + mean(z)) / 3,
.period = 10,
.align = "right"
)
# Or
avg_of_avgs <- slidify(
~(mean(..1) + mean(..2) + mean(..3)) / 3,
.period = 10,
.align = "right"
)
FB %>%
mutate(avg_of_avgs = avg_of_avgs(open, high, low))
# Optional arguments MUST be passed at the creation of the rolling function
# Only data arguments that are "rolled over" are allowed when calling the
# rolling version of the function
FB$adjusted[1] <- NA
roll_mean_na_rm <- slidify(~mean(.x, na.rm = TRUE), .period = 5, .align = "right")
FB %>%
mutate(roll_mean = roll_mean_na_rm(adjusted))
# --- ROLLING REGRESSIONS ----
# Rolling regressions are easy to implement using `.unlist = FALSE`
lm_roll <- slidify(~lm(.x ~ .y), .period = 90, .unlist = FALSE, .align = "right")
FB %>%
drop_na() %>%
mutate(numeric_date = as.numeric(date)) %>%
mutate(rolling_lm = lm_roll(adjusted, numeric_date)) %>%
filter(!is.na(rolling_lm))
Run the code above in your browser using DataLab