Search code examples
rfunctionquantmodquantile

Function in quantmod to get the Volume data column into a Quartile Rank


With the help of community I've created the code to download multiple tickers from a .csv file list.

My next step would be to create a column with the quartile rank for the Volume data. What is wrong in my approach?

Here is my approach:

Load my tickers list from a .csv file, create a list with all of them.

library(quantmod)
Tickers <- read.csv("nasdaq_tickers_list.csv", stringsAsFactors = FALSE)
getSymbols(Tickers$Tickers,from="2018-08-01", src="yahoo" )
stock_data = sapply(.GlobalEnv, is.xts)
all_stocks <- do.call(list, mget(names(stock_data)[stock_data])) 

Function to get the Volume column data into a Quartile Rank? What is wrong?

Volume_q_rank <- function(x) {
stock_name <- stringi::stri_extract(names(x)[1], regex = "^[A-Z]+")
stock_name <- paste0(stock_name, ".Volqrank")
column_names <- c(names(x), stock_name)
x$volqrank <-as.integer(cut(quantmod::Vo(x),
quantile(x,probs=0:4/4),include.lowest=TRUE))
}

calculate quartile rank for stock volume column and add them to the data

all_stocks <- lapply(all_stocks, Volume_q_rank)

What is wrong in my function?

When I run the function I get the following error:

Error in quantile.default(coredata(x), ...) : 
missing values and NaN's not allowed if 'na.rm' is FALSE 

Thanks for any input.


Solution

  • I'm not sure why you are getting this error. I used 103 NASDAQ tickers. But I did adjust your function as it didn't return the correct results. In my case it only returned the value 4 for every record of each ticker.

    Adjustments made to the function: One, I made sure that the quantile function also looks at the volume of the stocks. You have it looking at the whole xts object. Now it returns the volume divided in 4 quantiles. Secondly, the function was only returning x$volqrank instead of x. I added the last 2 lines to the function to make sure it returns the full xts object.

    Here is the new function:

    Volume_q_rank <- function(x) {
      stock_name <- stringi::stri_extract(names(x)[1], regex = "^[A-Z]+")
      stock_name <- paste0(stock_name, ".Volqrank")
      column_names <- c(names(x), stock_name)
      x$volqrank <- as.integer(cut(quantmod::Vo(x),
                                  quantile(quantmod::Vo(x),probs=0:4/4),include.lowest=TRUE))
      x <- setNames(x, column_names)
      return(x)
    }
    
    all_stocks <- lapply(all_stocks, Volume_q_rank)
    
    head(all_stocks$MSFT)
               MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume MSFT.Adjusted MSFT.Volqrank
    2018-08-01    106.03    106.45   105.42     106.28    23628700      105.8726             4
    2018-08-02    105.40    108.09   104.84     107.57    26104300      107.1576             4
    2018-08-03    107.80    108.05   106.82     108.04    18659600      107.6258             2
    2018-08-06    108.12    108.42   107.56     108.13    20265900      107.7155             2
    2018-08-07    108.56    109.10   108.17     108.88    16080200      108.4626             1
    2018-08-08    109.33    109.75   108.76     109.49    15487500      109.0703             1