rib icon indicating copy to clipboard operation
rib copied to clipboard

Getting started

Open ghost opened this issue 6 years ago • 14 comments

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
> 

ghost avatar Apr 16 '19 16:04 ghost

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 ActiveX is checked Configuration->API->Settings->Socket port 7496 (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.

lbilli avatar Apr 16 '19 18:04 lbilli

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 avatar Apr 16 '19 18:04 ghost

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 avatar Apr 16 '19 19:04 ghost

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) 

ghost avatar Apr 16 '19 19:04 ghost

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

lbilli avatar Apr 16 '19 20:04 lbilli

> 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

ghost avatar Apr 16 '19 20:04 ghost

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)

lbilli avatar Apr 16 '19 20:04 lbilli

> 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

ghost avatar Apr 16 '19 20:04 ghost

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?

lbilli avatar Apr 16 '19 21:04 lbilli

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 avatar Apr 17 '19 13:04 ghost

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) 

ghost avatar Apr 17 '19 14:04 ghost

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()

lbilli avatar Apr 17 '19 15:04 lbilli

> 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
> 

ghost avatar Apr 17 '19 16:04 ghost

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.

lbilli avatar Apr 18 '19 11:04 lbilli