IBrokers reqMktData,如何向回调函数添加超时? [英] IBrokers reqMktData, how to add timeout to the callback function?

查看:173
本文介绍了IBrokers reqMktData,如何向回调函数添加超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用很棒的IBrokers软件包中的经过改进的snapShot函数从IB获得最后"价格,并且它对于流动性股票一直非常有用. 我打的电话是例如.

I have been using a modified snapShot function from the great IBrokers package to get "Last" prices from IB and it has been working great for liquid stocks. The call I make is eg.

reqMktData(tws, twsSTK("AAPL"), eventWrapper=eWrapper.data.Last(1),CALLBACK=snapShot)

尝试检索流动性极低的股票或期权时会出现问题.因此,我需要向snapShot函数添加超时.如何以及在何处添加超时?

The problem arises when trying to retrieve very illiquid stocks or options. I would therefore need to add a timeout to the snapShot function. How and where could the timeout be added?

具有snapShot函数的代码:

The code with the snapShot function:

library(IBrokers)
tws <- twsConnect()

eWrapper.data.Last <- function(n) {
  eW <- eWrapper(NULL)  # use basic template
  eW$assign.Data("data", rep(list(structure(.xts(matrix(rep(NA_real_,2),nc=2),0),
                                      .Dimnames=list(NULL,c("LastSize","Last")))),n))

  eW$tickPrice <- function(curMsg, msg, timestamp, file, ...) 
  {
    tickType = msg[3]
    msg <- as.numeric(msg)
    id <- msg[2] #as.numeric(msg[2])
    data <- eW$get.Data("data") #[[1]]  # list position of symbol (by id == msg[2])
    attr(data[[id]],"index") <- as.numeric(Sys.time())
    nr.data <- NROW(data[[id]])
    if(tickType == .twsTickType$LAST) {
      data[[id]][nr.data,2] <- msg[4]
    }
    eW$assign.Data("data", data)
    c(curMsg, msg)
  }
  eW$tickSize  <- function(curMsg, msg, timestamp, file, ...) 
  { 
    data <- eW$get.Data("data")
    tickType = msg[3]
    msg <- as.numeric(msg)
    id <- as.numeric(msg[2])
    attr(data[[id]],"index") <- as.numeric(Sys.time())
    nr.data <- NROW(data[[id]])
    if(tickType == .twsTickType$LAST_SIZE) {
      data[[id]][nr.data,1] <- msg[4]
    } 
    eW$assign.Data("data", data)
    c(curMsg, msg)
  }
  return(eW)
}

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

推荐答案

您可以使用 R.utils .我没有进行测试,但是我敢肯定,将evalWithTimeout封装在while循环中会达到您想要的目的.

You can use evalWithTimeout from the R.utils. I didn't test it, but I'm pretty sure wrapping evalWithTimeout around the while loop would achieve what you're after.

library(R.utils)

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

这篇关于IBrokers reqMktData,如何向回调函数添加超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