rgrouptechnical-indicatorttr

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


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!


Solution

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