ib-api 972.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +50 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +16 -0
  7. data/Gemfile.lock +105 -0
  8. data/Guardfile +24 -0
  9. data/LICENSE +674 -0
  10. data/README.md +65 -0
  11. data/Rakefile +11 -0
  12. data/VERSION +1 -0
  13. data/api.gemspec +43 -0
  14. data/bin/console +95 -0
  15. data/bin/console.yml +3 -0
  16. data/bin/setup +8 -0
  17. data/changelog.md +7 -0
  18. data/example/README.md +76 -0
  19. data/example/account_info +54 -0
  20. data/example/account_positions +30 -0
  21. data/example/account_summary +88 -0
  22. data/example/cancel_orders +74 -0
  23. data/example/fa_accounts +25 -0
  24. data/example/fundamental_data +40 -0
  25. data/example/historic_data_cli +186 -0
  26. data/example/list_orders +45 -0
  27. data/example/portfolio_csv +81 -0
  28. data/example/scanner_data +62 -0
  29. data/example/template +19 -0
  30. data/example/tick_data +28 -0
  31. data/lib/extensions/class-extensions.rb +87 -0
  32. data/lib/ib-api.rb +7 -0
  33. data/lib/ib/base.rb +103 -0
  34. data/lib/ib/base_properties.rb +160 -0
  35. data/lib/ib/connection.rb +450 -0
  36. data/lib/ib/constants.rb +393 -0
  37. data/lib/ib/errors.rb +44 -0
  38. data/lib/ib/logger.rb +26 -0
  39. data/lib/ib/messages.rb +99 -0
  40. data/lib/ib/messages/abstract_message.rb +101 -0
  41. data/lib/ib/messages/incoming.rb +251 -0
  42. data/lib/ib/messages/incoming/abstract_message.rb +116 -0
  43. data/lib/ib/messages/incoming/account_value.rb +78 -0
  44. data/lib/ib/messages/incoming/alert.rb +34 -0
  45. data/lib/ib/messages/incoming/contract_data.rb +102 -0
  46. data/lib/ib/messages/incoming/delta_neutral_validation.rb +23 -0
  47. data/lib/ib/messages/incoming/execution_data.rb +50 -0
  48. data/lib/ib/messages/incoming/historical_data.rb +84 -0
  49. data/lib/ib/messages/incoming/market_depths.rb +44 -0
  50. data/lib/ib/messages/incoming/next_valid_id.rb +18 -0
  51. data/lib/ib/messages/incoming/open_order.rb +277 -0
  52. data/lib/ib/messages/incoming/order_status.rb +85 -0
  53. data/lib/ib/messages/incoming/portfolio_value.rb +78 -0
  54. data/lib/ib/messages/incoming/real_time_bar.rb +32 -0
  55. data/lib/ib/messages/incoming/scanner_data.rb +54 -0
  56. data/lib/ib/messages/incoming/ticks.rb +268 -0
  57. data/lib/ib/messages/outgoing.rb +437 -0
  58. data/lib/ib/messages/outgoing/abstract_message.rb +88 -0
  59. data/lib/ib/messages/outgoing/account_requests.rb +112 -0
  60. data/lib/ib/messages/outgoing/bar_requests.rb +250 -0
  61. data/lib/ib/messages/outgoing/place_order.rb +209 -0
  62. data/lib/ib/messages/outgoing/request_marketdata.rb +99 -0
  63. data/lib/ib/messages/outgoing/request_tick_data.rb +21 -0
  64. data/lib/ib/model.rb +4 -0
  65. data/lib/ib/models.rb +14 -0
  66. data/lib/ib/server_versions.rb +114 -0
  67. data/lib/ib/socket.rb +185 -0
  68. data/lib/ib/support.rb +160 -0
  69. data/lib/ib/version.rb +6 -0
  70. data/lib/models/ib/account.rb +85 -0
  71. data/lib/models/ib/account_value.rb +33 -0
  72. data/lib/models/ib/bag.rb +55 -0
  73. data/lib/models/ib/bar.rb +31 -0
  74. data/lib/models/ib/combo_leg.rb +105 -0
  75. data/lib/models/ib/condition.rb +245 -0
  76. data/lib/models/ib/contract.rb +415 -0
  77. data/lib/models/ib/contract_detail.rb +108 -0
  78. data/lib/models/ib/execution.rb +67 -0
  79. data/lib/models/ib/forex.rb +13 -0
  80. data/lib/models/ib/future.rb +15 -0
  81. data/lib/models/ib/index.rb +15 -0
  82. data/lib/models/ib/option.rb +78 -0
  83. data/lib/models/ib/option_detail.rb +55 -0
  84. data/lib/models/ib/order.rb +519 -0
  85. data/lib/models/ib/order_state.rb +152 -0
  86. data/lib/models/ib/portfolio_value.rb +64 -0
  87. data/lib/models/ib/stock.rb +16 -0
  88. data/lib/models/ib/underlying.rb +34 -0
  89. data/lib/models/ib/vertical.rb +96 -0
  90. data/lib/requires.rb +12 -0
  91. metadata +203 -0
