0

I want to download the option chain data from google finance, and here I find a R script to download, it is useful, I've changed it capable to download multiple expiry dates option price, but the origin json link seems to only have the call option data, how can I get put option data.

library(rjson)

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)
} 

1 Answers1

1

If you want a quick and dirty solution, replace this line

options <- ldply (options.list[["calls"]], data.frame)

with

options <- ldply (options.list[["puts"]], data.frame)

In both cases the function will return a data frame with 48 rows. But you'll notice that the data returned is different. Calls have cids such as 'GOOG170120C00250000', puts have a "P" inside: 'GOOG170120P00250000'

Out of personal interest, I have rewritten your example a little bit, so that it works for me. Here is the code:

library(rjson)
library(plyr)

getOptionChain <- function (symbol,exp = 14, type = "calls") {
        # symbol = "WMT"
        if( ! any(grepl(type, c("puts", "calls") ))){
                stop("ERROR: Third argument must be either 'calls' or 'puts'. Defaults to 'calls'.")
        }

        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, )
        outfile = paste0(symbol, ".json")
        rv <- download.file(url, destfile = outfile, method="curl")
        warning(paste0("fetching url 1: ", url))

        google.options.json <-  readLines(outfile, 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="")
        warning(paste0("fetching url 2: ", url))
        outfile2 = paste0(symbol, ".longest-expiry.json")
        rv <- download.file(url, destfile = outfile2, method="curl")

        google.options.json <- readLines(outfile2, 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[[type]], 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)
}

Example function calls:

calls <- getOptionChain("GOOG", 12, "calls") puts <- getOptionChain("GOOG", 12, "puts")

the "exp" parameter is set to an arbitrary value of "12". I don't understand what it is for, but never mind.

knb
  • 9,138
  • 4
  • 58
  • 85
  • Thanks, I've also changed the code like your way, the exp is 2017/01/20 due to the google finance only provides the option Chain at that time. Another question of this program is that it cannot download optionChain of SPY, have you tried? –  Feb 15 '15 at 23:21
  • I don't know. What does SPY stand for? an ETF, or a "small" logistics company, or something else? – knb Feb 16 '15 at 09:29