I am trying to compute various technical indicators that will be used to predict the stock price movement of around 100 stocks. For example, I want to calculate the Average True Range (ATR) for each of the companies in my time series, which I am trying to do with the TTR package in R. However, the problem is that I can't figure out how to do it for each of the companies in my dataset. I have tried to use dplyr::group_by(company) which doesn't work.
data_ATR <- data_price %>%
dplyr::group_by(company) %>%
TTR::ATR(data_price[,c("PRICE HIGH", "PRICE LOW", "CLOSING PRICE")], n=14)
Any help would be greatly appreciated!
We may use group_modify
here
library(dplyr)
data_price %>%
dplyr::group_by(company) %>%
dplyr::group_modify(~ as.data.frame(TTR::ATR(.[,c("PRICE HIGH",
"PRICE LOW", "CLOSING PRICE")], n=14)))
If there are NAs we may need to get the index of the first non-NA row among all the subset of columns
data_price %>%
dplyr::group_by(company) %>%
dplyr::group_modify(~
{
tmp <- .x[,c("PRICE HIGH", "PRICE LOW", "CLOSING PRICE")]
i1 <- which(rowSums(!is.na(tmp)) == ncol(tmp))[1]
tmp <- tmp[i1:nrow(tmp), ]
tryCatch(as.data.frame(TTR::ATR(tmp, n= min(c(nrow(tmp)-1,
14)))), error = function(e) data.frame(tr = NA_real_))
})
Using a reproducible example
library(TTR)
data(ttrc)
ttrc %>%
mutate(company = as.integer(gl(n(), 25, n()))) %>%
group_by(company) %>%
group_modify(~ as.data.frame(ATR(.[c("High", "Low", "Volume")], n = 14))) %>%
ungroup
# A tibble: 5,550 × 5
company tr atr trueHigh trueLow
<int> <dbl> <dbl> <dbl> <dbl>
1 1 NA NA NA NA
2 1 1870903. NA 1870906 3.09
3 1 3099503. NA 3099506 3.08
4 1 2274154. NA 2274157 3.07
5 1 2086755. NA 2086758 3.08
6 1 2166345. NA 2166348 3.1
7 1 3441795. NA 3441798 3.14
8 1 7550745. NA 7550748 3.2
9 1 4853309. NA 4853312 3.22
10 1 5814822. NA 5814825 3.28
# … with 5,540 more rows
data_price <- structure(list(company = c("1", "1", "1", "1", "1", "1", "1",
"1", "1", "2", "2", "2", "2"), `PRICE HIGH` = c(NA, NA, NA, 2,
3, 5, 10, 15, 12, NA, NA, NA, 2), `PRICE LOW` = c(NA, NA, 2,
3, 4, 7, 11, 4, 5, NA, NA, 2, 3), `CLOSING PRICE` = c(NA, NA,
5, 6, 9, 10, 15, 12, 15, NA, NA, 5, 6)), class = "data.frame", row.names = c(NA,
-13L))