Search code examples
rfunctionxts

Add an ROC column to multiple xts files in r


I have several xts object with stock market data. I am trying to add the Rate of Change (ROC) from the TTR package, but want to write a function to do that.

It works the "verbose" way, but somehow the function does not do the trick:

#Loading the data
library(xts)
library(quantmod)
library(ggplot2)
library(tidyquant)
library(Hmisc)
library(PerformanceAnalytics)
library(TTR)

StartDate <- "2017-01-01"

# Get data from yahoo finance

symbolsYahoo <- c("^FTSE", "^GDAXI")

loadSymbols(Symbols = symbolsYahoo, from = StartDate, periodicity = "daily" )


#verbose way
GDAXI$GDAXI.ROC <- na.locf(ROC(Cl(GDAXI)))

#function
rocFun <- function(x){
  x <- merge(x, na.locf(ROC(Cl(x))))
}

rocFun(GDAXI)

I have tried several other ways of writing that function but none add the column. Can you help?


Solution

  • Without knowing much about xts objects, here's a hacky way of doing this. I'm sure there are more elegant ways to achieve this:

    library(xts)
    
    GDAXI <- sample.xts
    
    func1 <- function(df){
      k <- as.data.frame(z)
      k$ROC <- ROC(k$Close)
      return(k)
    }
    
    func2 <- function(xts_object, col = 4){
      names_initial <- names(xts_object)
      k <- ROC(xts_object[, col])
      ret <- merge(xts_object, k)
      names_new <- c(names_initial, 'ROC')
      names(ret) <- names_new
      return(ret)
    }
    

    func1 converts the xts object to a data.frame and adds a column, whereas func2 uses merge to add an ROC column without changing the class. The output is below:

    > str(func1(GDAXI))
    'data.frame':   180 obs. of  5 variables:
     $ Open : num  50 50.2 50.4 50.4 50.2 ...
     $ High : num  50.1 50.4 50.4 50.4 50.2 ...
     $ Low  : num  50 50.2 50.3 50.2 50.1 ...
     $ Close: num  50.1 50.4 50.3 50.3 50.2 ...
     $ ROC  : num  NA 5.57e-03 -1.30e-03 4.45e-05 -3.05e-03 ...
    
    > str(func2(GDAXI))
    An ‘xts’ object on 2007-01-02/2007-06-30 containing:
      Data: num [1:180, 1:5] 50 50.2 50.4 50.4 50.2 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:5] "Open" "High" "Low" "Close" ...
      Indexed by objects of class: [POSIXct,POSIXt] TZ: 
      xts Attributes:  
    List of 1
     $ descr: chr "my new xts object"
    
    > head(func2(GDAXI))
                   Open     High      Low    Close           ROC
    2007-01-02 50.03978 50.11778 49.95041 50.11778            NA
    2007-01-03 50.23050 50.42188 50.23050 50.39767  5.569091e-03
    2007-01-04 50.42096 50.42096 50.26414 50.33236 -1.296719e-03
    2007-01-05 50.37347 50.37347 50.22103 50.33459  4.445937e-05
    2007-01-06 50.24433 50.24433 50.11121 50.18112 -3.053731e-03
    2007-01-07 50.13211 50.21561 49.99185 49.99185 -3.778799e-03
    

    You could loop through the vector of your stock names using lapply('GDAXI', function(z){...}) instead of passing individual xts objects.