2014-10-23 6 views
3
내가 VIX에 대한 옵션 체인을 다운로드 할 QuantMod 라이브러리에서 함수 getOptionChain()를 사용하는 것을 시도하고있다

, SP500 및 Eurostoxx 50 있지만 다음은 작동하지 않습니다QuantMod getOptionChain "경계 밖으로 첨자"오류

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

는이 오류를 받고 있어요 :

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' 

어떻게이 문제를 해결할 수 있습니까?

+1

이 될 것으로 보인다는 아닌 [드문 문제] (http://r.789695.n4.nabble.com/quantmod-getOptionChain-errors-td4645782.html) 결정적인 문제가 없습니다. – hrbrmstr

+2

그리고'quantmod' 만이 문제가되는 것은 아닙니다. (http://stackoverflow.com/questions/26539963/how-can-i-download-option-data-given-the-new-format-introduced- 오늘 -10-23-14). 야후는 HTML 형식을 변경 한 것으로 보이며 스크래퍼를 깨뜨리고있다. – hrbrmstr

+0

Google은 실용적인 대안을 제공합니다. 아래 답변을 참조하십시오. – jclouse

답변

2

이 문제에 대한 패치를 작성 중입니다. 지금까지는 작동하지만 opex 날짜를 정확하게 지정해야합니다 (월 3 번째 금요일).

예 호출

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 ... 

형식은 이전 버전 (내 생각)을 일치합니다.

이 패치는 rjson 패키지에 새로운 종속성을 도입합니다.

는() ("rjson을"install.packages) rjson를 설치, 패치를 사용하고로드 quantmod 후에 당신의 R 콘솔에서 다음을 실행하려면 다음을 수행하십시오 getOptionChain.yahoo에 무슨 문제가 있나요

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") 
+0

Yahoo의 형식이 다시 변경된 것처럼 보입니다. 2015 년 6 월 현재이 형식으로 작업 할 수 있도록 패치를 업데이트했습니다. 가장 효율적인 R 코드는 아니지만 작동합니다. –

0

패치 코드. dateToMillis에 하루를 잘못 추가하고 있습니다. 잘못 입력하지 않은 경우 이전에 코드가 작동했던 방식과 적어도 다릅니다.

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

야후의 데이터를 기반으로하는 해결책을 찾을 수 없었습니다. 저는 여전히 재고 데이터를 위해 QuantMod와 Yahoo를 사용하고 있으며 현재 옵션 체인 데이터를 위해 Google을 사용하고 있습니다. 여기에 작업 솔루션에서 첫 번째 시도이다 :

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