Module: AccountInfos

Included in:
IB::Gateway
Defined in:
lib/ib/gateway/account-infos.rb

Overview

module

Instance Method Summary collapse

Instance Method Details

#all_contractsObject



87
88
89
# File 'lib/ib/gateway/account-infos.rb', line 87

def all_contracts
clients.map(&:contracts).flat_map(&:itself).uniq(&:con_id)
end

#get_account_data(*accounts, **compatibily_argument) ⇒ Object

Queries the tws for Account- and PortfolioValues The parameter can either be the account_id, the IB::Account-Object or an Array of account_id and IB::Account-Objects.

Resets Account#portfolio_values and -account_values

Raises an IB::TransmissionError if the account-data are not transmitted in time (1 sec)

Raises an IB::Error if less then 100 items are received.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ib/gateway/account-infos.rb', line 33

def   *accounts, **compatibily_argument


	subscription = ( continuously: false )
   download_end = nil  # declare variable

	accounts = clients if accounts.empty?
   IB::Connection.logger.warn{ "No active account present. AccountData are NOT requested" } if accounts.empty?
	# Account-infos have to be requested sequentially.
	# subsequent (parallel) calls kill the former on the tws-server-side
	# In addition, there is no need to cancel the subscription of an request, as a new
	# one overwrites the active one.
	accounts.each do | ac |
		 =  ac.is_a?( IB::Account ) ?  ac  : clients.find{|x| x. == ac }
		error( "No Account detected " )  unless .is_a? IB::Account
		# don't repeat the query until 170 sec. have passed since the previous update
		if .last_updated.nil?  || ( Time.now - .last_updated ) > 170 # sec
       IB::Connection.logger.debug{ "#{.} :: Erasing Account- and Portfolio Data " }
       IB::Connection.logger.debug{ "#{.} :: Requesting AccountData " }

       q =  Queue.new
       download_end = tws.subscribe( :AccountDownloadEnd )  do | msg |
         q.push true if msg. == .
       end
			# reset account and portfolio-values
			.portfolio_values = []
			. = []
       # Data are gathered asynchron through the active subscription defined in  `subscribe_account_updates`
			send_message :RequestAccountData, subscribe: true, account_code: .

       th =  Thread.new{   sleep 10 ; q.close  }  # close the queue after 10 seconds
       q.pop                                      # wait for the data (or the closing event)

       if q.closed?
         error "No AccountData received", :reader
       else
         q.close
         tws.unsubscribe download_end
       end

       .organize_portfolio_positions  unless IB::Gateway.current.active_watchlists.empty?
		else
       IB::Connection.logger.info{ "#{.} :: Using stored AccountData " }
		end
	end
   tws.send_message :RequestAccountData, subscribe: false  ## do this only once
   tws.unsubscribe subscription
 rescue IB::TransmissionError => e
       tws.unsubscribe download_end unless download_end.nil?
       tws.unsubscribe subscription
       raise
end