QuantMod getOptionChain error "index out of bounds"

I'm trying to use getOptionChain () function from QuantMod library to load option chains for VIX, SP500 and Eurostoxx 50, but the following doesn't work:

library(quantmod)
VIX.OPT <- getOptionChain("^VIX")

      

I am getting this error:

Error in lapply(strsplit(opt, "<tr>"), function(.) gsub(",", "", gsub("N/A",  : 
  subscript out of bounds
In addition: Warning message:
In readLines(paste(paste("http://finance.yahoo.com/q/op?s", Symbols,  :
  incomplete final line found on 'http://finance.yahoo.com/q/op?s=^VIX+Options'

      

How can I fix this?

+3


source to share


3 answers


I am working on a patch for this. So far this works, but you must specify the opex date exactly (3rd Friday of the month).

Examples of calls:

getOptionChain("^VIX")
$calls
                   Strike  Bid  Ask Last   Vol     OI
VIX141119C00010000   10.0 7.10 7.40 7.10    18   1974
VIX141119C00010500   10.5 6.60 6.90 6.90   330    510
VIX141119C00011000   11.0 6.10 6.40 6.10   108   1469 ...

getOptionChain("^VIX", '2014-12-16') #note VIX dec expiry is NOT 12/19, weird
$calls
                   Strike  Bid  Ask Last   Vol     OI
VIX141217C00010000   10.0 7.10 7.40 7.50     1    964
VIX141217C00011000   11.0 6.20 6.40 6.53   100    673
VIX141217C00012000   12.0 5.20 5.40 5.50     4    873 ...

      

The format is the old version (I THINK).



This patch introduces a new dependency on the rjson package .

To use the patch, install rjson (install.packages ("rjson")) and then run from the R console AFTER loading the quantum module:

getOptionChain.yahoo.patch <- function(Symbols, Exp, ...)
{
    library("XML")
    library("rjson")

    millisToDate <- function(x)
    {
        return (as.Date(x / 86400000, origin = "1970-01-01"))
    }

    dateToMillis <- function(x)
    {
        as.numeric(x+1) * 86400000  /1000
    }

    parse.expiry <- function(x) {
        if(is.null(x))
          return(NULL)

        if(is.character(x))
        {
            x <- as.Date(x)
        }

        if(inherits(x, "Date") || inherits(x, "POSIXt"))
          return(dateToMillis(x))

         return(NULL)
    }

    getOptionChainJson <- function(sym, Exp)
    {
      if(missing(Exp))
        {
            url <- paste("http://finance.yahoo.com/q/op?s",sym,sep="=")
            opt <- readLines(url)
        }
      else
        {   
            url <- paste("http://finance.yahoo.com/q/op?s=",sym,"&date=",parse.expiry(Exp),sep="")
            opt <- readLines(url)
        }

        opt <- opt[grep("percentChangeRaw", opt)]
        opt <- unlist(strsplit(opt, "<script>"))
        json <- opt[3]
        json <- gsub("<script>", "", json)
        json <- gsub("</script>", "", json)
        json <- gsub(";", "", json)
        json <- unlist(strsplit(json, "="))[4]

        j <- fromJSON(json)
        price <- j$models$applet_model$data$optionData$quote$regularMarketPrice
        calls <- j$models$applet_model$data$optionData$options$calls
        puts <- j$models$applet_model$data$optionData$options$puts
        return (list(calls=chainToDf(calls), puts=chainToDf(puts), price = price, sym = sym))
    }

    chainToDf <- function(theList)
    {
        x <- do.call(rbind.data.frame, theList)

        rownames(x) <- x$contractSymbol
        y <- x[,c("strike", "bid", "ask", "lastPrice", "volume", "openInterest")]
        theNames <- c("Strike", "Bid", "Ask", "Last", "Vol", "OI")
        names(y) <- theNames
        for(i in theNames)
        {
            y[,i] <- as.numeric(as.character(y[,i]))
        }

        #y$contractSymbol <- as.character(x$contractSymbol)
        #y$expiration <- millisToDate(as.numeric(as.character(x$expiration)) * 1000)

        return(y)
    }

    getOptionChainJson(Symbols, Exp)
}
assignInNamespace("getOptionChain.yahoo", getOptionChain.yahoo.patch, "quantmod")

      

+2


source


I was unable to find a working solution based on Yahoo data. I still use QuantMod and Yahoo for stock data and now use Google for option chain data. Here's a first attempt at a working solution:



library(rjson)

getOptionChain <- function (symbol) {
  # 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"]])
  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)
}

      

+1


source


There is a bug in the getOptionChain.yahoo.patch code. You are adding a day to dateToMillis which is wrong, or at least different from how the code worked before, if I'm not mistaken. it should be:

dateToMillis <- function(x)
{
    as.numeric(x) * 86400000  /1000
}

      

0


source







All Articles