我刚刚开始使用IBrokers包,我想知道一旦tickGenerics被填充,如何正确地退出reqMktData函数。谢谢你的回答。例如:
library(IBrokers)
PATH <- ""
# initialize log file
fnIB <- paste(PATH,"IBlog.csv",sep="")
if( file.exists(fnIB) )
file.remove(fnIB)
tws <- twsConnect()
file.csv <- file(fnIB,open="wa")
reqMktData(tws, twsEquity("SPY", "SMART"),tickGenerics="456",file=file.csv)
close(file.csv)
twsDisconnect(tws)
感谢您的帮助。以下是snapShot函数所在代码的答案(我花了一些时间来了解发生了什么,并设置了一个有效的调试策略…)
library(IBrokers)
tws <- twsConnect()
aaz <- reqMktData(tws,twsSTK("SPY"),tickGenerics="456",eventWrapper=eWrapper.mydata(1),CALLBACK=snapShot)
twsDisconnect(tws)
其中
eWrapper.mydata <- function (n)
{
eW <- eWrapper(NULL)
eW$assign.Data("data", rep(list(structure(.xts(matrix(rep(NA_real_,
9), ncol = 9), 0), .Dimnames = list(NULL, c("BidSize",
"BidPrice", "AskPrice", "AskSize", "Last", "LastSize",
"Volume","Ex-Date","Amount")))), 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 <- 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)
}
eW$tickString <- function(curMsg, msg, timestamp, file, ...) {
data <- eW$get.Data("data")
tickType = msg[3]
id <- as.numeric(msg[2])
attr(data[[id]], "index") <- as.numeric(Sys.time())
nr.data <- NROW(data[[id]])
if (tickType == 59) {
data[[id]][nr.data, 8:9] <- unlist(strsplit(msg[4],","))[3:4]
}
eW$assign.Data("data", data)
c(curMsg, msg)
}
return(eW)
}
对于多个ticker(请参阅下面的代码),它不起作用,因为只有一个安全性可以获得tickGenerics(它指的是tickString函数的"456"…)信息。
nms <- c("LQD","JNK")
bbz <- reqMktData(tws,lapply(nms,twsSTK),tickGenerics="456",eventWrapper=eWrapper.mydata(length(nms)),CALLBACK=snapShot)
为了避免IB提供NA字段,"数据"结构应该用-1初始化。因此进行了以下修改:
is.negative <- function (x) {
tmp <- FALSE
if (is.numeric(x)) tmp <- (x<0)
return (tmp)
}
eWrapper.mydata <- function (n)
{
eW <- eWrapper(NULL)
eW$assign.Data("data", rep(list(structure(.xts(matrix(rep(-1, 2), ncol = 2), 0), .Dimnames = list(NULL, c("Ex-Date","Amount")))), n))
eW$tickString <- function(curMsg, msg, timestamp, file, ...) {
data <- eW$get.Data("data")
tickType = msg[3]
#print(paste("curMsg",curMsg,"tickString",tickType,sep=" "))
#print(msg)
id <- as.numeric(msg[2])
attr(data[[id]], "index") <- as.numeric(Sys.time())
nr.data <- NROW(data[[id]])
if (tickType == 59) {
data[[id]][nr.data, 1:2] <- unlist(strsplit(msg[4],","))[3:4]
}
#print(data)
eW$assign.Data("data", data)
c(curMsg, msg)
}
return(eW)
}
snapShot <- function (twsCon, eWrapper, timestamp, file, playback = 1, ...)
{
if (missing(eWrapper)) eWrapper <- eWrapper()
names(eWrapper$.Data$data) <- eWrapper$.Data$symbols
con <- twsCon[[1]]
# print("snapShot")
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))
# print(paste("snapShot curMsg: ",curMsg,sep=""))
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.negative)))
return(do.call(rbind, lapply(eWrapper$.Data$data, as.data.frame)))
}
}
}