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)