IBrokers reqMktData,如何向回调函数添加超时?

IBrokers reqMktData,如何向回调函数添加超时?,r,ibrokers,R,Ibrokers,我一直在使用great IBrokers软件包中的一个修改过的快照函数从IB获取“最后”价格,它对流动性股票非常有效。 我打的电话是 reqMktData(tws, twsSTK("AAPL"), eventWrapper=eWrapper.data.Last(1),CALLBACK=snapShot) 当试图取回流动性非常差的股票或期权时,问题就出现了。因此,我需要为快照函数添加一个超时。如何以及在何处添加超时 具有快照功能的代码: library(IBrokers) tws <- t

我一直在使用great IBrokers软件包中的一个修改过的快照函数从IB获取“最后”价格,它对流动性股票非常有效。 我打的电话是

reqMktData(tws, twsSTK("AAPL"), eventWrapper=eWrapper.data.Last(1),CALLBACK=snapShot)
当试图取回流动性非常差的股票或期权时,问题就出现了。因此,我需要为快照函数添加一个超时。如何以及在何处添加超时

具有快照功能的代码:

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)))
       }
   }
}
库(IBrokers)

tws您可以从中使用
evalWithTimeout
。我没有测试它,但我非常确定围绕while循环包装
evalWithTimeout
将实现您所追求的目标

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")
库(R.utils)
evalWithTimeout(
while(TRUE){
socketSelect(列表(con)、FALSE、NULL)

curMsg是快照函数的来源吗?是的!但是更正了列名sry,实际上它是其中的变体,只获取“Last”:但是列名发生了变化dhi!谢谢!我没有想到这个简单而优雅的解决方案。您可能注意到我发布的代码的原始部分来自邮件列表,也是您:)实际上,它是从那里的变体,只获取“Last”:marc.info/?l=r-sig-finance&m=131662968112461,但列名已更改