R IBrokers reqopenorders 未更新

问题描述 投票:0回答:2

我正在使用 IBrokers 包中的代码查询 TWS Interactive Brokers 中的挂单列表。

函数 reqOpenOrders(tws) 有一个错误,它挂起,如here所示,即使它工作,输出也很混乱,如here所示。

我将一些来自不同来源的代码组合在一起,创建一个清晰/逻辑易于理解的函数,同时输出结果的数据框。

功能如下,第一次使用效果很好。但是,当在 TWS 中进行更改时(例如取消挂单或下达追踪订单),如果在 R 中运行以下函数,则更改不会更新。

如果我关闭并再次打开与 TWS 的连接,则在运行下面的函数后我会得到一个空的 data.frame。如果我关闭所有连接并多次尝试该函数,最终它会返回更新的结果。

有谁知道为什么调用该函数没有查询到TWS中最新的变化吗?

我认为这与 R 与 TWS 的连接有关。该函数似乎等待连接最终变得可用。如果我重新启动 R,第一次运行该函数时,结果会更新,这表明如果所有连接都恢复,该函数可以正常运行。对于这个问题有什么建议吗?

我想知道退出函数后是否需要关闭所有套接字和连接?我尝试了该解决方案的不同版本,但没有成功。

非常感谢任何帮助。

library(IBrokers)

Get.Open.Orders<- function(tws)
{
library(dplyr)
Open.Orders <- function(tws)
  {
   con <- tws[[1]] #connector used to communicate with TWS
   VERSION <- "1"
   writeBin(c(.twsOutgoingMSG$REQ_OPEN_ORDERS, VERSION), con) #send request for open orders
   eW  <- eWrapper()                         #Creates a custom function to get the data that was requested
   socketSelect(list(con), FALSE, NULL)      #Wait for first socket connection to become available
   curMsg <- readBin(con, character(), 1L)   #read the response received from IB            
   processMsg(curMsg, con, eW)               #Process message 
 }

#orginize the data recieved into a data.frame, selects only  set of vaiables received.
open <- data.frame()
 i <- 0
   while(i < 2)
   {
     x <- Open.Orders(tws)
       if(!is.null(x) && x[1] == 53) # OPEN_ORDER_END
       {i = i + 1 } else if(!is.null(x) && x[1] == 5) # For Open Orders
         {
           x <- data.frame(t(x), stringsAsFactors = FALSE)
           open <- bind_rows(open, x)
         }
     rm(x)
   }

if(nrow(open) > 0)
{
 open <- open %>% distinct() %>%
   rename(conId = X4, symbol = X5, sectype = X6, strike = X10,
         currency = X11, action = X13, totalQuantity = X14,
         orderType = X15, lmtPrice = X16, auxPrice = X17,
         tif = X18, outsideRTH = X19, account = X20, orderId = X25, Status = X77
  ) %>%
  select(account, orderId, conId, symbol, sectype, strike, currency,
         action, totalQuantity, orderType, lmtPrice, auxPrice, tif, Status) %>%
  mutate(orderId = as.integer(orderId)
         , totalQuantity = as.numeric(totalQuantity)
         , lmtPrice = as.numeric(lmtPrice)
         , auxPrice = as.numeric(auxPrice) )
} else
{
open <- data.frame(account = character()
                   , orderId = integer()
                   , conId = character()
                   , symbol = character()
                   , sectype = character()
                   , strike = character()
                   , currency = character()
                   , action = character()
                   , totalQuantity = numeric()
                   , orderType = character()
                   , lmtPrice = numeric()
                   , auxPrice = numeric()
                   , tif = character()
                   , Status = character()
                   , stringsAsFactors = FALSE)
 }

 assign("IB.open.orders", open, envir = .GlobalEnv)
 rm(i, Open.Orders, open)
 return(data.frame(IB.open.orders))
 }


 #now connect to IB and get active orders; it works fine first time
 tws = twsConnect()
 Get.Open.Orders (tws)

 # now go to TWS and delete any given pending order for the sake of an example. Then in R run function again to request pending orders
Get.Open.Orders (tws)

#The change in TWS is now reflected in the output, so I disconnect TWS, and connect again

twsDisconnect(tws)  #disconned TWS
tws = twsConnect()  #connect to TWS
Get.Open.Orders (tws)

#the result is an empty dataframe. If I run the three lines of code above...say 10 times, eventually the updated results are returned.

showConnections(all = TRUE)
closeAllConnections()
tws = twsConnect()
Get.Open.Orders (tws)
r tws ibrokers
2个回答
1
投票

这可能不是最好的解决方案,但我找到了一种从 TWS 获取未结订单的最新数据的方法。上面的原始功能似乎只有在使用正确的连接时才起作用。在两次尝试之间,它返回一个空的 data.frame。因此,我所做的就是创建一个 while 循环,将查询发送到 TWS,直到使用正确的连接。代码如下。它可以工作并在几次尝试后返回正确的数据。我想我分享代码作为临时解决方案。

tws = twsConnect()

#Current pending orders
  OpenOrders=Get.Open.Orders (tws)
  showConnections(all = TRUE)    
  nOP=nrow(OpenOrders)

while (nOP==0){
  tws = twsConnect()
  OpenOrders=Get.Open.Orders (tws)  
  nOP=nrow(OpenOrders)
  quiet = TRUE
}

0
投票

这实际上是对上面唯一答案的评论,但我以前也做过这个循环,直到我意识到每个订单实际上都将客户名称和 reqID 附加到每个订单,所以我开始跟踪它们,然后我可以访问通过创建新客户端(使用旧客户端 ID)并使用 reqID 引用长期订单,然后在从函数返回结果之前关闭并销毁客户端,可以从函数环境内部发出任何订单。

因此,我将使用这样的代码来实现括号订单的止盈部分:

  tporder <-
      placeOrder(
        mainclient,
        contract,
        bracketaction,
        abs(adj_quantity),
        transmit = T,
        orderType = "LMT",
        limitPrice = tpp,
        tif = tif,
        stopPrice = "0.0",
        ocaGroup = ocaGroup,
        ocaType = ocaType,
        trigger = tp_trigger,
        stf = stf
      )
    
    print(mainclient$clientId)
    tporder$clientid <- mainclient$clientId

然后取消订单,我将使用这样的代码:

if (exists("tp_data")) {
  if (tp_data[1] != "NO ORDER") {
    # first check if the order is attached to current client
    cancelOrder(current_client, tp_data$order_id)
    
    # if it's not then this code would create a new client
    # and cancel the order
    cancel_con <- connectToIB(tp_data$clientid)
    cancelOrder(cancel_con, tp_data$order_id)
    twsDisconnect(cancel_con)
    print("Take Profit Order Cancelled")
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.