Question

I use R to download option chains, via the quantmod package. My goal is to download and export option chains in order to be used on other software.

If I download only the front month expiry, I am able to correctly export to a .txt file, using these lines:

library(quantmod)
aapl_front <- getOptionChain ('AAPL')
front <- do.call('rbind', aapl_front)
write.table (front, 'data_front.txt')

Problems appear when I download all the expiries. Here the rbind function fails to work as I think it should, and I export a table that is useless; these are the lines:

aapl_total <- getOptionChain('AAPL', NULL)
total <- do.call('rbind', aapl_total)
write.table(total, 'data_total.txt')

I guess that in the second case aapl_total is a list of lists, that contains all the expiries, and I'm not able to correctly split them.

Any suggestions?

Was it helpful?

Solution

You could loop through each expiration and rbind the calls and puts.

lapply(aapl_total, function(x) do.call(rbind, x))

Then, you'd have a list that you could do.call(rbind()).

In one step:

do.call(rbind, lapply(aapl_total, function(x) do.call(rbind, x)))

OTHER TIPS

These are not working for option data anymore, because yahoo changes its website, please use Google finance as the option data source, here is a sample

EXAMPLE: getOptionChain('GOOG',3) means the next 3 expiry date for google option chain

library(rjson)
library(plyr)
getOptionChain <- function (symbol,exp) {
  # symbol = "WMT"  

  url <- "https://www.google.com/finance/option_chain?q="
  # url <- paste(url, symbol, "&expd=15&expm=01&expy=2016&output=json", sep="")
  url <- paste(url, symbol, "&output=json", sep="")

  google.options.json <- readLines(url, warn = FALSE)

  options.json <- google.options.json
  options.json <- gsub("[{]", "{\"", options.json)
  options.json <- gsub("[:]", "\":", options.json)
  options.json <- gsub("[,] ", "$$$", options.json)
  options.json <- gsub("[,]", ",\"", options.json)
  options.json <- gsub("[,]\"[{]", ",{", options.json)
  options.json <- gsub("[$][$][$]", ", ", options.json)

  options.list <- fromJSON(options.json)

  #get the options chain without an expiry date and then determine longest option

  last.expiration <- length(options.list[["expirations"]])
  if ( exp>0 && exp< last.expiration) {
    last.expiration <-exp
  } 
  month <- sprintf("%02d", options.list[["expirations"]][[last.expiration]]$m)
  day <- sprintf("%02d", options.list[["expirations"]][[last.expiration]]$d )
  year <- options.list[["expirations"]][[last.expiration]]$y

  #now request option chain for the longest expiry

  url <- "https://www.google.com/finance/option_chain?q="
  url <- paste(url, symbol, "&expd=", day, "&expm=", month, "&expy=", year, "&output=json", sep="")

  google.options.json <- readLines(url, warn = FALSE)

  options.json <- google.options.json
  options.json <- gsub("[{]", "{\"", options.json)
  options.json <- gsub("[:]", "\":", options.json)
  options.json <- gsub("[,] ", "$$$", options.json)
  options.json <- gsub("[,]", ",\"", options.json)
  options.json <- gsub("[,]\"[{]", ",{", options.json)
  options.json <- gsub("[$][$][$]", ", ", options.json)

  options.list <- fromJSON(options.json)

  options <- ldply (options.list[["calls"]], data.frame)
  options <- rename(options, c("s" = "contract.name",
                               "p" = "price",
                               "b" = "bid", 
                               "a" = "ask",
                               "c" = "change",
                               "cp" = "change.percentage",
                               "oi" = "open.interest",
                               "vol" = "volume"))
  options <- options[c( "contract.name", 
                        "strike",
                        "price", 
                        "change", 
                        "change.percentage",
                        "bid", 
                        "ask", 
                        "volume",
                        "open.interest")]


  options$expiry <- paste(options.list[["expiry"]]$m, options.list[["expiry"]]$d, options.list[["expiry"]]$y, sep = "/")

  last.expiration <- length(options.list[["expirations"]])
  options$longest.available.expiry <- paste(options.list[["expirations"]][[last.expiration]]$m,
                                            options.list[["expirations"]][[last.expiration]]$d, 
                                            options.list[["expirations"]][[last.expiration]]$y, sep = "/")

  options$underlying.price <- options.list[["underlying_price"]]

  return(options)
}

Here another approach. I recover the list structure:

ni <- seq_along(aapl_total)
nj <- seq_along(aapl_total[[1]])
nij <- as.matrix(expand.grid( ni=ni,  nj=nj))
data <- apply(nij, 1, function(ij) aapl_total[[ij]])

Then I put it a single data.frame:

res <- do.call(rbind,data)

EDIT add a column type since rownames are not significant.

labels <- as.vector(outer(c('call','put'),
                         names(aapl_total),paste0))
data <- lapply(seq(nrow(nij)), function(i) {
  data.frame(aapl_total[[nij[i,]]],type=labels[i])
})
res <- do.call(rbind,data)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top