@@ -0,0 +1,32 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ # RealTimeBar contains following @data:
6
+ # :request_id - The ID of the *request* to which this is responding
7
+ # :time - The date-time stamp of the start of the bar. The format is offset in
8
+ # seconds from the beginning of 1970, same format as the UNIX epoch time
9
+ # :bar - received RT Bar
10
+ RealTimeBar = def_message [50, 3],
11
+ [:request_id, :int],
12
+ [:bar, :time, :int_date],
13
+ [:bar, :open, :decimal],
14
+ [:bar, :high, :decimal],
15
+ [:bar, :low, :decimal],
16
+ [:bar, :close, :decimal],
17
+ [:bar, :volume, :int],
18
+ [:bar, :wap, :decimal],
19
+ [:bar, :trades, :int]
20
+ class RealTimeBar
21
+ def bar
22
+ @bar = IB::Bar.new @data[:bar]
23
+ end
24
+
25
+ def to_human
26
+ "<RealTimeBar: #{request_id} #{bar}>"
27
+ end
28
+ end # RealTimeBar
29
+
30
+ end # module Incoming
31
+ end # module Messages
32
+ end # module IB
@@ -0,0 +1,54 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ # This method receives the requested market scanner data results.
6
+ # ScannerData contains following @data:
7
+ # :request_id - The ID of the request to which this row is responding
8
+ # :count - Number of data points returned (size of :results).
9
+ # :results - an Array of Hashes, each hash contains a set of
10
+ # data about one scanned Contract:
11
+ # :contract - a full description of the contract (details).
12
+ # :distance - Varies based on query.
13
+ # :benchmark - Varies based on query.
14
+ # :projection - Varies based on query.
15
+ # :legs - Describes combo legs when scan is returning EFP.
16
+ ScannerData = def_message [20, 3],
17
+ [:request_id, :int], # request id
18
+ [:count, :int]
19
+ class ScannerData
20
+ attr_accessor :results
21
+ using IBSupport # extended Array-Class from abstract_message
22
+
23
+ def load
24
+ super
25
+
26
+ @results = Array.new(@data[:count]) do |_|
27
+ {:rank => buffer.read_int,
28
+ :contract =>
29
+ Contract.build(
30
+ :con_id => buffer.read_int,
31
+ :symbol => buffer.read_string,
32
+ :sec_type => buffer.read_string,
33
+ :expiry => buffer.read_string,
34
+ :strike => buffer.read_decimal,
35
+ :right => buffer.read_string,
36
+ :exchange => buffer.read_string,
37
+ :currency => buffer.read_string,
38
+ :local_symbol => buffer.read_string,
39
+ :contract_detail =>
40
+ IB::ContractDetail.new(
41
+ :market_name => buffer.read_string,
42
+ :trading_class => buffer.read_string)),
43
+ :distance => buffer.read_string,
44
+ :benchmark => buffer.read_string,
45
+ :projection => buffer.read_string,
46
+ :legs => buffer.read_string,
47
+ }
48
+ end
49
+ end
50
+ end # ScannerData
51
+
52
+ end # module Incoming
53
+ end # module Messages
54
+ end # module IB
@@ -0,0 +1,268 @@
1
+ # All message classes related to ticks located here
2
+ module IB
3
+ module Messages
4
+ module Incoming
5
+
6
+ class AbstractTick < AbstractMessage
7
+ # Returns Symbol with a meaningful name for received tick type
8
+ def type
9
+ TICK_TYPES[@data[:tick_type]]
10
+ end
11
+
12
+ def to_human
13
+ "<#{self.message_type} #{type}:" +
14
+ @data.map do |key, value|
15
+ " #{key} #{value}" unless [:version, :ticker_id, :tick_type].include?(key)
16
+ end.compact.join(',') + " >"
17
+ end
18
+
19
+ def the_data
20
+ @data.reject{|k,_| [:version, :ticker_id].include? k }
21
+ end
22
+ end
23
+
24
+
25
+ # The IB code seems to dispatch up to two wrapped objects for this message, a tickPrice
26
+ # and sometimes a tickSize, which seems to be identical to the TICK_SIZE object.
27
+ #
28
+ # Important note from
29
+ # http://chuckcaplan.com/twsapi/index.php/void%20tickPrice%28%29 :
30
+ #
31
+ # "The low you get is NOT the low for the day as you'd expect it
32
+ # to be. It appears IB calculates the low based on all
33
+ # transactions after 4pm the previous day. The most inaccurate
34
+ # results occur when the stock moves up in the 4-6pm aftermarket
35
+ # on the previous day and then gaps open upward in the
36
+ # morning. The low you receive from TWS can be easily be several
37
+ # points different from the actual 9:30am-4pm low for the day in
38
+ # cases like this. If you require a correct traded low for the
39
+ # day, you can't get it from the TWS API. One possible source to
40
+ # help build the right data would be to compare against what Yahoo
41
+ # lists on finance.yahoo.com/q?s=ticker under the "Day's Range"
42
+ # statistics (be careful here, because Yahoo will use anti-Denial
43
+ # of Service techniques to hang your connection if you try to
44
+ # request too many bytes in a short period of time from them). For
45
+ # most purposes, a good enough approach would start by replacing
46
+ # the TWS low for the day with Yahoo's day low when you first
47
+ # start watching a stock ticker; let's call this time T. Then,
48
+ # update your internal low if the bid or ask tick you receive is
49
+ # lower than that for the remainder of the day. You should check
50
+ # against Yahoo again at time T+20min to handle the occasional
51
+ # case where the stock set a new low for the day in between
52
+ # T-20min (the real time your original quote was from, taking into
53
+ # account the delay) and time T. After that you should have a
54
+ # correct enough low for the rest of the day as long as you keep
55
+ # updating based on the bid/ask. It could still get slightly off
56
+ # in a case where a short transaction setting a new low appears in
57
+ # between ticks of data that TWS sends you. The high is probably
58
+ # distorted in the same way the low is, which would throw your
59
+ # results off if the stock traded after-hours and gapped down. It
60
+ # should be corrected in a similar way as described above if this
61
+ # is important to you."
62
+ #
63
+ # IB then emits at most 2 events on eWrapper:
64
+ # tickPrice( tickerId, tickType, price, canAutoExecute)
65
+ # tickSize( tickerId, sizeTickType, size)
66
+ TickPrice = def_message [1, 6], AbstractTick,
67
+ [:ticker_id, :int],
68
+ [:tick_type, :int],
69
+ [:price, :float],
70
+ [:size, :int],
71
+ [:can_auto_execute, :int]
72
+ class TickPrice
73
+ def valid?
74
+ super && !price.zero?
75
+ end
76
+ end
77
+
78
+ TickSize = def_message [2, 6], AbstractTick,
79
+ [:ticker_id, :int],
80
+ [:tick_type, :int],
81
+ [:size, :int]
82
+
83
+ TickGeneric = def_message [45, 6], AbstractTick,
84
+ [:ticker_id, :int],
85
+ [:tick_type, :int],
86
+ [:value, :decimal]
87
+
88
+ TickString = def_message [46, 6], AbstractTick,
89
+ [:ticker_id, :int],
90
+ [:tick_type, :int],
91
+ [:value, :string]
92
+
93
+ TickEFP = def_message [47, 6], AbstractTick,
94
+ [:ticker_id, :int],
95
+ [:tick_type, :int],
96
+ [:basis_points, :decimal],
97
+ [:formatted_basis_points, :string],
98
+ [:implied_futures_price, :decimal],
99
+ [:hold_days, :int],
100
+ [:dividend_impact, :decimal],
101
+ [:dividends_to_expiry, :decimal]
102
+
103
+ # This message is received when the market in an option or its underlier moves.
104
+ # TWS option model volatilities, prices, and deltas, along with the present
105
+ # value of dividends expected on that options underlier are received.
106
+ # TickOption message contains following @data:
107
+ # :ticker_id - Id that was specified previously in the call to reqMktData()
108
+ # :tick_type - Specifies the type of option computation (see TICK_TYPES).
109
+ # :implied_volatility - The implied volatility calculated by the TWS option
110
+ # modeler, using the specified :tick_type value.
111
+ # :delta - The option delta value.
112
+ # :option_price - The option price.
113
+ # :pv_dividend - The present value of dividends expected on the options underlier
114
+ # :gamma - The option gamma value.
115
+ # :vega - The option vega value.
116
+ # :theta - The option theta value.
117
+ # :under_price - The price of the underlying.
118
+ TickOptionComputation = TickOption =
119
+ def_message([21, 6], AbstractTick,
120
+ [:ticker_id, :int],
121
+ [:tick_type, :int],
122
+ # What is the "not yet computed" indicator:
123
+ [:implied_volatility, :decimal_limit_1], # -1 and below
124
+ [:delta, :decimal_limit_2], # -2 and below
125
+ [:option_price, :decimal_limit_1], # -1 -"-
126
+ [:pv_dividend, :decimal_limit_1], # -1 -"-
127
+ [:gamma, :decimal_limit_2], # -2 -"-
128
+ [:vega, :decimal_limit_2], # -2 -"-
129
+ [:theta, :decimal_limit_2], # -2 -"-
130
+ [:under_price, :decimal_limit_1]) do
131
+
132
+ "<TickOption #{type} for #{ticker_id}: underlying @ #{under_price}, "+
133
+ "option @ #{option_price}, IV #{implied_volatility}%, delta #{delta}, " +
134
+ "gamma #{gamma}, vega #{vega}, theta #{theta}, pv_dividend #{pv_dividend}>"
135
+ end
136
+
137
+ TickSnapshotEnd = def_message 57, [:ticker_id, :int]
138
+ =begin
139
+ def processTickByTickMsg(self, fields):
140
+ next(fields)
141
+ reqId = decode(int, fields)
142
+ tickType = decode(int, fields)
143
+ time = decode(int, fields)
144
+
145
+ if tickType == 0:
146
+ # None
147
+ pass
148
+ elif tickType == 1 or tickType == 2:
149
+ # Last or AllLast
150
+ price = decode(float, fields)
151
+ size = decode(int, fields)
152
+ mask = decode(int, fields)
153
+ class TickAttribLast(Object):
154
+ def __init__(self):
155
+ self.pastLimit = False
156
+ self.unreported = False
157
+
158
+ def __str__(self):
159
+ return "PastLimit: %d, Unreported: %d" % (self.pastLimit, self.unreported)
160
+
161
+ tickAttribLast = TickAttribLast()
162
+ tickAttribLast.pastLimit = mask & 1 != 0
163
+ tickAttribLast.unreported = mask & 2 != 0
164
+ exchange = decode(str, fields)
165
+ specialConditions = decode(str, fields)
166
+
167
+ self.wrapper.tickByTickAllLast(reqId, tickType, time, price, size, tickAttribLast,
168
+ exchange, specialConditions)
169
+ elif tickType == 3:
170
+ # BidAsk
171
+ bidPrice = decode(float, fields)
172
+ askPrice = decode(float, fields)
173
+ bidSize = decode(int, fields)
174
+ askSize = decode(int, fields)
175
+ mask = decode(int, fields)
176
+ class TickAttribBidAsk(Object):
177
+ def __init__(self):
178
+ self.bidPastLow = False
179
+ self.askPastHigh = False
180
+
181
+ def __str__(self):
182
+ return "BidPastLow: %d, AskPastHigh: %d" % (self.bidPastLow, self.askPastHigh)
183
+
184
+
185
+ tickAttribBidAsk = TickAttribBidAsk()
186
+ tickAttribBidAsk.bidPastLow = mask & 1 != 0
187
+ tickAttribBidAsk.askPastHigh = mask & 2 != 0
188
+
189
+ self.wrapper.tickByTickBidAsk(reqId, time, bidPrice, askPrice, bidSize,
190
+ askSize, tickAttribBidAsk)
191
+ elif tickType == 4:
192
+ # MidPoint
193
+ midPoint = decode(float, fields)
194
+
195
+ self.wrapper.tickByTickMidPoint(reqId, time, midPoint)
196
+ =end
197
+ TickByTick = def_message [99, 0], [:ticker_id, :int ],
198
+ [ :tick_type, :int],
199
+ [ :time, :int_date ]
200
+
201
+ ## error messages: (10189) "Failed to request tick-by-tick data:Historical data request pacing violation"
202
+ #
203
+ class TickByTick
204
+ using IBSupport # extended Array-Class from abstract_message
205
+
206
+ def resolve_mask
207
+ @data[:mask].present? ? [ @data[:mask] & 1 , @data[:mask] & 2 ] : []
208
+ end
209
+
210
+ def load
211
+ super
212
+ case @data[:tick_type ]
213
+ when 0
214
+ # do nothing
215
+ when 1, 2 # Last, AllLast
216
+ load_map [ :price, :decimal ] ,
217
+ [ :size, :int ] ,
218
+ [ :mask, :int ] ,
219
+ [ :exchange, :string ],
220
+ [ :special_conditions, :string ]
221
+ when 3 # bid/ask
222
+ load_map [ :bid_price, :decimal ],
223
+ [ :ask_price, :decimal],
224
+ [ :bid_size, :int ],
225
+ [ :ask_size, :int] ,
226
+ [ :mask, :int ]
227
+ when 4
228
+ load_map [ :mid_point, :decimal ]
229
+ end
230
+
231
+ @out_labels = case @data[ :tick_tpye ]
232
+ when 1, 2
233
+ [ "PastLimit", "Unreported" ]
234
+ when 3
235
+ [ "BitPastLow", "BidPastHigh" ]
236
+ else
237
+ []
238
+ end
239
+ end
240
+ def to_human
241
+ "< TickByTick:" + case @data[ :tick_type ]
242
+ when 1,2
243
+ "(Last) #{size} @ #{price} [#{exchange}] "
244
+ when 3
245
+ "(Bid/Ask) #{bid_size} @ #{bid_price} / #{ask_size } @ #{ask_price} "
246
+ when 4
247
+ "(Midpoint) #{mid_point } "
248
+ else
249
+ ""
250
+ end + @out_labels.zip(resolve_mask).join( "/" )
251
+ end
252
+
253
+ [:price, :size, :mask, :exchange, :specialConditions, :bid_price, :ask_price, :bid_size, :ask_size, :mid_point].each do |name|
254
+ define_method name do
255
+ @data[name]
256
+ end
257
+ end
258
+ # def method_missing method, *args
259
+ # if @data.keys.include? method
260
+ # @data[method]
261
+ # else
262
+ # error "method #{method} not known"
263
+ # end
264
+ # end
265
+ end
266
+ end # module Incoming
267
+ end # module Messages
268
+ end # module IB
@@ -0,0 +1,437 @@
1
+ require 'ib/messages/outgoing/abstract_message'
2
+
3
+ # TODO: Don't instantiate messages, use their classes as just namespace for .encode/decode
4
+
5
+ module IB
6
+ module Messages
7
+
8
+ # Outgoing IB messages (sent to TWS/Gateway)
9
+ module Outgoing
10
+ extend Messages # def_message macros
11
+
12
+ ### Defining (short) Outgoing Message classes for IB:
13
+
14
+ ## Empty messages (no data)
15
+
16
+ # Request the open orders that were placed from THIS client. Each open order
17
+ # will be fed back through the OpenOrder and OrderStatus messages ONCE.
18
+ # NB: Client with a client_id of 0 will also receive the TWS-owned open orders.
19
+ # These orders will be associated with the client and a new orderId will be
20
+ # generated. This association will persist over multiple API and TWS sessions.
21
+ RequestOpenOrders = def_message 5
22
+
23
+ # Request the open orders placed from all clients and also from TWS. Each open
24
+ # order will be fed back through the OpenOrder and OrderStatus messages ONCE.
25
+ # Note this does not re-bind those Orders to requesting Client!
26
+ # Use RequestAutoOpenOrders to request such re-binding.
27
+ RequestAllOpenOrders = def_message 16
28
+
29
+ # Request that newly created TWS orders be implicitly associated with this client.
30
+ # When a new TWS order is created, the order will be associated with this client
31
+ # and automatically fed back through the OpenOrder and OrderStatus messages.
32
+ # It is a 'continuous' request such that it gets turned 'on' when called with a
33
+ # TRUE auto_bind parameter. When it's called with FALSE auto_bind, new TWS orders
34
+ # will not bind to this client going forward. Note that TWS orders can only be
35
+ # bound to clients with a client_id of 0. TODO: how to properly test this?
36
+ # data = { :auto_bind => boolean }
37
+ RequestAutoOpenOrders = def_message 15, :auto_bind
38
+
39
+ # Requests an XML document that describes the valid parameters that a scanner
40
+ # subscription can have (for outgoing RequestScannerSubscription message).
41
+ RequestScannerParameters = def_message 24
42
+
43
+ RequestNewsArticle = def_message 84,
44
+ :request_id , # autogenerated
45
+ :provider_code,
46
+ :article_id,
47
+ :options # taglist
48
+
49
+
50
+ RequestNewsProviders = def_message 85 # no further parameters
51
+ RequestHistoricalNews = def_message 86,
52
+ :request_id , # autogenerated
53
+ :con_id,
54
+ :provider_code,
55
+ :start, # date
56
+ :total_results,
57
+ :options # taglist
58
+
59
+
60
+ CancelNewsBulletins = def_message 13
61
+ RequestCurrentTime = def_message 49
62
+ RequestGlobalCancel = def_message 58
63
+
64
+ ## Data format is: @data = { :id => ticker_id}
65
+ CancelMarketData = def_message [2, 2]
66
+ CancelMarketDepth = def_message 11
67
+ CancelScannerSubscription = def_message 23
68
+ CancelHistoricalData = def_message 25
69
+ CancelRealTimeBars = def_message 51
70
+
71
+ ## Data format is: @data = { :id => request_id }
72
+ CancelFundamentalData = def_message 53
73
+ CancelCalculateImpliedVolatility = CancelImpliedVolatility = def_message 56
74
+ CancelCalculateOptionPrice = CancelOptionPrice = def_message 57
75
+
76
+ ## Data format is: @data ={ :id => local_id of order to cancel }
77
+ CancelOrder = def_message 4
78
+
79
+ # Request the next valid ID that can be used when placing an order. Responds with
80
+ # NextValidId message, and the id returned is that next valid Id for orders.
81
+ # That ID will reflect any autobinding that has occurred (which generates new
82
+ # IDs and increments the next valid ID therein).
83
+ # @data = { :number of ids requested => int } NB: :number option is ignored by TWS!
84
+ RequestIds = def_message 8, [:number, 1]
85
+ # data = { :all_messages => boolean }
86
+ RequestNewsBulletins = def_message 12, :all_messages
87
+ # data = { :log_level => int }
88
+ SetServerLoglevel = def_message 14, :log_level
89
+ # data = { :fa_data_type => int } 1 -> groups, 2 -> Profiles, 3 -> Account Aliases
90
+ RequestFA = def_message 18, :fa_data_type
91
+ # data = { :fa_data_type => int, :xml => String }
92
+ ReplaceFA = def_message 19, :fa_data_type, :xml
93
+ # data = { :market_data_type => int }
94
+
95
+
96
+ # data => { :id => request_id (int), :contract => Contract }
97
+ #
98
+ # Special case for options: "wildcards" in the Contract fields retrieve Option chains
99
+ # strike = 0 means all strikes
100
+ # right = "" meanns both call and put
101
+ # expiry = "" means all expiries
102
+ # expiry = "2013" means all expiries in 2013
103
+ # expiry = "201311" means all expiries in Nov 2013
104
+ # You'll get several ContractData (10) messages back if there is more than one match.
105
+ # When all the matches are delivered you'll get ContractDataEnd (52) message.
106
+ RequestContractDetails = RequestContractData =
107
+ def_message([9, 8], :request_id , # autogenerated
108
+ [:contract, :serialize_long, [:sec_id_type]])
109
+
110
+ # Requests security definition option parameters for viewing a contract's option chain
111
+ # request_id: The ID chosen for the request
112
+ # underlyingSymbol
113
+ # futFopExchange: The exchange on which the returned options are trading.
114
+ # Can be set to the empty string "" for all exchanges.
115
+ # underlyingSecType: The type of the underlying security, i.e. STK
116
+ # underlyingConId: the contract ID of the underlying security.
117
+ # con_id:
118
+ # Responses via Messages::Incoming::SecurityDefinitionOptionParameter
119
+
120
+
121
+ RequestSecurityDefinitionOptionParameters = ReqSecDefOptParams = RequestOptionChainDefinition = def_message [78,0],
122
+ :request_id, # autogenerated if not specified
123
+ :symbol, # underlyingSymbol
124
+ [:exchange, ""], # futOptExchange
125
+ :sec_type, # underlyingSecType
126
+ :con_id # underlyingConId (required)
127
+
128
+ # data = { :id => ticker_id (int), :contract => Contract, :num_rows => int }
129
+
130
+
131
+ # Requests venues for which market data is returned to updateMktDepthL2
132
+ # returns MarketDepthExchanges-Message
133
+ #
134
+ RequestMarketDepthExchanges = # requires ServerVersion >= 112
135
+ def_message 82
136
+
137
+
138
+ ## actual Version supported is: 137
139
+ ## changes: MIN_SERVER_VER_SMART_DEPTH: 146 --> insert 'is_smarth_depth' after 'num_rows'
140
+ ## then: 'is_smart_depth' (bool) has to be specified in CancelMarketDepth, too
141
+ #
142
+ RequestMarketDepth = def_message([10, 5],
143
+ :request_id, # autogenerated if not specified
144
+ [:contract, :serialize_supershort ],
145
+ :num_rows,
146
+ "") # mktDataOptionsStr. ## not supported by api
147
+
148
+ # When this message is sent, TWS responds with ExecutionData messages, each
149
+ # containing the execution report that meets the specified criteria.
150
+ # @data={:id => int: :request_id,
151
+ # :client_id => int: Filter the results based on the clientId.
152
+ # :account => Filter the results based on based on account code.
153
+ # Note: this is only relevant for Financial Advisor accts.
154
+ # :sec_type => Filter the results based on the order security type.
155
+ # :time => Filter the results based on execution reports received
156
+ # after the specified time - format "yyyymmdd-hh:mm:ss"
157
+ # :symbol => Filter the results based on the order symbol.
158
+ # :exchange => Filter the results based on the order exchange
159
+ # :side => Filter the results based on the order action: BUY/SELL/SSHORT
160
+ RequestExecutions = def_message([7, 3],
161
+ :request_id, # autogenerated if not specified
162
+ :client_id,
163
+ :account,
164
+ :time, # Format "yyyymmdd-hh:mm:ss"
165
+ :symbol,
166
+ :sec_type,
167
+ :exchange,
168
+ :side)
169
+
170
+ # data = { :id => ticker_id (int),
171
+ # :contract => IB::Contract,
172
+ # :exercise_action => int, 1 = exercise, 2 = lapse
173
+ # :exercise_quantity => int, The number of contracts to be exercised
174
+ # :account => string,
175
+ # :override => int: Specifies whether your setting will override the
176
+ # system's natural action. For example, if your action
177
+ # is "exercise" and the option is not in-the-money, by
178
+ # natural action the option would not exercise. If you
179
+ # have override set to "yes" the natural action would be
180
+ # overridden and the out-of-the money option would be
181
+ # exercised. Values are:
182
+ # - 0 = do not override
183
+ # - 1 = override
184
+ ExerciseOptions = def_message([ 21, 2 ],
185
+ # :request_id, # id -> required # todo : TEST
186
+ [:contract, :serialize_short],
187
+ :exercise_action,
188
+ :exercise_quantity,
189
+ :account,
190
+ :override)
191
+
192
+
193
+ # The API can receive frozen market data from Trader Workstation. Frozen market
194
+ # data is the last data recorded in our system. During normal trading hours,
195
+ # the API receives real-time market data. If you use this function, you are
196
+ # telling TWS to automatically switch to frozen market data AFTER the close.
197
+ # Then, before the opening of the next trading day, market data will automatically
198
+ # switch back to real-time market data.
199
+ # :market_data_type = 1 (:real_time) for real-time streaming, 2 (:frozen) for frozen market data
200
+ # = 3 (:delayed) for delayed streaming , 4 (:frozen_delayed) for frozen delayed
201
+ RequestMarketDataType =
202
+ def_message 59, [:market_data_type,
203
+ lambda { |type| MARKET_DATA_TYPES.invert[type] || type }, []]
204
+
205
+ # Send this message to receive Reuters global fundamental data. There must be
206
+ # a subscription to Reuters Fundamental set up in Account Management before
207
+ # you can receive this data.
208
+ # data = { :id => int: :request_id,
209
+ # :contract => Contract,
210
+ # :report_type => String: one of the following:
211
+ # 'estimates' - Estimates
212
+ # 'finstat' - Financial statements
213
+ # 'snapshot' - Summary }a
214
+ # ReportsFinSummary Financial summary
215
+ #ReportsOwnership Company's ownership (Can be large in size)
216
+ #ReportSnapshot Company's financial overview
217
+ #ReportsFinStatements Financial Statements
218
+ #RESC Analyst Estimates
219
+ #CalendarReport Company's calendar
220
+ RequestFundamentalData =
221
+ def_message([52,2],
222
+ :request_id, # autogenerated if not specified
223
+ [:contract, :serialize, :primary_exchange],
224
+ :report_type,
225
+ "" )
226
+
227
+ # Returns the timestamp of earliest available historical data for a contract and data type.
228
+ # :what_to_show: type of data for head timestamp - "BID", "ASK", "TRADES", etc
229
+ # :use_rth : use regular trading hours only, 1 for yes or 0 for no
230
+ # format_data : set to 2 to obtain it like system time format in second ---> don't change
231
+ RequestHeadTimeStamp =
232
+ def_message( [87,0], :request_id, # autogenerated
233
+ [:contract, :serialize_short, [:primary_exchange,:include_expired] ],
234
+ [:use_rth, 1 ],
235
+ [:what_to_show, 'Trades' ],
236
+ [:format_date, 2 ] ) ## don't change!
237
+
238
+ CancelHeadTimeStamp =
239
+ def_message [90,0 ] # , :(request_)id #required
240
+
241
+
242
+
243
+ RequestHistogramData =
244
+ def_message( [88, 0], :request_id, # autogenerated
245
+ [:contract, :serialize_short, [:primary_exchange,:include_expired] ],
246
+ [:use_rth, 1 ],
247
+ [:time_period ] )
248
+
249
+ CancelHistogramData =
250
+ def_message [89,0 ] # , :(request_)id required
251
+
252
+ RequestCalculateImpliedVolatility = CalculateImpliedVolatility =
253
+ RequestImpliedVolatility =
254
+ def_message([ 54,3 ],:request_id, # autogenerated
255
+ [:contract, :serialize_short, :primary_exchange],
256
+ :option_price,
257
+ :under_price,
258
+ [:implied_volatility_options_count, 0],
259
+ [:implied_volatility_options_conditions, ''])
260
+
261
+ # data = { :request_id => int, :contract => Contract,
262
+ # :volatility => double, :under_price => double }
263
+ RequestCalculateOptionPrice = CalculateOptionPrice = RequestOptionPrice =
264
+ def_message([ 55, 3], :request_id, #autogenerated if not specified
265
+ [:contract, :serialize_short, :primary_exchange],
266
+ :volatility,
267
+ :under_price,
268
+ [:implied_volatility_options_count, 0],
269
+ [:implied_volatility_options_conditions, ''])
270
+
271
+ # Start receiving market scanner results through the ScannerData messages.
272
+ # @data = { :id => ticker_id (int),
273
+ # :number_of_rows => int: number of rows of data to return for a query.
274
+ # :instrument => The instrument type for the scan. Values include
275
+ # 'STK', - US stocks
276
+ # 'STOCK.HK' - Asian stocks
277
+ # 'STOCK.EU' - European stocks
278
+ # :location_code => Legal Values include:
279
+ # - STK.US - US stocks
280
+ # - STK.US.MAJOR - US stocks (without pink sheet)
281
+ # - STK.US.MINOR - US stocks (only pink sheet)
282
+ # - STK.HK.SEHK - Hong Kong stocks
283
+ # - STK.HK.ASX - Australian Stocks
284
+ # - STK.EU - European stocks
285
+ # :scan_code => The type of the scan, such as HIGH_OPT_VOLUME_PUT_CALL_RATIO.
286
+ # :above_price => double: Only contracts with a price above this value.
287
+ # :below_price => double: Only contracts with a price below this value.
288
+ # :above_volume => int: Only contracts with a volume above this value.
289
+ # :market_cap_above => double: Only contracts with a market cap above this
290
+ # :market_cap_below => double: Only contracts with a market cap below this value.
291
+ # :moody_rating_above => Only contracts with a Moody rating above this value.
292
+ # :moody_rating_below => Only contracts with a Moody rating below this value.
293
+ # :sp_rating_above => Only contracts with an S&P rating above this value.
294
+ # :sp_rating_below => Only contracts with an S&P rating below this value.
295
+ # :maturity_date_above => Only contracts with a maturity date later than this
296
+ # :maturity_date_below => Only contracts with a maturity date earlier than this
297
+ # :coupon_rate_above => double: Only contracts with a coupon rate above this
298
+ # :coupon_rate_below => double: Only contracts with a coupon rate below this
299
+ # :exclude_convertible => Exclude convertible bonds.
300
+ # :scanner_setting_pairs => Used with the scan_code to help further narrow your query.
301
+ # Scanner Setting Pairs are delimited by slashes, making
302
+ # this parameter open ended. Example is "Annual,true" -
303
+ # when used with 'Top Option Implied Vol % Gainers' scan
304
+ # would return annualized volatilities.
305
+ # :average_option_volume_above => int: Only contracts with average volume above this
306
+ # :stock_type_filter => Valid values are:
307
+ # 'ALL' (excludes nothing)
308
+ # 'STOCK' (excludes ETFs)
309
+ # 'ETF' (includes ETFs) }
310
+ # ------------
311
+ # To learn all valid parameter values that a scanner subscription can have,
312
+ # first subscribe to ScannerParameters and send RequestScannerParameters message.
313
+ # Available scanner parameters values will be listed in received XML document.
314
+ RequestScannerSubscription =
315
+ def_message([22, 3], :request_id ,
316
+ [:number_of_rows, -1], # was: EOL,
317
+ :instrument,
318
+ :location_code,
319
+ :scan_code,
320
+ :above_price,
321
+ :below_price,
322
+ :above_volume,
323
+ :market_cap_above,
324
+ :market_cap_below,
325
+ :moody_rating_above,
326
+ :moody_rating_below,
327
+ :sp_rating_above,
328
+ :sp_rating_below,
329
+ :maturity_date_above,
330
+ :maturity_date_below,
331
+ :coupon_rate_above,
332
+ :coupon_rate_below,
333
+ :exclude_convertible,
334
+ :average_option_volume_above, # ?
335
+ :scanner_setting_pairs,
336
+ :stock_type_filter)
337
+
338
+
339
+
340
+ require 'ib/messages/outgoing/place_order'
341
+ require 'ib/messages/outgoing/bar_requests'
342
+ require 'ib/messages/outgoing/account_requests'
343
+ require 'ib/messages/outgoing/request_marketdata'
344
+ require 'ib/messages/outgoing/request_tick_data'
345
+
346
+ end # module Outgoing
347
+ end # module Messages
348
+ end # module IB
349
+
350
+ __END__
351
+ ## python: message.py
352
+ REQ_MKT_DATA = 1
353
+ CANCEL_MKT_DATA = 2
354
+ PLACE_ORDER = 3
355
+ CANCEL_ORDER = 4
356
+ REQ_OPEN_ORDERS = 5
357
+ REQ_ACCT_DATA = 6
358
+ REQ_EXECUTIONS = 7
359
+ REQ_IDS = 8
360
+ REQ_CONTRACT_DATA = 9
361
+ REQ_MKT_DEPTH = 10
362
+ CANCEL_MKT_DEPTH = 11
363
+ REQ_NEWS_BULLETINS = 12
364
+ CANCEL_NEWS_BULLETINS = 13
365
+ SET_SERVER_LOGLEVEL = 14
366
+ REQ_AUTO_OPEN_ORDERS = 15
367
+ REQ_ALL_OPEN_ORDERS = 16
368
+ REQ_MANAGED_ACCTS = 17
369
+ REQ_FA = 18
370
+ REPLACE_FA = 19
371
+ REQ_HISTORICAL_DATA = 20
372
+ EXERCISE_OPTIONS = 21
373
+ REQ_SCANNER_SUBSCRIPTION = 22
374
+ CANCEL_SCANNER_SUBSCRIPTION = 23
375
+ REQ_SCANNER_PARAMETERS = 24
376
+ CANCEL_HISTORICAL_DATA = 25
377
+ REQ_CURRENT_TIME = 49
378
+ REQ_REAL_TIME_BARS = 50
379
+ CANCEL_REAL_TIME_BARS = 51
380
+ REQ_FUNDAMENTAL_DATA = 52
381
+ CANCEL_FUNDAMENTAL_DATA = 53
382
+ REQ_CALC_IMPLIED_VOLAT = 54
383
+ REQ_CALC_OPTION_PRICE = 55
384
+ CANCEL_CALC_IMPLIED_VOLAT = 56
385
+ CANCEL_CALC_OPTION_PRICE = 57
386
+ REQ_GLOBAL_CANCEL = 58
387
+ REQ_MARKET_DATA_TYPE = 59 --> supported by ib-ruby 0.94
388
+
389
+ REQ_POSITIONS = 61 supported now
390
+ REQ_ACCOUNT_SUMMARY = 62 supported now
391
+
392
+ CANCEL_ACCOUNT_SUMMARY = 63 supported now
393
+
394
+ CANCEL_POSITIONS = 64 supported now
395
+ VERIFY_REQUEST = 65
396
+ VERIFY_MESSAGE = 66
397
+ QUERY_DISPLAY_GROUPS = 67
398
+ SUBSCRIBE_TO_GROUP_EVENTS = 68
399
+ UPDATE_DISPLAY_GROUP = 69
400
+ UNSUBSCRIBE_FROM_GROUP_EVENTS = 70
401
+ START_API = 71
402
+ VERIFY_AND_AUTH_REQUEST = 72
403
+ VERIFY_AND_AUTH_MESSAGE = 73
404
+ REQ_POSITIONS_MULTI = 74 supported now
405
+ CANCEL_POSITIONS_MULTI = 75 supported now
406
+
407
+ REQ_ACCOUNT_UPDATES_MULTI = 76 supported now
408
+
409
+ CANCEL_ACCOUNT_UPDATES_MULTI = 77 supported now
410
+
411
+ REQ_SEC_DEF_OPT_PARAMS = 78 supported now
412
+ REQ_SOFT_DOLLAR_TIERS = 79
413
+ REQ_FAMILY_CODES = 80
414
+ REQ_MATCHING_SYMBOLS = 81
415
+ REQ_MKT_DEPTH_EXCHANGES = 82
416
+ REQ_SMART_COMPONENTS = 83
417
+ REQ_NEWS_ARTICLE = 84 in preparation
418
+ REQ_NEWS_PROVIDERS = 85 in preparatino
419
+ REQ_HISTORICAL_NEWS = 86 in preparation
420
+
421
+ REQ_HEAD_TIMESTAMP = 87 supported now
422
+
423
+ REQ_HISTOGRAM_DATA = 88 supported now
424
+
425
+ CANCEL_HISTOGRAM_DATA = 89 supported now
426
+
427
+ CANCEL_HEAD_TIMESTAMP = 90 supported now
428
+
429
+ REQ_MARKET_RULE = 91
430
+ REQ_PNL = 92
431
+ CANCEL_PNL = 93
432
+ REQ_PNL_SINGLE = 94
433
+ CANCEL_PNL_SINGLE = 95
434
+ REQ_HISTORICAL_TICKS = 96
435
+ REQ_TICK_BY_TICK_DATA = 97
436
+ CANCEL_TICK_BY_TICK_DATA = 98
437
+