Search code examples
rquantmod

getOptionChain() not returning Index Options Data in R


I am trying to call all the ^SPX options tables via quantmod:

library("quantmod")

# Returns the front month
getOptionChain("^SPX")

# does not return all the Option Tables
getOptionChain("^SPX", Exp=NULL)

The error message I get:

> getOptionChain("^SPX", NULL)
Error in (function (object = nm, nm)  : 
  attempt to set an attribute on NULL

How do I fix this issue so i can call all option tables?


Solution

  • The last two expiration dates for "^SPX" do not have data for calls and puts, respectively. Here's a patch you can apply to fix the issue (and an issue with commas in numeric data, which causes them to be kept as character):

    diff --git a/R/getOptionChain.R b/R/getOptionChain.R
    index fb490ef..b3cca51 100644
    --- a/R/getOptionChain.R
    +++ b/R/getOptionChain.R
    @@ -20,13 +20,17 @@ getOptionChain.yahoo <- function(Symbols, Exp, ...)
           XML::xmlValue(x)
         }
       }
    -  NewToOld <- function(x) {
    +  NewToOld <- function(x, nm) {
    +    if(is.null(x))
    +      return(x)
         # clean up colnames, in case there's weirdness in the HTML
    -    x <- setNames(x, make.names(names(x)))
    +    x <- setNames(x, make.names(nm))
         # set cleaned up colnames to current output colnames
         d <- with(x, data.frame(Strike=strike, Last=last, Chg=change,
           Bid=bid, Ask=ask, Vol=volume, OI=openinterest,
           row.names=`contractname`, stringsAsFactors=FALSE))
    +    # remove commas from the numeric data
    +    d[] <- lapply(d, gsub, pattern=",", replacement="", fixed=TRUE)
         d[] <- lapply(d, type.convert, as.is=TRUE)
         d
       }
    @@ -100,8 +104,7 @@ getOptionChain.yahoo <- function(Symbols, Exp, ...)
       dftables <- XML::xmlApply(XML::getNodeSet(tbl, xpaths$tables), XML::readHTMLTable, stringsAsFactors=FALSE)
       names(dftables) <- table.names
    
    -  dftables <- mapply(setNames, dftables, table.headers, SIMPLIFY=FALSE)
    -  dftables <- lapply(dftables, NewToOld)
    +  dftables <- mapply(NewToOld, x=dftables, nm=table.headers, SIMPLIFY=FALSE)
       dftables
     }