Skip to content

Commit

Permalink
Added some documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Hartmut Bischoff committed May 7, 2015
1 parent 2fbd7fc commit 760f8f5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 43 deletions.
45 changes: 29 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ib-ruby

Ruby Implementation of the Interactive Brokers Trader Workstation (TWS) API v.965-967.
# Development-Branch, Environment: Ruby 2.20, ActiveModel, Rspec3/Guard-Testsuite
## Development-Branch, Environment: Ruby 2.20, ActiveModel, Rspec3/Guard-Testsuite

The hole TWS-Environment is accessible through Ruby-Objects.

Expand All @@ -27,11 +27,22 @@ and tolerates the daily reset of the TWS, and thus enables a 24/7-operation-mode
However, ib-ruby offers a simple translation of ruby-queries to tws-socket-codes and
offers the pure TWS-response as well. The usage of the object-tree is optional.
Any code for previous versions of the programm should work.

For more details refer to the [introduction](intro.md)
and for programming hints the [integration](integration.md) section.

### Changes from the stable branch


* Only ActiveModel/ActiveRecord-Support.
* A IB::Gateway is added. This builds an object-orientated representation of Accounts with pending and completed Orders, Positions and Contracts
* Only ActiveModel-Support.
* Alert-Messages are handled by IB::Alerts
* IB::Stock, IB::Future, IB::Forex are derived from IB::Contract
* IB::Account model added, where contracts, orders, positions and AccountValues are present
* IB::Gateway builds an object-orientated representation of Accounts with pending and completed
Orders, Positions and Contracts. A thread-safe access to objects which are updated concurrently
by the TWS is realized.

An Example
``` ruby
require 'ib'

Expand All @@ -51,24 +62,26 @@ Any code for previous versions of the programm should work.
IB::Gateway.tws.send_message(...)
IB::Gateway.tws.subscribe(...)
```
However, the old way to access the TWS by initializing IB::Connection is still supported. There is even an Object IB::Connection.current, witch points to IB::Gateway.tws

* TWS-queries are working in an asynchronic/ multithreaded environment and can be used with FA-Accounts with multible active and independently managed User-Accounts
* IB::Stock, IB::Option, IB::Future and IB::Forex inherent IB::Contract
* There is a wrapper IB::Contract.update_contract which allows a validation of
the given Contract-Attributes prior to further actions, ie data-retrieving and ordering
The previous way to access the TWS by initializing IB::Connection is still supported.
There is even an Object IB::Connection.current, witch points to IB::Gateway.tws

* TWS-queries are working in an asynchronic/ multithreaded environment
* There is a wrapper IB::Contract.verify which offers a validation of
the given Contract-Attributes prior to further actions, ie data-retrieving and ordering.
* Although Connection#place_order still works, its advisable to use the save place_order method
of IB::Account
``` ruby
require 'ib'

IB::Gateway.new connect:true
gw= IB::Gateway.new connect:true
contract = IB::Stock.new symbol: 'RRD'
buy_order = IB::Order.new total_quantity: 100, limit_price: 21.00,
action: :buy, :order_type: :limit,
tif: 'GTC'
IB::Gateway.tws.subscribe(:OpenOrder) { |msg| puts "Placed: #{msg.order}!" }
IB::Gateway.tws.subscribe(:ExecutionData) { |msg| puts "Filled: #{msg.execution}!" }

contract.update_contract do |msg|
buy_order = IB::Order.new :total_quantity => 100, :limit_price => 21.00,
:action => :buy, :order_type => :limit
IB::Gateway.tws.place_order buy_order, msg.contract

local_id= gw.for_selected_account( 'U123456' ) do |account|
account.place_order order: buy_order, contract: contract
end

```
Expand Down
8 changes: 8 additions & 0 deletions integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## ib-ruby :: Implementation hints

### Accessing IB::Model-Objects

### Handling Alerts

### Access to TWS-Messages

44 changes: 26 additions & 18 deletions intro.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
## ib-ruby – An Introduction
## ib-ruby – Introduction to the Gateway

Ib-ruby is a pure ruby implementation to access the IB-TWS-API.
It mirrors most of the information provided by the tws as Active-Model-Objects.
It mirrors most of the information provided by the TWS as Active-Model-Objects.

### Connect to the TWS

Assuming, the TWS ( FA-Account,»Friends and Family«, is needed ) is running
Assuming, the TWS ( FA-Account, aka »Friends and Family«, is needed ) is running
and API-Connections are enabled, just instantiate IB::Gateway to connect i.e.

```
gw = IB::Gateway.new connect: true, host: 'localhost:7496' , client_id: 1001
# for possible argumets look into lib/ib/gateway.rb
```

