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.
IB::Connection.current
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