Search code examples
rdataframextslapplyquantmod

Add a column with Ticker after converting zoo to dataframe


I am trying to add a column after I had converted a xts to a dataframe as xts can only include numeric values. Additional I want to bind them by row as a final result, but I fail and don´t find the solution. Here is my code which is collected from different authors on stackoverflow. Thanks to that!

library(quantmod)

# Fetch all Symbols from AMEX
symbols <- stockSymbols(exchange = c("AMEX"))  
symbols <- symbols[,1]  

# define environment
data <- new.env()

# Load Stock data in environment
getSymbols(symbols,from="2016-01-01", env=data)

# build function to convert zoo to dataframe
zoo.to.data.frame <- function(x, index.name="Date") {
     stopifnot(is.zoo(x))
     xn <- if(is.null(dim(x))) deparse(substitute(x)) else colnames(x)
     setNames(data.frame(index(x), x, row.names=NULL), c(index.name,xn))
}

# build function to calculate different signals (...only price and ADX in this example)
"SignalCalculator" <- function(x) {
      # Adjusted Price
       price <- x[,c(6)]

      # ADX
      adx <- ADX(x[,c("High","Low","Close")], n =14)
      DIp <- adx$DIp
      DIn <- adx$DIn
      Adx <- adx$ADX

      # bind single values together and convert to dataframe
      result  <- zoo.to.data.frame(cbind(price, DIp, DIn, Adx))
      # the following is not working respectively I don´t know how to
      # result2 <- cbind(result, Ticker = x) 
}

# Loop function on data #
lapply(data,FUN = SignalCalculator)

What I would like to do after the function is applied to all the ticker, is to generate one huge dataframe with a row bind, with all the tickers inside to export them to a csv file. This should look like the following. But for me it is unclear how to bind them together? I appreciate any help on this topic. Thanks.

Table with stock data


Solution

  • out2 below is in the format of the table in the link you provided. You can make use of helper functions from xts, like HLC and Ad which are more flexible than hard coding your column selections, and you don't need to do that zoo.to.data.frame stuff.

    # define environment
    data <- new.env()
    
    # Load Stock data in environment
    getSymbols(symbols,from="2016-01-01", env=data)
    
    SignalCalculator2 <- function(x) {
        # Assumes first colname format is still [tickername].Open
        tickername <- strsplit(colnames(x)[1], "\\.")[[1]][1]
        # Adjusted Price:
        price <- Ad(x)
        colnames(price) <- "Price"
        adx <- ADX(HLC(x), n = 14)
        # You dont want this column in your table:
        adx$DX <- NULL
        res <- merge(price, adx)
        # res is an xts object.  Now convert to data.frame
        df_res <- data.frame("Date" = index(res), "Ticker" = tickername, coredata(res))
        df_res
    }
    
    # data is an environment, not a list, so can use eapply (similar to lapply):
    out <- eapply(env = data, FUN = SignalCalculator2)
    out2 <- do.call(rbind, out)
    # If you want to order rows by date:
    out2 <- out2[order(out2$Date),]
    # Optional tidy up:
    rownames(out2) <- NULL
    
    
    > tail(out2)
    # Date Ticker Price      DIp      DIn      ADX
    # 164 2016-08-25   AAMC 12.72 17.67766 21.28021 11.31483
    # 330 2016-08-25    AAU  1.42 22.36896 23.64023 30.50243
    # 165 2016-08-26   AAMC 12.80 16.48608 21.07136 11.37868
    # 331 2016-08-26    AAU  1.36 23.02102 21.80518 28.51742
    # 166 2016-08-29   AAMC 13.15 15.75814 20.14096 11.43797
    # 332 2016-08-29    AAU  1.43 21.63012 22.30030 26.58943