44
55Originally inspired by [ ` IBrokers ` ] ( https://CRAN.R-project.org/package=IBrokers ) ,
66` rib ` is a native [ R] ( https://www.r-project.org/ ) client that
7- implements [ Interactive Brokers] ( https://www.interactivebrokers.com/ ) API
8- to communicate with their TWS or IBGateway.
7+ implements the [ Interactive Brokers] ( https://www.interactivebrokers.com/ ) API
8+ to communicate with TWS or IBGateway.
99
1010It aims to be feature complete, however it does not support legacy versions.
1111Currently, only API versions ` v165+ ` are supported.
1212
1313The package design mirrors the official C++/Java
1414[ IB API] ( https://interactivebrokers.github.io/tws-api/ ) ,
15- which is based on an asynchronous request-response communication model
16- over TCP.
15+ which is based on an asynchronous communication model over TCP.
1716
1817### Installation
1918To install from GitHub,
@@ -26,9 +25,9 @@ remotes::install_github("lbilli/rib")
2625### Usage
2726The user interacts mainly with two classes, implemented as
2827[ ` R6 ` ] ( https://CRAN.R-project.org/package=R6 ) objects:
29- - ` IBClient ` : responsible to establish the connection and send requests to the server.
30- - ` IBWrap ` : base class holding the callbacks that are executed when the
31- client processes the responses. Customized versions are derived from this class.
28+ - ` IBClient ` : responsible to establish the connection and send requests to the server
29+ - ` IBWrap ` : base class holding the callbacks that are executed when responses
30+ are processed. User customizations are derived from this class.
3231
3332Other data structures, such as ` Contract ` and ` Order ` , are implemented as R lists,
3433or nested lists, and mirror the respective classes of the official IB API.
@@ -65,35 +64,35 @@ IBWrapCustom <- R6::R6Class("IBWrapCustom",
6564
6665# Instantiate wrapper and client
6766wrap <- IBWrapCustom $ new()
68- ic <- IBClient $ new(wrap )
67+ ic <- IBClient $ new()
6968
7069# Connect to the server with clientId = 1
7170ic $ connect(port = 4002 , clientId = 1 )
7271
7372# Check connection messages (optional)
74- ic $ checkMsg()
73+ ic $ checkMsg(wrap )
7574
7675# Define contract
77- contract <- IBContract(" GOOG" )
76+ contract <- IBContract(symbol = " GOOG" , secType = " STK " , exchange = " SMART " , currency = " USD " )
7877
7978# Define order
80- order <- IBOrder(" BUY" , 10 , " LMT" , 1000 )
79+ order <- IBOrder(action = " BUY" , totalQuantity = 10 , orderType = " LMT" , lmtPrice = 1000 )
8180
8281orderId <- 1 # Should match whatever is returned by the server
8382
8483# Send order
8584ic $ placeOrder(orderId , contract , order )
8685
87- # Check messages
88- ic $ checkMsg()
86+ # Check inbound messages
87+ ic $ checkMsg(wrap )
8988
9089# Disconnect
9190ic $ disconnect()
9291```
9392
94- As R is single threaded, in general it is the user's responsability to code
95- an event loop that handles the request-response pattern :
96- _ i.e._ there is no ` Reader ` in the background monitoring the connection
93+ As R is single threaded, in general it is the user's responsibility to code
94+ some kind of event loop to periodically process incoming messages :
95+ _ i.e._ there is no background ` Reader ` monitoring the connection
9796and processing the server responses.
9897
9998Two possible approaches, with or without a loop, are described:
@@ -111,18 +110,18 @@ library(rib)
111110
112111# Instantiate wrapper, client and connect
113112wrap <- IBWrapSimple $ new()
114- ic <- IBClient $ new(wrap )
113+ ic <- IBClient $ new()
115114ic $ connect(port = 4002 , clientId = 1 )
116115
117116# Send requests, e.g.:
118- contract <- IBContract(" GOOG" )
117+ contract <- IBContract(symbol = " GOOG" , secType = " STK " , exchange = " SMART " , currency = " USD " )
119118ic $ reqContractDetails(11 , contract )
120119
121120# more requests can go here...
122121
123122# Parse responses
124123# Might need to be called several times to exhaust all messages
125- ic $ checkMsg()
124+ ic $ checkMsg(wrap )
126125
127126# Find results in
128127wrap $ context
@@ -145,7 +144,7 @@ library(rib)
145144
146145# Instantiate wrapper, client and connect
147146wrap <- IBWrapSimple $ new()
148- ic <- IBClient $ new(wrap )
147+ ic <- IBClient $ new()
149148ic $ connect(port = 4002 , clientId = 1 )
150149
151150# Main loop
@@ -156,7 +155,7 @@ repeat {
156155 ic $ reqContractDetails(... )
157156
158157 # Wait and process responses
159- ic $ checkMsg()
158+ ic $ checkMsg(wrap )
160159
161160 if (done )
162161 break
@@ -173,33 +172,31 @@ ic$disconnect()
173172
174173##### [ ` IBClient ` ] ( R/IBClient.R )
175174This implements the IB ` EClient ` class functionality. Among its methods:
176- - ` new(wrap) ` : constructor. Require an object derived from ` IBWrap ` as argument.
177- - ` replaceWrap(wrap) ` : replace the ` wrap ` . As the client runs in a single thread,
178- it is possible to swap wrappers on the fly in a connected client.
175+ - ` new() ` : create a new instance.
179176- ` connect(host, port, clientId, connectOptions) ` : establish a connection.
180177- ` disconnect() ` : terminate the connection.
181- - ` checkMsg(timeout, flush) ` : wait for responses and dispatch callbacks.
178+ - ` checkMsg(wrap, timeout) ` : wait for responses and dispatch callbacks defined
179+ in ` wrap ` , which must be an instance of a class derived from ` IBWrap ` .
182180 If no response is available, it ** blocks** up to ` timeout ` seconds.
183- If ` flush=TRUE ` callbacks are not dispatched .
184- Return the number of responses processed. ** Needs to be called regularly** .
185- - methods that send specific requests to the server.
181+ If ` wrap ` is missing, messages are taken off the wire and discarded .
182+ Return the number of responses processed. ** Needs to be called regularly! **
183+ - methods that send requests to the server.
186184 Refer to the official IB ` EClient ` class documentation for further details and
187185 method signatures.
188186
189187##### [ ` IBWrap ` ] ( R/IBWrap.R )
190188Like the official IB ` EWrapper ` class, this holds the callbacks that are dispatched
191- when responses are processed. ` IBWrap ` itself is a base class containing
192- only dummy methods.
189+ when responses are processed. ` IBWrap ` itself contains only stubs.
193190Users need to derive from it and override the desired methods.
194- The code [ above] ( #usage ) provides a quick view of the procedure.
191+ The code [ above] ( #usage ) provides a template of the procedure.
195192
196193For a more extensive example refer to the definition of
197- [ ` IBWrapSimple ` ] ( R /IBWrapSimple.R) , which is provided for
198- illustrative purposes and which prints out the content of the responses or store it
199- within ` IBWrapSimple$context ` for later inspection.
194+ [ ` IBWrapSimple ` ] ( examples /IBWrapSimple.R) , mainly provided for
195+ illustrative purposes, which simply prints out the content of the responses
196+ or store it within ` IBWrapSimple$context ` for later inspection.
200197
201198For more details about callback definitions and signatures,
202- refer again to the official IB ` EWrapper ` class documentation.
199+ refer to the official IB ` EWrapper ` class documentation.
203200
204201### Notes
205202Callbacks are generally invoked with arguments and types matching the signatures
@@ -226,21 +223,21 @@ are **not** used in this package.
226223` marketRule() ` and the ` historicalTicks*() ` family.
227224
228225##### Missing Values
229- Occasionally there is the need for numerical types to represent
226+ Occasionally, for numerical types, there is the need to represent
230227the lack of a value.
231228
232- The IB API does not adopt a uniform solution for all situations , but rather
233- various sentinel values are used .
229+ IB API does not have a uniform solution across the board , but rather
230+ it adopts a variety of sentinel values .
234231They can be either the plain ` 0 ` or the largest representable value
235232of a given type such as ` 2147483647 ` and ` 9223372036854775807 `
236- for 32 and 64 bit integers respectively or ` 1.7976931348623157E308 `
237- for 64 bit floating point.
233+ for 32- and 64- bit integers respectively or ` 1.7976931348623157E308 `
234+ for 64- bit floating point.
238235
239- Within this package an effort is made to replace all these values with
240- R built- in ` NA ` .
236+ This package makes an effort to use R built-in ` NA `
237+ in all circumstances .
241238
242239##### Data Structures
243- Other classes that mainly hold data are also [ defined ] ( R/structs.R ) .
240+ Other classes that mainly hold data are also [ replicated ] ( R/structs.R ) .
244241They are implemented as R lists, possibly nested, with names, types and default values
245242matching the IB API counterparts: _ e.g._
246243` Contract ` , ` Order ` , ` ComboLeg ` , ` ExecutionFilter ` , ` ScannerSubscription `
@@ -253,9 +250,9 @@ contract$conId <- 12345
253250contract $ currency <- " USD"
254251```
255252In the case of ` Contract ` and ` Order ` , helper [ functions] ( R/factory.R )
256- are also provided to prefill some common fields:
253+ are also provided to simplify the assignment to a subset of the fields:
257254``` R
258- contract <- IBContract(" GOOG" )
255+ contract <- IBContract(symbol = " GOOG" , secType = " STK " , exchange = " SMART " , currency = " USD " )
259256
260257# Equivalent to
261258contract <- Contract
@@ -266,7 +263,7 @@ contract$currency <- "USD"
266263```
267264and
268265``` R
269- order <- IBOrder(totalQuantity = 100 , lmtPrice = 50 )
266+ order <- IBOrder(action = " BUY " , totalQuantity = 100 , orderType = " LMT " , lmtPrice = 50 )
270267
271268# Equivalent to
272269order <- Order
0 commit comments