ib-api 972.0 → 972.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +36 -37
- data/README.md +48 -3
- data/VERSION +1 -1
- data/api.gemspec +1 -1
- data/bin/console +4 -8
- data/changelog.md +12 -0
- data/lib/ib/base_properties.rb +3 -4
- data/lib/ib/connection.rb +18 -16
- data/lib/ib/logger.rb +1 -1
- data/lib/ib/messages/incoming.rb +1 -1
- data/lib/ib/messages/incoming/abstract_message.rb +7 -7
- data/lib/ib/messages/incoming/account_value.rb +5 -1
- data/lib/ib/messages/incoming/contract_data.rb +0 -2
- data/lib/ib/messages/incoming/historical_data.rb +25 -5
- data/lib/ib/messages/incoming/ticks.rb +21 -60
- data/lib/ib/messages/outgoing.rb +4 -2
- data/lib/ib/messages/outgoing/abstract_message.rb +3 -3
- data/lib/ib/messages/outgoing/bar_requests.rb +4 -5
- data/lib/ib/messages/outgoing/request_marketdata.rb +10 -7
- data/lib/ib/models.rb +1 -1
- data/lib/ib/support.rb +32 -15
- data/lib/logging.rb +45 -0
- data/lib/models/ib/account.rb +0 -13
- data/lib/models/ib/bag.rb +7 -1
- data/lib/models/ib/bar.rb +1 -1
- data/lib/models/ib/combo_leg.rb +22 -0
- data/lib/models/ib/contract.rb +44 -32
- data/lib/models/ib/contract_detail.rb +13 -7
- data/lib/models/ib/index.rb +1 -1
- data/lib/models/ib/option.rb +8 -2
- data/lib/models/ib/option_detail.rb +19 -3
- data/lib/models/ib/order.rb +5 -0
- data/lib/models/ib/spread.rb +168 -0
- data/lib/models/ib/stock.rb +9 -3
- data/lib/models/ib/underlying.rb +4 -1
- data/lib/requires.rb +10 -3
- metadata +9 -20
- data/example/README.md +0 -76
- data/example/account_info +0 -54
- data/example/account_positions +0 -30
- data/example/account_summary +0 -88
- data/example/cancel_orders +0 -74
- data/example/fa_accounts +0 -25
- data/example/fundamental_data +0 -40
- data/example/historic_data_cli +0 -186
- data/example/list_orders +0 -45
- data/example/portfolio_csv +0 -81
- data/example/scanner_data +0 -62
- data/example/template +0 -19
- data/example/tick_data +0 -28
data/example/fa_accounts
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This script receives Financial Adviser and Managed Accounts info
|
4
|
-
|
5
|
-
require 'bundler/setup'
|
6
|
-
require 'ib-api'
|
7
|
-
|
8
|
-
# First, connect to IB TWS.
|
9
|
-
ib = IB::Connection.new client_id: 1114, port: 4002 #, :port => 7496 # TWS
|
10
|
-
|
11
|
-
# Subscribe to TWS alerts/errors and FA/managed account info
|
12
|
-
ib.subscribe(:Alert, :ManagedAccounts, :ReceiveFA) { |msg| puts msg.to_human }
|
13
|
-
|
14
|
-
##
|
15
|
-
## type of Financial Advisor configuration data
|
16
|
-
# being received from TWS. Valid values include:
|
17
|
-
# 1 = GROUPS, 2 = PROFILE, 3 = ACCOUNT ALIASES
|
18
|
-
|
19
|
-
ib.send_message :RequestFA, fa_data_type: 3
|
20
|
-
ib.send_message :RequestManagedAccounts
|
21
|
-
|
22
|
-
ib.wait_for :ReceiveFA
|
23
|
-
|
24
|
-
|
25
|
-
|
data/example/fundamental_data
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This script downloads Fundamental data for specific symbols from IB
|
4
|
-
# This only works IF you have Reuters data subscription!
|
5
|
-
|
6
|
-
require 'bundler/setup'
|
7
|
-
|
8
|
-
require 'ib-api'
|
9
|
-
|
10
|
-
# allocate two variables
|
11
|
-
request_id, snapshot_data = nil
|
12
|
-
|
13
|
-
ib = IB::Connection.new port: 7496, :client_id => 1112 do | gw | #, :port => 7496 # TWS
|
14
|
-
gw.subscribe(:Alert) { |msg| puts msg.to_human }
|
15
|
-
|
16
|
-
# Fundamental Data will arrive in XML format, we need to parse it
|
17
|
-
gw.subscribe(:FundamentalData) { |msg| snapshot_data = msg.xml if msg.request_id == request_id }
|
18
|
-
end
|
19
|
-
|
20
|
-
# Request Fundamental Data for IBM. Possible report types:
|
21
|
-
# 'estimates' - Estimates
|
22
|
-
# 'finstat' - Financial statements
|
23
|
-
# 'snapshot' - Summary
|
24
|
-
request_id = ib.send_message :RequestFundamentalData,
|
25
|
-
:contract => IB::Stock.new( symbol: 'ibm' ),
|
26
|
-
:report_type => 'snapshot'
|
27
|
-
|
28
|
-
# Needs some time to receive and parse XML. Standard timeout of 1 sec is just too low.
|
29
|
-
ib.wait_for :FundamentalData
|
30
|
-
|
31
|
-
# Now just extract and use all the fundamental data you needed
|
32
|
-
puts snapshot_data[:ReportSnapshot][:TextInfo][:Text]
|
33
|
-
|
34
|
-
pp snapshot_data[:ReportSnapshot][:Ratios]
|
35
|
-
STDIN.gets
|
36
|
-
|
37
|
-
puts "Displaying the complete transmitted data:"
|
38
|
-
puts ""
|
39
|
-
|
40
|
-
pp snapshot_data
|
data/example/historic_data_cli
DELETED
@@ -1,186 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# This script connects to IB API, and downloads historic data
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'time'
|
6
|
-
require 'getopt/long'
|
7
|
-
require 'bundler/setup'
|
8
|
-
require 'ib-api'
|
9
|
-
|
10
|
-
include Getopt
|
11
|
-
|
12
|
-
opt = Getopt::Long.getopts(
|
13
|
-
["--help", BOOLEAN],
|
14
|
-
["--end", REQUIRED],
|
15
|
-
["--port", REQUIRED],
|
16
|
-
["--security", REQUIRED],
|
17
|
-
["--duration", REQUIRED],
|
18
|
-
["--barsize", REQUIRED],
|
19
|
-
["--csv", BOOLEAN],
|
20
|
-
["--dateformat", REQUIRED],
|
21
|
-
["--nonregularhours", BOOLEAN],
|
22
|
-
["--what", OPTIONAL]
|
23
|
-
)
|
24
|
-
|
25
|
-
if opt["help"] || opt["security"].nil? || opt["security"].empty?
|
26
|
-
puts <<ENDHELP
|
27
|
-
|
28
|
-
This program requires a TWS or Gateway running on localhost.
|
29
|
-
|
30
|
-
----------
|
31
|
-
|
32
|
-
One argument is required: --security, the security specification you want, in
|
33
|
-
"long serialized IB-Ruby" format. This is a colon-separated string of the format:
|
34
|
-
|
35
|
-
symbol:security_type:expiry:strike:right:multiplier:exchange:primary_exchange:currency:local_symbol
|
36
|
-
|
37
|
-
Fields not needed for a particular security should be left blank (e.g. strike and right are only relevant for options.)
|
38
|
-
|
39
|
-
For example, to query the Apple 500 Strike Call expiring in January 2013, use:
|
40
|
-
|
41
|
-
$ ./historic_data_cli --security AAPL:OPT:202101:200:CALL::SMART::USD:
|
42
|
-
|
43
|
-
Consult contract.rb for allowed values, and see also the examples in the symbols/ directory
|
44
|
-
(load them in irb and run security#serialize_ib_ruby to see the appropriate string.)
|
45
|
-
|
46
|
-
----------
|
47
|
-
|
48
|
-
Options:
|
49
|
-
|
50
|
-
--end is is the last time we want data for. The default is now.
|
51
|
-
This is eval'ed by Ruby, so you can use a Ruby expression, which must return a Time object.
|
52
|
-
|
53
|
-
--duration is time period before --end, in seconds. The default is 86400 sec (1 day).
|
54
|
-
TWS imposes limit of 86400 sec (1 day) worth of historic data per request.
|
55
|
-
|
56
|
-
--what determines what the data will be comprised of. This can be
|
57
|
-
"trades", "midpoint", "bid", or "ask". The default is "trades".
|
58
|
-
|
59
|
-
--barsize determines how long each bar will be.
|
60
|
-
|
61
|
-
Possible bar values (from the IB documentation):
|
62
|
-
Values less than 30 sec do not appear to work for some securities.
|
63
|
-
|
64
|
-
sec1 = 1 sec
|
65
|
-
sec5 = 5 sec
|
66
|
-
sec15 = 15 sec
|
67
|
-
sec30 = 30 sec
|
68
|
-
min1 = 1 minute
|
69
|
-
min2 = 2 minutes
|
70
|
-
min5 = 5 minutes
|
71
|
-
min15 = 15 minutes (default)
|
72
|
-
min30 = 30 minutes
|
73
|
-
hour1 = 1 hour
|
74
|
-
day1 = 1 day
|
75
|
-
|
76
|
-
--nonregularhours : Normally, only data from the instrument's regular trading
|
77
|
-
hours is returned. If --nonregularhours is given, all data available during the time
|
78
|
-
span requested is returned, even for time intervals when the market was illiquid.
|
79
|
-
|
80
|
-
--dateformat : 1 (default) human-readable time/date format, like "20050307 11:32:16".
|
81
|
-
If you set it to 2 instead, you will get UNIX epoch offsets (seconds since Jan 1, 1970).
|
82
|
-
|
83
|
-
--csv : print out the historic data in CSV format, with header.
|
84
|
-
|
85
|
-
--port : 4001 for Gateway (default), 7496 for TWS, or your custom port
|
86
|
-
|
87
|
-
ENDHELP
|
88
|
-
exit
|
89
|
-
end
|
90
|
-
|
91
|
-
### Parameters
|
92
|
-
|
93
|
-
# DURATION is how much historic data we want, in seconds, before END_DATE_TIME.
|
94
|
-
DURATION = (opt["duration"] && opt["duration"].to_i) || 86400
|
95
|
-
|
96
|
-
if DURATION > 86400
|
97
|
-
STDERR.puts("\nTWS rejects --duration longer than 86400 seconds (1 day).\n")
|
98
|
-
exit(1)
|
99
|
-
end
|
100
|
-
|
101
|
-
# This is the last time we want data for.
|
102
|
-
END_DATE_TIME = (opt["end"] && eval(opt["end"]).to_ib) || Time.now.to_ib
|
103
|
-
|
104
|
-
# This can be :trades, :midpoint, :bid, or :asked
|
105
|
-
WHAT = (opt["what"] && opt["what"].to_sym) || :trades
|
106
|
-
|
107
|
-
|
108
|
-
# Values less than 4 do not appear to actually work; they are rejected by the server.
|
109
|
-
#
|
110
|
-
BAR_SIZE = (opt["barsize"] && opt["barsize"].to_sym) || :min15
|
111
|
-
|
112
|
-
# If REGULAR_HOURS_ONLY is set to 0, all data available during the time
|
113
|
-
# span requested is returned, even data bars covering time
|
114
|
-
# intervals where the market in question was illiquid. If useRTH
|
115
|
-
# has a non-zero value, only data within the "Regular Trading
|
116
|
-
# Hours" of the product in question is returned, even if the time
|
117
|
-
# span requested falls partially or completely outside of them.
|
118
|
-
|
119
|
-
REGULAR_HOURS_ONLY = opt["nonregularhours"] ? 0 : 1
|
120
|
-
|
121
|
-
# Using a DATE_FORMAT of 1 will cause the dates in the returned
|
122
|
-
# messages with the historic data to be in a text format, like
|
123
|
-
# "20050307 11:32:16". If you set :format_date to 2 instead, you
|
124
|
-
# will get an offset in seconds from the beginning of 1970, which
|
125
|
-
# is the same format as the UNIX epoch time.
|
126
|
-
|
127
|
-
DATE_FORMAT = (opt["dateformat"] && opt["dateformat"].to_i) || 1
|
128
|
-
|
129
|
-
PORT = (opt["port"] && opt["port"]) || '4002'
|
130
|
-
|
131
|
-
lastMessageTime = Queue.new # for communicating with the reader thread.
|
132
|
-
|
133
|
-
# First, connect to IB TWS.
|
134
|
-
ib = IB::Connection.new( :client_id => 1112, :port => PORT) do | gw|
|
135
|
-
|
136
|
-
# Subscribe to TWS alerts/errors
|
137
|
-
gw.subscribe(:Alert) { |msg| puts msg.to_human }
|
138
|
-
|
139
|
-
|
140
|
-
# Subscribe to incoming HistoricalData events. The code passed in the
|
141
|
-
# block will be executed when a message of the subscribed type is
|
142
|
-
# received, with the received message as its argument. In this case,
|
143
|
-
# we just print out the data.
|
144
|
-
#
|
145
|
-
# Note that we have to look the ticker id of each incoming message
|
146
|
-
# up in local memory to figure out what security it relates to.
|
147
|
-
# The incoming message packet from TWS just identifies it by ticker id.
|
148
|
-
#
|
149
|
-
gw.subscribe(:HistoricalData) do |msg|
|
150
|
-
if opt["csv"]
|
151
|
-
puts "date,time,open,high,low,close,volume,wap,has_gaps"
|
152
|
-
msg.results.each do |datum|
|
153
|
-
puts "#{datum.time},#{datum.open},#{datum.high},#{datum.low}," +
|
154
|
-
"#{datum.close},#{datum.volume},#{datum.wap},#{datum.has_gaps}"
|
155
|
-
end
|
156
|
-
n
|
157
|
-
STDERR.puts "Received #{msg.count} items:"
|
158
|
-
msg.results.each { |datum| puts datum.to_s }
|
159
|
-
end
|
160
|
-
lastMessageTime.push(Time.now)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
# Now we actually request historical data for the symbols we're
|
164
|
-
# interested in. TWS will respond with a HistoricalData message,
|
165
|
-
# which will be received by the code above.
|
166
|
-
ib.send_message :RequestHistoricalData,
|
167
|
-
:request_id => 123,
|
168
|
-
:contract => opt["security"],
|
169
|
-
:end_date_time => END_DATE_TIME,
|
170
|
-
:duration => DURATION, # seconds == 1 hour
|
171
|
-
:bar_size => BAR_SIZE, # 1 minute bars
|
172
|
-
:what_to_show => WHAT,
|
173
|
-
:use_RTH => REGULAR_HOURS_ONLY,
|
174
|
-
:keep_up_todate => 0,
|
175
|
-
:format_date => DATE_FORMAT
|
176
|
-
|
177
|
-
# A complication here is that IB does not send any indication when all historic data
|
178
|
-
# is done being delivered. So we have to guess - when there is no more new data for
|
179
|
-
# some period, we interpret that as "end of data" and exit.
|
180
|
-
sleep 2
|
181
|
-
while true
|
182
|
-
lastTime = lastMessageTime.pop # blocks until a message is ready on the queue
|
183
|
-
sleep 0.1 # .. wait ..
|
184
|
-
exit if lastMessageTime.empty? # if still no more messages after 2 more seconds, exit.
|
185
|
-
end
|
186
|
-
|
data/example/list_orders
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This script retrieves list of all Orders from TWS
|
4
|
-
|
5
|
-
require 'bundler/setup'
|
6
|
-
require 'ib-api'
|
7
|
-
|
8
|
-
# Connect to IB as 0 (TWS) to retrieve all Orders, including TWS-generated ones
|
9
|
-
ib = IB::Connection.new :client_id => 0 do |gw| # , :port => 7497 # TWS
|
10
|
-
|
11
|
-
# Subscribe to TWS alerts/errors and order-related messages
|
12
|
-
counter = 0
|
13
|
-
|
14
|
-
gw.subscribe(:Alert, :ManagedAccounts, :OrderStatus, :OpenOrderEnd) { |msg| puts msg.to_human }
|
15
|
-
|
16
|
-
gw.subscribe(:OpenOrder) do |msg|
|
17
|
-
counter += 1
|
18
|
-
puts "#{counter}: #{msg.to_human}"
|
19
|
-
|
20
|
-
# Get rid of logging verbosity
|
21
|
-
gw.logger.level = Logger::FATAL
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
## fire request
|
26
|
-
ib.send_message :RequestAllOpenOrders
|
27
|
-
|
28
|
-
# Wait for IB to respond to our request
|
29
|
-
ib.wait_for :OpenOrderEnd
|
30
|
-
sleep 1 # Let printer do the job
|
31
|
-
|
32
|
-
=begin
|
33
|
-
---> expected output
|
34
|
-
1: <OpenOrder: <Bag: GOOG SMART USD legs: 269330045|1,269562569|1,301964119|-2 > <Order: LMT GTC buy 10.0 0.06 PreSubmitted #9/561364885 from 1112/DU167349 fee 0.0>>
|
35
|
-
<OrderStatus: <OrderState: PreSubmitted #9/561364885 from 1112 filled 0.0/10.0 at 0.0/0.0 why_held locate>>
|
36
|
-
2:<OpenOrder: <Stock: WFC USD> <Order: LMT DAY sell 100.0 34.05 PreSubmitted #19/561364895 from 1112/DU167349 fee 0.0>>
|
37
|
-
<OrderStatus: <OrderState: PreSubmitted #19/561364895 from 1112 filled 0.0/100.0 at 0.0/0.0 why_held child,locate>>
|
38
|
-
3: <OpenOrder: <Stock: WFC USD> <Order: STP DAY sell 100.0 0.0 PreSubmitted /33.55#18/561364894 from 1112/DU167349 fee 0.0>>
|
39
|
-
<OrderStatus: <OrderState: PreSubmitted #18/561364894 from 1112 filled 0.0/100.0 at 0.0/0.0 why_held child,locate,trigger>>
|
40
|
-
4: <OpenOrder: <Bag: GOOG SMART USD legs: 269330045|1,269562569|1,301964119|-2 > <Order: LMT GTC buy 10.0 0.06 PreSubmitted #8/1562725198 from 1112/DU167349 fee 0.0>>
|
41
|
-
<OrderStatus: <OrderState: PreSubmitted #8/1562725198 from 1112 filled 0.0/10.0 at 0.0/0.0 why_held locate>>
|
42
|
-
5: <OpenOrder: <Stock: WFC USD> <Order: LMT GTC buy 100.0 1.72 Submitted #3/1562725193 from 1112/DU167349 fee 0.0>>
|
43
|
-
<OrderStatus: <OrderState: Submitted #3/1562725193 from 1112 filled 0.0/100.0 at 0.0/0.0 why_held >>
|
44
|
-
<OpenOrderEnd: >
|
45
|
-
=end
|
data/example/portfolio_csv
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# This script exports your IB portfolio in a CSV format. Usage:
|
4
|
-
# $ example/portfolio_csv [account] > portfolio.csv
|
5
|
-
|
6
|
-
require 'bundler/setup'
|
7
|
-
require 'ib-ruby'
|
8
|
-
|
9
|
-
# Only for Advisors: you need to provide account id such as U666777
|
10
|
-
account = ARGV[0] || ''
|
11
|
-
accounts = []
|
12
|
-
|
13
|
-
# Connect to IB TWS and subscribe to events
|
14
|
-
ib = IB::Connection.new( :client_id => 1112 , port: 4002 ) do |gw| # , :port => 7496 # TWS
|
15
|
-
|
16
|
-
# Redirect TWS alerts/errors to STDERR to keep output file clean
|
17
|
-
#gw.subscribe(:Alert) { |msg| STDERR.puts msg.to_human }
|
18
|
-
|
19
|
-
# Subscribe to TWS alerts/errors and account-related messages
|
20
|
-
# that TWS sends in response to account data request
|
21
|
-
gw.subscribe(:Alert) do |msg|
|
22
|
-
## if an account is not given. but required, (Error 321 indicates this)
|
23
|
-
## fetch data from the last account detected. (The first is most probably the Advisor-Account)
|
24
|
-
if msg.code == 321
|
25
|
-
account = accounts.last
|
26
|
-
gw.send_message :RequestAccountData, :subscribe => true, :account_code => account
|
27
|
-
else
|
28
|
-
puts msg.to_human
|
29
|
-
end
|
30
|
-
end
|
31
|
-
# Silently ignore account-related messages other than :PortfolioValue
|
32
|
-
gw.subscribe(:AccountUpdateTime, :AccountValue, :ManagedAccounts, :AccountDownloadEnd) {}
|
33
|
-
# Get rid of logging verbosity
|
34
|
-
gw.logger.level = Logger::FATAL
|
35
|
-
|
36
|
-
## Just in case: put account-names into accounts-array
|
37
|
-
gw.subscribe(:ManagedAccounts){ |msg| accounts = msg.accounts_list.split ',' }
|
38
|
-
end
|
39
|
-
|
40
|
-
# Output CSV headers
|
41
|
-
puts %w[Symbol
|
42
|
-
SecType
|
43
|
-
Expiry
|
44
|
-
Strike
|
45
|
-
Right
|
46
|
-
Currency
|
47
|
-
LocalSymbol
|
48
|
-
Position
|
49
|
-
MarketPrice
|
50
|
-
MarketValue
|
51
|
-
AvgCost
|
52
|
-
UnrealizedPNL
|
53
|
-
RealizedPNL
|
54
|
-
Account].map {|val| "\"#{val}\""}.join(",")
|
55
|
-
|
56
|
-
# Output each portfolio position as a single line in CSV format
|
57
|
-
ib.subscribe(:PortfolioValue) do |msg|
|
58
|
-
contract = msg.contract
|
59
|
-
csv = [ contract.symbol,
|
60
|
-
IB::CODES[:sec_type][contract.sec_type],
|
61
|
-
contract.expiry,
|
62
|
-
contract.strike == 0 ? "" : contract.strike,
|
63
|
-
contract.right == :none ? "" : contract.right,
|
64
|
-
contract.currency,
|
65
|
-
contract.local_symbol,
|
66
|
-
msg.position,
|
67
|
-
msg.market_price,
|
68
|
-
msg.market_value,
|
69
|
-
msg.average_cost,
|
70
|
-
msg.unrealized_pnl,
|
71
|
-
msg.realized_pnl,
|
72
|
-
msg.account_name
|
73
|
-
].map {|val| "\"#{val}\""}.join(",")
|
74
|
-
puts csv
|
75
|
-
end
|
76
|
-
|
77
|
-
# Request account data, wait for its end, unsubscribe
|
78
|
-
ib.send_message :RequestAccountData, :subscribe => true, :account_code => account
|
79
|
-
ib.wait_for :AccountDownloadEnd, 30
|
80
|
-
ib.send_message :RequestAccountData, :subscribe => false, :account_code => account
|
81
|
-
sleep 0.5
|
data/example/scanner_data
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# This Script needs testing. remove this line after sucessfully using the scanner facility
|
3
|
-
#
|
4
|
-
# This script setups a scan request and retreives the results.
|
5
|
-
|
6
|
-
require 'rubygems'
|
7
|
-
require 'bundler/setup'
|
8
|
-
require 'ib-api'
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# Connect to IB TWS.
|
13
|
-
ib = IB::Connection.new :client_id => 1112 , port: 7496 do | gw | #, :port => 7497 # TWS
|
14
|
-
|
15
|
-
|
16
|
-
# Subscribe to TWS alerts/errors
|
17
|
-
gw.subscribe(:Alert) { |msg| puts msg.to_human }
|
18
|
-
|
19
|
-
|
20
|
-
# Subscribe to ScannerData incoming events. The code passed in the block
|
21
|
-
# will be executed when a message of that type is received, with the received
|
22
|
-
# message as its argument. In this case, we just print out the data.
|
23
|
-
#
|
24
|
-
gw.subscribe(IB::Messages::Incoming::ScannerData) do |msg|
|
25
|
-
puts "ID: #{msg.request_id} : #{msg.count} items:"
|
26
|
-
msg.results.each { |entry| puts " #{entry}" }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
id = 42
|
30
|
-
# Now we actually request scanner data for the type of scan we are interested.
|
31
|
-
# Some scan types can be found here: http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/tables/available_market_scanners.htm
|
32
|
-
mess = IB::Messages::Outgoing::RequestScannerSubscription.new(
|
33
|
-
:request_id => id,
|
34
|
-
:number_of_rows => 20,
|
35
|
-
:instrument => "STK",
|
36
|
-
:location_code => 'STK.US.MAJOR',
|
37
|
-
:scan_code => 'TOP_PERC_GAIN',
|
38
|
-
:above_price => 4.0,
|
39
|
-
:below_price => Float::MAX,
|
40
|
-
:above_volume => 5000,
|
41
|
-
:market_cap_above => 100000000,
|
42
|
-
:market_cap_below => Float::MAX,
|
43
|
-
:moody_rating_above => "",
|
44
|
-
:moody_rating_below => "",
|
45
|
-
:sp_rating_above => "",
|
46
|
-
:sp_rating_below => "",
|
47
|
-
:maturity_date_above => "",
|
48
|
-
:maturity_date_below => "",
|
49
|
-
:coupon_rate_above => Float::MAX,
|
50
|
-
:coupon_rate_below => Float::MAX,
|
51
|
-
:exclude_convertible => "",
|
52
|
-
:average_option_volume_above => "", # ?
|
53
|
-
:scanner_setting_pairs => "Annual,true",
|
54
|
-
:stock_type_filter => "Stock"
|
55
|
-
)
|
56
|
-
|
57
|
-
ib.send_message( mess )
|
58
|
-
|
59
|
-
# IB does not send any indication when all data is done being delivered.
|
60
|
-
# So we need to interrupt manually when our request is answered.
|
61
|
-
puts "\n******** Press <Enter> to exit... *********\n\n"
|
62
|
-
STDIN.gets
|
data/example/template
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# Your script description here...
|
4
|
-
|
5
|
-
require 'bundler/setup'
|
6
|
-
require 'ib-api'
|
7
|
-
|
8
|
-
# First, connect to IB TWS and subscribe for events.
|
9
|
-
ib = IB::Connection.new :client_id => 1112 do | gw | #, :port => 7497 # TWS
|
10
|
-
|
11
|
-
# Subscribe to TWS alerts/errors
|
12
|
-
gw.subscribe(:Alert, :ManagedAccounts) { |msg| puts msg.to_human }
|
13
|
-
# Set log level
|
14
|
-
gw.logger.level = Logger::FATAL # DEBUG -- INFO -- WARN -- ERROR -- FATAL
|
15
|
-
|
16
|
-
end
|
17
|
-
# Put your code here
|
18
|
-
# ...
|
19
|
-
|