Is it possible to group by company when computing different technical indicators from the TTR package in R?

83 Views Asked by At

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!

1

There are 1 best solutions below

10
On BEST ANSWER

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)))

Update

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

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))