[R-SIG-Finance] how to get quotes with IBrokers
Jeff Ryan
jeff.a.ryan at gmail.com
Wed Aug 18 18:18:36 CEST 2010
To answer the *actual* question you posed, regarding R and IBrokers
(not Excel and Yahoo!?)
In the talks I have given at useR and R/Finance I have a slide/video
that addresses this issue. As Russ pointed out in his reply, the TWS
has some rather picky rules to keep in mind, so caveat emptor as
always.
snapshot=TRUE in the API is really useless - this is a design flaw of
the API (not IBrokers). It doesn't assure timeliness of the data,
even IF it managed to do things quickly - which it doesn't do either.
IBrokers maps to the API and leaves you the user with the burden of
dealing with the APIs warts.
Of course I also made the functions R like where possible (fixing the
API, if you will)...
The workaround is exactly what you are pursuing. The weakness at
present is in the error handling - at present the code I will paste
below chokes if it encounters a bad ticker. I'll work on a patch to
make that ugliness go away.
With that in mind ...
# some symbols to start with ..
> nms <- c("AAPL","YHOO","AMZN","CSCO","BBY","A","AAR","AA","PCM","PEP","SAP","ZMH","MSFT")
> reqMktData(tws, lapply(nms,twsSTK), eventWrapper=eWrapper.data(length(nms)),CALLBACK=snapShot)
BidSize BidPrice AskPrice AskSize Last LastSize Volume
AAPL 7 252.92 253.00 3 253.00 1 40937
YHOO 138 13.89 13.90 474 13.89 1 29920
AMZN 4 128.87 128.92 1 128.93 1 17413
CSCO 346 22.30 22.31 631 22.30 2 206266
BBY 6 32.95 32.96 44 32.95 1 11780
A 32 29.17 29.18 30 29.18 3 12172
AAR 7 21.81 21.85 1 21.85 1 87
AA 372 10.84 10.85 536 10.85 2 70867
PCM 4 10.87 10.95 2 10.85 12 41
PEP 10 65.42 65.43 1 65.44 1 6528
SAP 11 45.28 45.30 9 45.30 1 2197
ZMH 1 51.48 51.49 21 51.48 1 3458
MSFT 453 24.56 24.57 661 24.55 1 136815
> system.time( reqMktData(tws, lapply(nms,twsSTK), eventWrapper=eWrapper.data(length(nms)),
user system elapsed
0.259 0.004 0.889
Extending to 500 symbols or so is doable as well, though takes more
time to fetch. I am breaking it up into 100 symbol chunks, as I think
you might have some issues that Russ alluded to if you don't ... but
experimenting is easy with R.
> nms100 <- rep(nms[1:10],10)
> reqMktData(tws, lapply(nms100,twsSTK), eventWrapper=eWrapper.data(length(nms100)),CALLBACK=snapShot)
> system.time( reqMktData(tws, lapply(nms100,twsSTK), eventWrapper=eWrapper.data(length(nms100)),CALLBACK=snapShot) )
user system elapsed
10.931 0.054 11.038
> str(reqMktData(tws, lapply(nms100,twsSTK), eventWrapper=eWrapper.data(length(nms100)),CALLBACK=snapShot))
'data.frame': 100 obs. of 7 variables:
$ BidSize : num 1 299 1 400 20 36 5 215 4 35 ...
$ BidPrice: num 253.8 13.9 129.2 22.3 33 ...
$ AskPrice: num 253.8 13.9 129.3 22.4 33 ...
$ AskSize : num 2 192 1 937 24 34 4 434 4 7 ...
$ Last : num 253.8 13.9 129.2 22.4 33 ...
$ LastSize: num 2 1 1 1 1 1 2 1 1 1 ...
$ Volume : num 45476 34769 19535 235881 16038 ...
The "snapShot" code is only twsCALLBACK modified in 2 places...
> dput(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)))
}
}
}
The lines changed are:
names(eWrapper$.Data$data) <- eWrapper$.Data$symbols
and:
if (!any(sapply(eWrapper$.Data$data, is.na)))
return(do.call(rbind, lapply(eWrapper$.Data$data,
as.data.frame)))
HTH
Jeff
On Tue, Aug 17, 2010 at 11:20 PM, zerdna <azege at yahoo.com> wrote:
>
> Hi, i need to get a quotes for a large set of stocks at 5 min after the open.
> I am trying to use IBrokers, but frankly not making much progress. I
> understand that i need to use reqMktData. It seems that taking snapshot is
> what i need, but when i do something like
>
> df<-reqMktData(tws, lapply(nms, twsSTK), tickGenerics="", snapshot=T),
>
> where nms is my vector of tickers,
>
> i get a dataframe back after waiting for a while -- about 12 sec per ticker,
> which comes out to more than 1.5 hours for my list of 500 tickers. Also,
> most of the data is NA. Maybe it has to do with stocks on the list being
> relatively illiquid or maybe i am doing something wrong. Could someone
> comment, please?
>
> I looked into not using snapshot and try instead to use
> myWrapper <- eWrapper.MktData.CSV(1) and
> myWrapper$get.Data("data") . While i could do it for one stock by manually
> interrupting reqMktData and getting last quote, i cannot figure out what
> needs to be done for a list of stocks. Do i need to repeat reqMktData and
> somehow programmatically interrupt inside the loop? Do i modify twsCALLBACK
> to return after gathering full quote? Would really appreciate any pointers,
> references, or help of any kind.
>
> --
> View this message in context: http://r.789695.n4.nabble.com/how-to-get-quotes-with-IBrokers-tp2329328p2329328.html
> Sent from the Rmetrics mailing list archive at Nabble.com.
>
> _______________________________________________
> R-SIG-Finance at stat.math.ethz.ch 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
jeff.a.ryan at gmail.com
More information about the R-SIG-Finance
mailing list