简体   繁体   中英

R IBrokers reqopenorders not updating

I am querying the list of pending orders in TWS Interactive Brokers using codes from the IBrokers package.

The function reqOpenOrders(tws) has an error in it, in that it hangs as shown here , and even when it works the outputs are messy as shown here .

I have put together some snipes of code from different sources to create a function that is clear/logical to understand, while outputting a data.frame of the results.

The function is below, and it works well the first time that is used. However, when a change is done in TWS (like cancelling a pending order, or placing a trail order), the change is not updated if the function below is run in R.

If I close and open again the connection to TWS, I get a empty data.frame after running the function below. if I close all connections and try the function several times eventually it returns the updated results.

Does any one know why calling the function does not query the most updated changes in TWS?

I think it has something to do with R connectivity to TWS. It seems the function waits for the connection to eventually become available. If I restart R, the first time I run the function, the results are updated, suggesting that if all connections are restored the function works well. Any suggestion to this problem?

I wonder if all sockets and connections need to be closed after exiting the function? I tried different versions to this solution with no success.

Any help is greatly appreciated.

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)

This is probably not the best solution, but I found a way around getting the most updated data on open orders from TWS. The original function above seems to work only when the right connection is used. In between tries, it returns an empty data.frame. So what I did was to create a while loop that sends queries to TWS until the right connection is used. The code is below. It works and returns the right data after a handful of attempts. I figure I share the code as a temporary solution.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM