def initialize host: '127.0.0.1:4002', # IB Gateway connection  4001:  production
                # or 'localhost:7497'  # TWS                    7496:  production
               logger: default_logger,
               client_id:  rand( 1001 .. 9999 ) 

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

If called without arguments, it connects through port 4002 to a locally running gateway and prints the logs to the standard output device.

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

Events are triggert 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

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.

One centerpiece is its send_message method.

> 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' ) do | gw |
      gw.subscribe(:Alert, :AccountValue) { |msg| puts msg.to_human }
      gw.subscribe(:OpenOrder)            { |msg| puts "Placed: #{msg.order}!" }
      gw.subscribe(:ExecutionData)        { |msg| puts "Filled: #{msg.execution}!" }
      gw.received = true  # activate storing of messages in the received-array
    end
 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: