lib/ib/gateway.rb in ib-extensions-1.2 vs lib/ib/gateway.rb in ib-extensions-1.3
- old
+ new
@@ -111,11 +111,11 @@
self.logger.info { '-' * 20 +' initialize ' + '-' * 20 }
@connection_parameter = { received: serial_array, port: port, host: host, connect: false, logger: logger, client_id: client_id }
@account_lock = Mutex.new
- @watchlists = watchlists
+ @watchlists = watchlists.map{ |b| IB::Symbols.allocate_collection b }
@gateway_parameter = { s_m_a: subscribe_managed_accounts,
s_a: subscribe_alerts,
s_o_m: subscribe_order_messages,
g_a_d: get_account_data }
@@ -131,11 +131,11 @@
if connect
i = 0
begin
i+=1
if connect(100) # tries to connect for about 2h
- get_account_data(watchlists: watchlists.map{|b| IB::Symbols.allocate_collection b}) if get_account_data
+ get_account_data()
# request_open_orders() if request_open_orders || get_account_data
else
@accounts = [] # definitivley reset @accounts
end
rescue IB::Error => e
@@ -154,10 +154,14 @@
end
def active_watchlists
@watchlists
end
+ def add_watchlist watchlist
+ new_watchlist = IB::Symbols.allocate_collection( watchlist )
+ @watchlists << new_watchlist unless @watchlists.include?( new_watchlist )
+ end
def get_host
"#{@connection_parameter[:host]}: #{@connection_parameter[:port] }"
end
@@ -194,42 +198,35 @@
else
logger.info { "Giving up!!" }
return false
end
rescue Errno::EHOSTUNREACH => e
- logger.error 'Cannot connect to specified host'
- logger.error e
+ error "Cannot connect to specified host #{e}", :reader, true
return false
rescue SocketError => e
- logger.error 'Wrong Adress, connection not possible'
+ error 'Wrong Adress, connection not possible', :reader, true
return false
+ rescue IB::Error => e
+ logger.info e
end
- tws.start_reader
- # let NextValidId-Event appear
- (1..30).each do |r|
- break if tws.next_local_id.present?
- sleep 0.1
- if r == 30
- error "Connected, NextLocalId is not initialized. Repeat with another client_id"
- end
- end
# initialize @accounts (incl. aliases)
tws.send_message( :RequestFA, fa_data_type: 3) if fa?
logger.debug { "Communications successfully established" }
# update open orders
request_open_orders if @gateway_parameter[:s_o_m] || @gateway_parameter[:g_a_d]
+ true # return gatway object
end # def
def reconnect
if tws.present?
disconnect
- sleep 1
+ sleep 0.1
end
logger.info "trying to reconnect ..."
connect
end
@@ -310,17 +307,32 @@
(AccountValues, Portfolio-Values, Contracts and Orders)
It returns an Array of the return-values of the block
If called without a parameter, all clients are accessed
+
+Example
+
+```
+g = IB::Gateway.current
+# thread safe access
+g.account_data &:portfolio_values
+
+g.account_data &:account_values
+
+# primitive access
+g.clients.map &:portfolio_values
+g.clients.map &:account_values
+
+```
=end
def account_data account_or_id=nil
safe = ->(account) do
@account_lock.synchronize do
- yield account
+ yield account
end
end
if block_given?
if account_or_id.present?
@@ -347,14 +359,13 @@
## apply other initialisations which should apper before the connection as block
## i.e. after connection order-state events are fired if an open-order is pending
## a possible response is best defined before the connect-attempt is done
# ## Attention
# ## @accounts are not initialized yet (empty array)
- if block_given?
- yield self
+ yield self if block_given?
- end
+
end
=begin
InitializeManagedAccounts
defines the Message-Handler for :ManagedAccounts
@@ -362,11 +373,11 @@
=end
def initialize_managed_accounts
rec_id = tws.subscribe( :ReceiveFA ) do |msg|
msg.accounts.each do |a|
- account_data( a.account ){| the_account | the_account.update_attribute :alias, a.alias } unless a.alias.blank?
+ account_data( a.account ){| the_account | the_account.update_attribute :alias, a.alias } unless a.alias.blank?
end
logger.info { "Accounts initialized \n #{@accounts.map( &:to_human ).join " \n " }" }
end
man_id = tws.subscribe( :ManagedAccounts ) do |msg|
@@ -405,28 +416,31 @@
#
# a = Time.now; G.check_connection; b= Time.now ;b-a
# => 0.00066005
#
def check_connection
- answer = nil; count=0
- z= tws.subscribe( :CurrentTime ) { answer = true }
- while (answer.nil?)
+ q = Queue.new
+ count = 0
+ result = nil
+ z= tws.subscribe( :CurrentTime ) { q.push true }
+ loop do
begin
tws.send_message(:RequestCurrentTime) # 10 ms ##
- i=0; loop{ break if answer || i > 40; i+=1; sleep 0.0001}
+ th = Thread.new{ sleep 1 ; q.push nil }
+ result = q.pop
+ count+=1
+ break if result || count > 10
rescue IOError, Errno::ECONNREFUSED # connection lost
- count = 6
+ count +=1
+ retry
rescue IB::Error # not connected
reconnect
- count +=1
- sleep 1
- retry if count <= 5
+ count = 0
+ retry
end
- count +=1
- break if count > 5
end
tws.unsubscribe z
- count < 5 && answer # return value
+ result # return value
end
private
def random_id
rand 99999