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