The Connection-Object, which provides the status and recieves subscriptions of TWS-Messages, is
Expand All @@ -18,12 +19,16 @@ always present as
```
tws = IB::Connection.tws
or
tws = gw.tws
tws = gw.tws
and also
tws = IB::Connction.current.tws
```
The Gateway acts as a Proxy to the Connection-Object and provides a simple Security-Layer.
The method »connect« waits approx. 1 hour for the TWS to start. IB::Gateway reconnects automatically if the
transmission was interrupted. It is even possible to switch from one TWS to another
The method »connect« without an argument waits approx. 1 hour for the TWS to connect to.
It tries to connect every 60 seconds. The argument detemines the count of repetitions.
IB::Gateway reconnects automatically if the transmission was interrupted.
It is even possible to switch from one TWS to another

```
gw.change_host host: 'new_host:new_port'
Expand All @@ -32,12 +37,12 @@ transmission was interrupted. It is even possible to switch from one TWS to anot
```


### Read Account-Date
### Read Account-Data

If you open the TWS-GUI you get a nice overview of all account-positions, the distribution of
currencies, margin-using, leverage and other account-measures.

These informations are transmitted by the API, too.
These informations are available through the API, too.
One can send a message to the tws and simply wait for the response.

The Gateway handles anything in the background and provides essential account-data
Expand All @@ -49,24 +54,27 @@ in a structured manner:
gw.request_open_orders
Gateway
--- Account
--- PortfolioValues
--- AccountValues
--- Orders
---> Account
---> PortfolioValues
---> AccountValues
---> Orders
---> Contracts
```
IB::Gateway provides an array of active Accounts. One is a Advisor-Account. Several tasks
are delegated to the accounts. An Advisor cannot submit an order for himself. An ordonary User
can only place orders for himself.
IB::Gateway provides an array of active Accounts. One is a Advisor-Account.
Several tasks are delegated to the accounts.
An Advisor cannot submit an order for himself.
A User can only place orders for himself.

The TWS sends data arbitrarily. Ib-ruby has to process them concurrently. Someone has to take care
of possible data-collistions. Therefor its not advisable to access the TWS-Data directly.
IB::Gateway provides wrapper-nethods
IB::Gateway provides thread safe wrapper-nethods
```
gw.for_active_accounts do |account | ... end
gw.for_selected_account( ib_account_id ) do |account| ... end
```
However, Advisor and Users are directly available through
However, if you know what you are doing and no interference with TWS-Messages are expected
Advisor and Users are directly available through
```
gw.advisor --> Account-Object
gw.active_accounts[n] --> Account-Object
Expand Down Expand Up @@ -117,7 +125,7 @@ To retrieve an ordered list this snipplet helps
=> [["682343", "BASE"], ["1829", "AUD"], ["629503", "EUR"], ["-23081", "JPY"], ["56692", "USD"]]
```

Open (pending) Orders are retrieved by »gw.request_open_orders«. IB::Gateway, in this case the module
Open (pending) Orders are retrieved by *»gw.request_open_orders«*. IB::Gateway, in this case the module
OrderHandling (in ib/order_handling.rb) updates the »orders«-Array of each Account.
The Account#orders-Array consists of IB::Order-Entries:

Expand Down
22 changes: 13 additions & 9 deletions lib/ib/gateway.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@ module IB
The Gateway-Class defines anything which has to be done before a connection can be established.
The Default Skeleton can easily be substituted by customized actions
The IB::Gateway can be used in two different modes
(1) IB::Gateway.new( connect:true ) do | gateway |
{ subscribe to Messages and define the response }
# This is declared before a connect-attempt is made
# The method waits until the connection is ready
The IB::Gateway can be used in three modes
(1) IB::Gateway.new( connect:true, --other arguments-- ) do | gateway |
** subscribe to Messages and define the response **
# This block is executed before a connect-attempt is made
end
(2) gw = IB:Gateway.new
{subscribe to Messages }
** subscribe to Messages **
gw.connect
(3) IB::Gateway.new connect:true, host: 'localhost' ....
Independently IB::Alert.alert_#{nnn} should be defined for a proper response to warnings, error-
and system-messages
and system-messages.
The Connection to the TWS is realized throught IB::Connection. Instead of the previous
Singleton IB::Connection.current now IB::Gateway.tws points to the active Connection.
Singleton IB::Connection.current
now IB::Gateway.tws points to the active Connection.
However, to support asynchronic access, the :recieved-Array of the Connection-Class is not active.
The Array is easily confused, if used in production mode with a FA-Account.
IB::Conncetion.wait_for(message) is not available.
IB::Conncetion.wait_for(message) is not available until the programm is called with
IB::Connection.new serial_array: false, (...)
=end

Expand Down

0 comments on commit 760f8f5

Please sign in to comment.