rib
rib copied to clipboard
Getting started
Hi, first at all, thank so much for the package.
I'm trying to test the req/resp example and I getting an error in the connection:
> wrap <- IBWrapSimple$new()
> ic <- IBClient$new(wrap)
> ic$connect(port=7496, clientId=1)
Error: length(res) == 2L is not TRUE
I'm using TWS972.
For other hand, I'm getting the following functions' output:
> ic$serVersion
NULL
> ic$isOpen
[1] TRUE
> ic$reqCurrentTime()
> ic$checkMsg(2000)
[1] 0
>
First of all, thanks for your feedback.
Now, that's an odd error that I rarely encountered before, however as I was trying to reproduce that behavior, it happened to me too. But it went away after restarting TWS, so it's not easy to debug.
I'd like to ask you try few things:
-
first make sure that in TWS:
Configuration->API->Settings->Enable ActiveXis checkedConfiguration->API->Settings->Socket port7496 (or whatever you like) -
then restart TWS and try again the example: i.e. paste in a new R session:
library(rib)
wrap <- IBWrapSimple$new()
ic <- IBClient$new(wrap)
ic$connect(port=7496, clientId=1)
and let me know if the error persists.
I've tried and restarted with: (checking the port and the Enable ActiveX)
TWS963 TWS972 GTW975
I'm using MacOS 10.14.4
I think it might be related to the Mac socket.
Changing the endian to swap (line 72 from IBClient.R) seems to be moving forward.
header <- writeBin(len, raw(), size=HEADER_LEN, endian="swap")
Now I'm getting the following error related with the version:
> ic$connect(port=7496, clientId=1)
Hide Traceback
Rerun with Debug
Error in paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER, connectOptions) :
object 'MIN_CLIENT_VER' not found
4. paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER, connectOptions)
3. stopifnot(is.character(msg), !is.na(msg)) at IBClient.R#54
2. private$encodeMsg(paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER,
connectOptions), api_sign = TRUE) at IBClient.R#267
1. ic$connect(port = 7496, clientId = 1)
TWS963
and after hardcode these variables: MIN_CLIENT_VER MAX_CLIENT_VER MAX_MSG_LEN HEADER_LEN API_SIGN
I get the initial error:
> ic$connect(port=7496, clientId=1)
Hide Traceback
Rerun with Debug
Error: length(res) == 2L is not TRUE
3. stop(msg, call. = FALSE, domain = NA)
2. stopifnot(length(res) == 2L) at IBClient.R#278
1. ic$connect(port = 7496, clientId = 1)
It might about endianess...
Out of curiosity, if you don't mind, could you paste the following in a R session and report back the output?
txt <- as.raw(c(0,0,0,0x1a))
writeBin(10L, raw(), size=4, endian="big")
writeBin(10L, raw(), size=4, endian="little")
readBin(txt, integer(), size=4, endian="big")
readBin(txt, integer(), size=4, endian="little")
Thanks
> txt <- as.raw(c(0,0,0,0x1a))
> writeBin(10L, raw(), size=4, endian="big")
[1] 00 00 00 0a
> writeBin(10L, raw(), size=4, endian="little")
[1] 0a 00 00 00
> readBin(txt, integer(), size=4, endian="big")
[1] 26
> readBin(txt, integer(), size=4, endian="little")
[1] 436207616
Well, that's what I get.
Could you try pasting this in R, while a fresh TWS is listening on 7496?
port <- 7496
msg <- as.raw(c(charToRaw("API"), 0L, 0L, 0L, 0L, 10L, charToRaw("v101..151"), 0L))
msg
ss <- socketConnection(port=port, open="r+b")
writeBin(msg, ss)
Sys.sleep(2)
len <- readBin(ss, integer(), size=4, endian="big")
len
readBin(ss, raw(), n=len)
> port <- 7496
> msg <- as.raw(c(charToRaw("API"), 0L, 0L, 0L, 0L, 10L, charToRaw("v101..151"), 0L))
> msg
[1] 41 50 49 00 00 00 00 0a 76 31 30 31 2e 2e 31 35 31 00
> ss <- socketConnection(port=port, open="r+b")
> writeBin(msg, ss)
> Sys.sleep(2)
> len <- readBin(ss, integer(), size=4, endian="big")
> len
[1] 26
> readBin(ss, raw(), n=len)
[1] 31 31 38 00 32 30 31 39 30 34 31 36 20 32 32 3a 35 37 3a 30 32 20 43 45 54 00
Well, that looks correct: the handshake with TWS is successful. I'd rule out endianness issues.
My next suspect would be socketSelect() and this issue caught my attention.
Are you on RStudio? If so, could you try a plain R session?
From R terminal:
> getRversion()
[1] ‘3.5.0’
> library(rib)
> wrap <- IBWrapSimple$new()
> ic <- IBClient$new(wrap)
> ic$connect(port=7496, clientId=1)
Error in ic$connect(port = 7496, clientId = 1) :
length(res) == 2L is not TRUE
It is curious if I force to use R 3.3.3 (changing the DESCRIPTION file and build again the package) the error is about the object MIN_CLIENT_VER, and then MAX_CLIENT_VER, MAX_MSG_LEN, HEADER_LEN and API_SIGN.
> library(rib)
> # Instantiate wrapper, client and connect
> wrap <- IBWrapSimple$new()
> ic <- IBClient$new(wrap)
> ic$connect(port=7496, clientId=1)
Hide Traceback
Rerun with Debug
Error in paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER, connectOptions) :
object 'MIN_CLIENT_VER' not found
4. paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER, connectOptions)
3. stopifnot(is.character(msg), !is.na(msg)) at IBClient.R#54
2. private$encodeMsg(paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER,
connectOptions), api_sign = TRUE) at IBClient.R#267
1. ic$connect(port = 7496, clientId = 1)
I tried removing socketSelect().
Could you try the following?
remotes::install_github("lbilli/rib", "issue2")
library(rib)
ew <- IBWrapSimple$new()
ic <- IBClient$new(ew)
ic$connect(port=7496)
ic$checkMsg()
> ic$connect(port=7496)
Hide Traceback
Rerun with Debug
Error in is.character(msg) : object 'MIN_CLIENT_VER' not found
9. stop(e)
8. value[[3L]](cond)
7. tryCatchOne(expr, names, parentenv, handlers[[1L]])
6. tryCatchList(expr, classes, parentenv, handlers)
5. tryCatch(if (missE) ...elt(i) else eval(cl.i, envir = envir),
error = function(e) {
e$call <- cl.i
stop(e) ...
4. withCallingHandlers(tryCatch(if (missE) ...elt(i) else eval(cl.i,
envir = envir), error = function(e) {
e$call <- cl.i
stop(e) ...
3. stopifnot(is.character(msg), !is.na(msg)) at IBClient.R#54
2. private$encodeMsg(paste0("v", MIN_CLIENT_VER, "..", MAX_CLIENT_VER,
connectOptions), api_sign = TRUE) at IBClient.R#267
1. ic$connect(port = 7496)
> ic$checkMsg()
[1] 0
>
That looks more like a namespace issue... maybe due to sourcing some files individually (e.g. IBClient.R) rather than loading the package as a whole.
Anyways, I think I'll have to put this on hold until I get access to a Mac myself in order to deal with it properly.