ib-api provides IB::Connection.new to connect to the TWS/Gateway.

ib = IB::Connection.new host: '127.0.0.1:4002', # IB Gateway(Papertrading) connection  4001:  production
                         # or 'localhost:7497'  # TWS       (Papertrading)             7496:  production

If called without arguments, it connects through port 4002 to a locally running gateway (Papertrade).

Operating States

A simple workflow is implemented. After initialisation, the program is in its virgin state. try_connection! connects and triggers a transition to the ready state. disconnect! cuts the connection and triggers a transition to the disconnected state.

State   Event   State
virgin try_connection ready
  activate_managed_accounts gateway_mode
ready disconnect disconnected
  activate_managed_accounts gateway_mode
gateway_mode initialize_managed_accounts account_based_operations
account_base_operations disconnect disconnected
disconnected try_connection ready
  activate_managed_accounts gateway_mode

Events are triggered simply by adding a “!” to the event name.

ib = IB::Connection.new 
ib.workflow_state                     =>  nil
ib.try_connection!
ib.workflow_state                     =>  ready
ib.disconnect!
ib.workflow_state                     =>  disconnected

Reconnect

To restore the Operating State after Disconnect, IB::Connection.current.reconnect is provided.
Individual subscriptions are cancelled, associated subscriptions are restored.

Connection#reconnect is aimed to respond to IB::TransmissionError-Events.

u = ib.clients.first
initial_order_state = u.orders
begin
 u.place order: IB::Limit.order( size: 100, price: 10), contract: IB::Stock.new( symbol: 'F')
rescue IB::TransmissionError => e
 ib.reconnect
 retry if initial_order_state == u.orders   #  normal execution after reestablishing the workflow state
 (...)
end
 ib.check_connection                   => true

Sending and receiving messages

After a successful connection, the main purpose of IB::Connection is to submit IB::Messages to the TWS-Api and to receive the response.

send_message is used to provide low-level communication to the TWS-server..

> c =  IB::Connection.current
> c.send_message {message symbol }, [ optional arguments ]

Visit this page for an overview of available messages and their arguments.

The TWS-Response can be stored in the received-Array.

ib = IB::Connection.new
ib.received = true   # Activate storage of incoming messages in received array
ib.try_connection!   # Connect and receive initial messages from the tws
puts ib.received.values.to_human
--> ["<NextValidId: local_id 15 >"],
    ["TWS Warning 2104: Market data farm connection is OK:hfarm",
    "TWS Warning 2104: Market data farm connection is OK:usfarm.nj",
    "TWS Warning 2106: HMDS data farm connection is OK:ushmds",
    "TWS Warning 2158: Sec-def data farm connection is OK:secdefeu"],
    ["<ManagedAccounts: DF4035274 - DU4035275 - DU4035276 - DU4035277 - DU4035278 - DU4035279>"]]

Alternatively the user can subscribe to messages and assign a code-block for immediate asynchronous execution.

 ib = IB::Connection.new( host: 'localhost:7497' )
 ib.subscribe(:Alert, :AccountValue) { |msg| puts msg.to_human }
 ib.subscribe(:OpenOrder)            { |msg| puts "Placed: #{msg.order}!" }
 ib.subscribe(:ExecutionData)        { |msg| puts "Filled: #{msg.execution}!" }
 ib.received = true  # activate storing of messages in the received-array
   
 ib.activate_plugin :order_prototypes # Easy order objects
 ib.try_connection!  
 ib.send_message :RequestAccountData, account_code: 'U123456'
 ib.wait_for :AccountDownloadEnd

 contract  = IB::Stock.new symbol: 'WFC'
 buy_order = IB::Limit.order size: 100, price: 21, account_code: 'U123456'

 ib.place_order buy_order, contract
 ib.wait_for :ExecutionData
Tags: