RyGuy
RyGuy

Reputation: 305

Looking up tickers for different time periods in a loop with quantmod

I'm able to loop through and calculate the overnight/over-weekend returns for a list of tickers when the time period is the same for every ticker, but am having trouble when the time period I want to look up is different for each ticker.

For example, with:

symbols <- c("AAPL", "GOOG"," MSFT")
dates <- as.Date(c("2015-01-04", "2015-01-05", "2015-01-06"))
example.df <- data.frame(tickers, dates)
example.df
  tickers dates
1    AAPL 2015-01-04
2    GOOG 2015-01-05
3    MSFT 2015-01-06

I'd want the overnight return for AAPL between 2015-01-04 and 2015-01-05, for GOOG between 2015-01-05 and 2015-01-06, etc. If it was a Friday, I'd want the next Monday.

I can can get what I'm looking for by looking up each individual ticker like this:

library(quantmod)
library(dplyr)
# date range accounts for weekends
getSymbols("AAPL", from = "2016-01-04", to = "2016-01-08")
data <- as.data.frame(AAPL)
colnames(data) <- c("open","high","low","close","volume","adj.")
# overnight return calculation
data$overnight.return <- data$open / lag(data$close, default = 0) - 1
data$overnight.return <- paste(round(data$overnight.return * 100, 3), "%",sep= "") 
# the overnight/over-weekend returns for the specified date
data.df.final <- slice(data, 2)

Of course that's terribly slow. Here's as far as I was able to get trying to make a loop out of it:

# needs to be a loop itself and inside the other 'for' loop somehow I think
symbol.list <- example.df[,1]
start <-  data[,2]
end <- data[,2] + days(3) 

results <- NULL
for (i in symbol.list) {
  data <- getSymbols(Symbols = i, 
                     src = "yahoo", 
                     from = start, to = end, 
                     auto.assign = FALSE)
  if (inherits(data, 'try-error')) next
  colnames(data) <- c("open","high","low","close","volume","adj.")
  data <- as.data.frame(data)
  data <- cbind(date = rownames(data), data)
  data$overnightRtn <- as.vector(data$open / lag(data$close, default = 0) - 1)
  data$overnightRtn <- paste(round(data$overnightRtn * 100, 3), "%") 
  data <- slice(data, 2)
  results <- bind_rows(results, data)
  }

How can I add the date looping aspect to the above ticker loop?

Upvotes: 2

Views: 442

Answers (1)

Carlos Alberto
Carlos Alberto

Reputation: 698

maybe this is what you are looking for. See that I'm using an index, not the actual list, so I can refer to every element of your data frame (it is not optimized, but it is doing the job you described in the function):

symbols <- c("AAPL", "GOOG"," MSFT")              ## " MSFT" has an extra space
dates <- as.Date(c("2015-01-04", "2015-01-05", "2015-01-06"))
example.df <- data.frame(tickers=symbols, dates)  ## there was an error here in your example.

symbol.list <- trimws(example.df[,1])
start <-  as.Date(example.df[,2])
end <- as.Date(example.df[,2]) + days(3) 

results <- NULL
for (i in 1:NROW(symbol.list)) {
  try(dataX <- getSymbols(Symbols = symbol.list[i], 
                     src = "yahoo", 
                     from = start[i], to = end[i], 
                     auto.assign = FALSE),silent=T)
  if (!exists("dataX")) {cat("Error in ",i,"\n");next}
  colnames(dataX) <- c("open","high","low","close","volume","adj.")
  dataX <- as.data.frame(dataX)
  dataX <- cbind(date = rownames(dataX), dataX)
  dataX$overnightRtn <- as.vector(dataX$open / lag(dataX$close, default = 0) - 1)
  dataX$overnightRtn <- paste(round(dataX$overnightRtn * 100, 3), "%") 
  data2 <- slice(dataX, 2);rm(dataX)
  results <- if (is.null(results)) data2 else rbind(results, data2)
}

Upvotes: 2

Related Questions