[R-SIG-Finance] IBrokers
Jeff Ryan
jeff.a.ryan at gmail.com
Mon Dec 6 00:17:04 CET 2010
Stephen,
Comments inline:
On Sun, Dec 5, 2010 at 1:23 PM, Stephen Choularton
<stephen at organicfoodmarkets.com.au> wrote:
> Hi
>
> If you read this list you will have noticed I have been working on callbacks
> and I finally got to some code that appears to work so I though I would
> share it:
>
> library(IBrokers)
>
> myCALLBACK <-
> function(twsCon, eWrapper, timestamp, file, playback = 1, ...) {
> con <- twsCon[[1]]
> twsOC <- twsConnect(2) # our order connection
> con2 <- twsOC[[1]]
> ocWrapper <- eWrapper(TRUE)
> traded <- FALSE
> while (TRUE) {
> cons <- socketSelect(list(con, con2), FALSE, 0.01)
> if(cons[1]) { #data
> curMsg <- readBin(con, character(), 1)
> if (!is.null(timestamp)) {
> processMsg(curMsg, con, eWrapper, format(Sys.time(),
> timestamp), file, ...)
> } else {
> processMsg(curMsg, con, eWrapper, timestamp, file, ...)
> }
> } else if(cons[2]) {
> curMsg <- readBin(con2, character(), 1)
> if (!is.null(timestamp)) {
> processMsg(curMsg, con2, ocWrapper, format(Sys.time(),
> timestamp), file, ...)
> } else {
> processMsg(curMsg, con2, ocWrapper, timestamp, file, ...)
> }
> } # TRADE LOGIC HERE
> curBID <- as.numeric(eWrapper$.Data$data[[1]][3])
> if(!traded ) { # add back on open: && !is.na(curBID) && curBID >
> 141.00
>
> print(c("the cur bid is ", curBID))
> # IBrokers:::.placeOrder(twsOC, twsEquity("CBA","ASX","AUD"),
> twsOrder(1053, "BUY", "0", "MKT"))
> traded <- TRUE
> }
> }
> twsDisconnect(twsOC)
> }
>
> con = twsConnect(1)
>
> # contracts <- list(twsSTK("MSFT"),twsSTK("AAPL")))
>
>
> reqMktData(con, twsEquity("GOOG"), CALLBACK=myCALLBACK)
>
> twsDisconnect(con)
>
> However, even though I have tried to close down my twsCnnections, if I run
> the code twice I get a warning along the lines:
>
> unable to connect. client id already in use. retry with unique client id
>
> and R freezes. Does anyone know how to solve the problem?
R is likely "freezing" due to buffering on Windows (which you can turn
off in the GUI), but that isn't really the core issue. You don't need
to have a second connection opened in the CALLBACK. It is in the
examples of one of my talks to illustrate having an external mkt data
feed and IB execution. If you are only looking at IB (for data and
execution), DON'T use a second connection. Seriously it is not needed
at all, and it is just making things more confusing I suspect.
>From there (on connection) close(con) or twsDisconnect(con) should
indeed free up the client id. You can always go the route of
closeAllConnections() route in R to 'start over'.
>
> Incidentally I notice that the code gets curBID <-
> as.numeric(eWrapper$.Data$data[[1]][3]). Does anyone know what the
> appropriate indices are for the other data in eWrapper$.Data and what that
> data is?
>
As Mark points out in his reply, look at the source for the answers/hints:
In order: BidSize, BidPrice, AskPrice, AskSize, Last, LastSize and
Volume. The first four ordering mimic what it looks like when you
stand in the pit on the floor and look at the CRTs (or your own custom
screen...) ;-)
# from the source
> eWrapper.data
function (n)
{
eW <- eWrapper(NULL)
eW$assign.Data("data", rep(list(structure(.xts(matrix(rep(NA_real_,
7), nc = 7), 0), .Dimnames = list(NULL, c("BidSize",
"BidPrice", "AskPrice", "AskSize", "Last", "LastSize",
"Volume")))), n))
eW$tickPrice <- function(curMsg, msg, timestamp, file, ...) {
tickType = msg[3]
msg <- as.numeric(msg)
id <- msg[2]
data <- eW$get.Data("data")
attr(data[[id]], "index") <- as.numeric(Sys.time())
nr.data <- NROW(data[[id]])
if (tickType == .twsTickType$BID) {
data[[id]][nr.data, 1:2] <- msg[5:4]
}
else if (tickType == .twsTickType$ASK) {
data[[id]][nr.data, 3:4] <- msg[4:5]
}
else if (tickType == .twsTickType$LAST) {
data[[id]][nr.data, 5] <- 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$BID_SIZE) {
data[[id]][nr.data, 1] <- msg[4]
}
else if (tickType == .twsTickType$ASK_SIZE) {
data[[id]][nr.data, 4] <- msg[4]
}
else if (tickType == .twsTickType$LAST_SIZE) {
data[[id]][nr.data, 6] <- msg[4]
}
else if (tickType == .twsTickType$VOLUME) {
data[[id]][nr.data, 7] <- msg[4]
}
eW$assign.Data("data", data)
c(curMsg, msg)
}
return(eW)
}
<environment: namespace:IBrokers>
You can of course do whatever you like to make it more logical to you.
Reading IBrokers source and the official Java source (yikes) is the
way to get to a different end if you so require.
Best,
Jeff
>
>
>
> --
> Stephen Choularton Ph.D., FIoD
>
> _______________________________________________
> R-SIG-Finance at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions
> should go.
>
--
Jeffrey Ryan
jeffrey.ryan at lemnica.com
www.lemnica.com
More information about the R-SIG-Finance
mailing list