Параллельный запрос цен исторических цепочек опционов / Последняя известная цена в IBrokers (R)

Я пытаюсь создать текущую цепочку опционов (опционы за страйк, за истечение) для тикера.

library(IBrokers)    
tws <- twsConnect()
# Lets say only Call prices
AA <- reqContractDetails(tws, twsOption(local="", right="C", symbol="AAPL"))

Нативная реализация с snapshot слишком медленная:

reqMktData(tws, AA[1:2], snapshot = TRUE)

Ожидание составляет около 11 sec на каждый контракт (текущее количество контрактов – 626).


Другая реализация:

snapShot <- function (twsCon, eWrapper, timestamp, file, playback = 1, ...)
{
  if (missing(eWrapper))
    eWrapper <- eWrapper()
  names(eWrapper$.Data$data) <- eWrapper$.Data$symbols
  con <- twsCon[[1]]
  if (inherits(twsCon, "twsPlayback")) {
    sys.time <- NULL
    while (TRUE) {
      if (!is.null(timestamp)) {
        last.time <- sys.time
        sys.time <- as.POSIXct(strptime(paste(readBin(con,
                                                      character(), 2), collapse = " "), timestamp))
        if (!is.null(last.time)) {
          Sys.sleep((sys.time - last.time) * playback)
        }
        curMsg <- .Internal(readBin(con, "character",
                                    1L, NA_integer_, TRUE, FALSE))
        if (length(curMsg) < 1)
          next
        processMsg(curMsg, con, eWrapper, format(sys.time,
                                                 timestamp), file, ...)
      }
      else {
        curMsg <- readBin(con, character(), 1)
        if (length(curMsg) < 1)
          next
        processMsg(curMsg, con, eWrapper, timestamp,
                   file, ...)
        if (curMsg == .twsIncomingMSG$REAL_TIME_BARS)
          Sys.sleep(5 * playback)
      }
    }
  }
  else {
    evalWithTimeout(
    while (TRUE) {
      socketSelect(list(con), FALSE, NULL)
      curMsg <- .Internal(readBin(con, "character", 1L,
                                  NA_integer_, TRUE, FALSE))
      if (!is.null(timestamp)) {
        processMsg(curMsg, con, eWrapper, format(Sys.time(),
                                                 timestamp), file, ...)
      }
      else {
        processMsg(curMsg, con, eWrapper, timestamp,
                   file, ...)
      }
      if (!any(sapply(eWrapper$.Data$data, is.na)))
        return(do.call(rbind, lapply(eWrapper$.Data$data,
                                     as.data.frame)))
    }, timeout=5, onTimeout="warning")
  }
} 

reqMktData(tws, AA[1:20], eventWrapper=eWrapper.data(20),CALLBACK=snapShot)

Это позволяет избежать ожидания (11 секунд).

Но это не работает, если нет данных в реальном времени или рынки закрыты.

Итак, я хочу получить только последнюю известную цену, даже если рынки закрыты.
Это мое псевдорешение:

reqHistoricalData(tws, AA[[1]]$contract, whatToShow='BID', barSize = "1 min", duration = "60 S")

Есть ли способ распараллелить это решение, чтобы оно требовало исторической цены нескольких контрактов?

В настоящее время он тратит около 2.3 seconds на контракт, в то время как предыдущее решение могло получить 20-30 контрактов за то же время.


person Jav    schedule 11.02.2016    source источник


Ответы (1)


Вместо использования reqMktData() рассмотрите возможность использования reqRealTimeBars() с переменной, содержащей ваш список контрактов, чтобы делать то, что вы хотите, без ограничений reqHistoricalData().

Бары в реальном времени — это запрос на потоковую передачу исторических данных, данные передаются обратно с тех же серверов, которые предоставляют исторические данные.

person Sagaponack FX    schedule 17.02.2016
comment
К сожалению, reqRealTimeBars, похоже, страдает от той же проблемы, что и reqMktData(). Насколько я вижу, ответа нет, если он предоставляется, когда рынки закрыты. Хотя я бы хотел, чтобы он сообщал последнюю известную цену, если рынки не открыты. - person Jav; 29.02.2016
comment
Вы пробовали использовать userRTH? reqHistoricalData(tws, AA[[1]]$contract, whatToShow='BID', barSize = 1 мин, продолжительность = 60 с, useRTH = 0) - person Sagaponack FX; 11.03.2016