lbilli / rib

An R implementation of Interactive Brokers API
GNU General Public License v3.0
34 stars 7 forks source link

Getting started #2

Open ghost opened 5 years ago

ghost commented 5 years ago

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
> 
lbilli commented 5 years ago

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:

wrap <- IBWrapSimple$new() ic <- IBClient$new(wrap) ic$connect(port=7496, clientId=1)


and let me know if the error persists.
ghost commented 5 years ago

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.

ghost commented 5 years ago

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

ghost commented 5 years ago

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) 
lbilli commented 5 years ago

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

ghost commented 5 years ago
> 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
lbilli commented 5 years ago

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)
ghost commented 5 years ago
> 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
lbilli commented 5 years ago

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?

ghost commented 5 years ago

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
ghost commented 5 years ago

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) 
lbilli commented 5 years ago

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()
ghost commented 5 years ago
> 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
> 
lbilli commented 5 years ago

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.