ib-api 10.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +52 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CLAUDE.md +131 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +17 -0
  8. data/Gemfile.lock +120 -0
  9. data/Guardfile +24 -0
  10. data/LICENSE +674 -0
  11. data/LLM_GUIDE.md +388 -0
  12. data/README.md +114 -0
  13. data/Rakefile +11 -0
  14. data/VERSION +1 -0
  15. data/api.gemspec +50 -0
  16. data/bin/console +96 -0
  17. data/bin/console.yml +3 -0
  18. data/bin/setup +8 -0
  19. data/bin/simple +91 -0
  20. data/changelog.md +32 -0
  21. data/conditions/ib/execution_condition.rb +31 -0
  22. data/conditions/ib/margin_condition.rb +28 -0
  23. data/conditions/ib/order_condition.rb +29 -0
  24. data/conditions/ib/percent_change_condition.rb +34 -0
  25. data/conditions/ib/price_condition.rb +44 -0
  26. data/conditions/ib/time_condition.rb +42 -0
  27. data/conditions/ib/volume_condition.rb +36 -0
  28. data/lib/class_extensions.rb +167 -0
  29. data/lib/ib/base.rb +109 -0
  30. data/lib/ib/base_properties.rb +178 -0
  31. data/lib/ib/connection.rb +573 -0
  32. data/lib/ib/constants.rb +402 -0
  33. data/lib/ib/contract.rb +30 -0
  34. data/lib/ib/errors.rb +52 -0
  35. data/lib/ib/messages/abstract_message.rb +68 -0
  36. data/lib/ib/messages/incoming/abstract_message.rb +116 -0
  37. data/lib/ib/messages/incoming/abstract_tick.rb +25 -0
  38. data/lib/ib/messages/incoming/account_message.rb +26 -0
  39. data/lib/ib/messages/incoming/alert.rb +34 -0
  40. data/lib/ib/messages/incoming/contract_data.rb +105 -0
  41. data/lib/ib/messages/incoming/contract_message.rb +13 -0
  42. data/lib/ib/messages/incoming/delta_neutral_validation.rb +23 -0
  43. data/lib/ib/messages/incoming/execution_data.rb +50 -0
  44. data/lib/ib/messages/incoming/histogram_data.rb +30 -0
  45. data/lib/ib/messages/incoming/historical_data.rb +65 -0
  46. data/lib/ib/messages/incoming/historical_data_update.rb +50 -0
  47. data/lib/ib/messages/incoming/managed_accounts.rb +21 -0
  48. data/lib/ib/messages/incoming/market_depth.rb +34 -0
  49. data/lib/ib/messages/incoming/market_depth_l2.rb +15 -0
  50. data/lib/ib/messages/incoming/next_valid_id.rb +19 -0
  51. data/lib/ib/messages/incoming/open_order.rb +290 -0
  52. data/lib/ib/messages/incoming/order_status.rb +85 -0
  53. data/lib/ib/messages/incoming/portfolio_value.rb +47 -0
  54. data/lib/ib/messages/incoming/position_data.rb +21 -0
  55. data/lib/ib/messages/incoming/positions_multi.rb +15 -0
  56. data/lib/ib/messages/incoming/real_time_bar.rb +32 -0
  57. data/lib/ib/messages/incoming/receive_fa.rb +30 -0
  58. data/lib/ib/messages/incoming/scanner_data.rb +54 -0
  59. data/lib/ib/messages/incoming/tick_by_tick.rb +77 -0
  60. data/lib/ib/messages/incoming/tick_efp.rb +18 -0
  61. data/lib/ib/messages/incoming/tick_generic.rb +12 -0
  62. data/lib/ib/messages/incoming/tick_option.rb +60 -0
  63. data/lib/ib/messages/incoming/tick_price.rb +60 -0
  64. data/lib/ib/messages/incoming/tick_size.rb +55 -0
  65. data/lib/ib/messages/incoming/tick_string.rb +13 -0
  66. data/lib/ib/messages/incoming.rb +292 -0
  67. data/lib/ib/messages/outgoing/abstract_message.rb +84 -0
  68. data/lib/ib/messages/outgoing/bar_request_message.rb +247 -0
  69. data/lib/ib/messages/outgoing/new-place-order.rb +193 -0
  70. data/lib/ib/messages/outgoing/old-place-order.rb +147 -0
  71. data/lib/ib/messages/outgoing/place_order.rb +149 -0
  72. data/lib/ib/messages/outgoing/request_account_summary.rb +79 -0
  73. data/lib/ib/messages/outgoing/request_historical_data.rb +182 -0
  74. data/lib/ib/messages/outgoing/request_market_data.rb +102 -0
  75. data/lib/ib/messages/outgoing/request_market_depth.rb +57 -0
  76. data/lib/ib/messages/outgoing/request_real_time_bars.rb +48 -0
  77. data/lib/ib/messages/outgoing/request_scanner_subscription.rb +73 -0
  78. data/lib/ib/messages/outgoing/request_tick_by_tick_data.rb +21 -0
  79. data/lib/ib/messages/outgoing.rb +410 -0
  80. data/lib/ib/messages.rb +139 -0
  81. data/lib/ib/order_condition.rb +26 -0
  82. data/lib/ib/plugins.rb +27 -0
  83. data/lib/ib/prepare_data.rb +61 -0
  84. data/lib/ib/raw_message_parser.rb +99 -0
  85. data/lib/ib/socket.rb +83 -0
  86. data/lib/ib/support.rb +236 -0
  87. data/lib/ib/version.rb +6 -0
  88. data/lib/ib-api.rb +44 -0
  89. data/lib/server_versions.rb +145 -0
  90. data/lib/support/array_function.rb +28 -0
  91. data/lib/support/logging.rb +45 -0
  92. data/models/ib/account.rb +72 -0
  93. data/models/ib/account_value.rb +33 -0
  94. data/models/ib/bag.rb +55 -0
  95. data/models/ib/bar.rb +31 -0
  96. data/models/ib/combo_leg.rb +127 -0
  97. data/models/ib/contract.rb +411 -0
  98. data/models/ib/contract_detail.rb +118 -0
  99. data/models/ib/execution.rb +67 -0
  100. data/models/ib/forex.rb +12 -0
  101. data/models/ib/future.rb +64 -0
  102. data/models/ib/index.rb +14 -0
  103. data/models/ib/option.rb +149 -0
  104. data/models/ib/option_detail.rb +84 -0
  105. data/models/ib/order.rb +720 -0
  106. data/models/ib/order_state.rb +155 -0
  107. data/models/ib/portfolio_value.rb +86 -0
  108. data/models/ib/spread.rb +176 -0
  109. data/models/ib/stock.rb +25 -0
  110. data/models/ib/underlying.rb +32 -0
  111. data/plugins/ib/advanced-account.rb +442 -0
  112. data/plugins/ib/alerts/base-alert.rb +125 -0
  113. data/plugins/ib/alerts/gateway-alerts.rb +15 -0
  114. data/plugins/ib/alerts/order-alerts.rb +73 -0
  115. data/plugins/ib/auto-adjust.rb +0 -0
  116. data/plugins/ib/connection-tools.rb +122 -0
  117. data/plugins/ib/eod.rb +326 -0
  118. data/plugins/ib/greeks.rb +102 -0
  119. data/plugins/ib/managed-accounts.rb +274 -0
  120. data/plugins/ib/market-price.rb +150 -0
  121. data/plugins/ib/option-chain.rb +167 -0
  122. data/plugins/ib/order-flow.rb +157 -0
  123. data/plugins/ib/order-prototypes/abstract.rb +67 -0
  124. data/plugins/ib/order-prototypes/adaptive.rb +40 -0
  125. data/plugins/ib/order-prototypes/all-in-one.rb +46 -0
  126. data/plugins/ib/order-prototypes/combo.rb +46 -0
  127. data/plugins/ib/order-prototypes/forex.rb +40 -0
  128. data/plugins/ib/order-prototypes/limit.rb +193 -0
  129. data/plugins/ib/order-prototypes/market.rb +116 -0
  130. data/plugins/ib/order-prototypes/pegged.rb +169 -0
  131. data/plugins/ib/order-prototypes/premarket.rb +31 -0
  132. data/plugins/ib/order-prototypes/stop.rb +202 -0
  133. data/plugins/ib/order-prototypes/volatility.rb +39 -0
  134. data/plugins/ib/order-prototypes.rb +118 -0
  135. data/plugins/ib/probability-of-expiring.rb +109 -0
  136. data/plugins/ib/process-orders.rb +155 -0
  137. data/plugins/ib/roll.rb +86 -0
  138. data/plugins/ib/spread-prototypes/butterfly.rb +77 -0
  139. data/plugins/ib/spread-prototypes/calendar.rb +97 -0
  140. data/plugins/ib/spread-prototypes/stock-spread.rb +56 -0
  141. data/plugins/ib/spread-prototypes/straddle.rb +70 -0
  142. data/plugins/ib/spread-prototypes/strangle.rb +93 -0
  143. data/plugins/ib/spread-prototypes/vertical.rb +83 -0
  144. data/plugins/ib/spread-prototypes.rb +70 -0
  145. data/plugins/ib/symbols/abstract.rb +136 -0
  146. data/plugins/ib/symbols/bonds.rb +28 -0
  147. data/plugins/ib/symbols/cfd.rb +19 -0
  148. data/plugins/ib/symbols/combo.rb +46 -0
  149. data/plugins/ib/symbols/commodity.rb +17 -0
  150. data/plugins/ib/symbols/forex.rb +41 -0
  151. data/plugins/ib/symbols/futures.rb +127 -0
  152. data/plugins/ib/symbols/index.rb +43 -0
  153. data/plugins/ib/symbols/options.rb +99 -0
  154. data/plugins/ib/symbols/stocks.rb +44 -0
  155. data/plugins/ib/symbols/version.rb +5 -0
  156. data/plugins/ib/symbols.rb +118 -0
  157. data/plugins/ib/verify.rb +226 -0
  158. data/symbols/w20.yml +210 -0
  159. data/t.txt +20 -0
  160. data/update.md +71 -0
  161. metadata +327 -0
@@ -0,0 +1,290 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+ using IB::Support
5
+ # OpenOrder is the longest message with complex processing logics
6
+ OpenOrder =
7
+ def_message [5, 0], # updated to v. 34 according to python (decoder.py processOpenOrder)
8
+ [ :order, :local_id, :int],
9
+
10
+ [ :contract, :contract], # read standard-contract
11
+ # [ con_id, symbol,. sec_type, expiry, strike, right, multiplier,
12
+ # exchange, currency, local_symbol, trading_class ]
13
+
14
+ [ :order, :action, :string ],
15
+ [ :order, :total_quantity, :decimal ],
16
+ [ :order, :order_type, :string ],
17
+ [ :order, :limit_price, :decimal ],
18
+ [ :order, :aux_price, :decimal ],
19
+ [ :order, :tif, :string ],
20
+ [ :order, :oca_group, :string ],
21
+ [ :order, :account, :string ],
22
+ [ :order, :open_close, :string ],
23
+ [ :order, :origin, :int ],
24
+ [ :order, :order_ref, :string ],
25
+ [ :order, :client_id, :int ],
26
+ [ :order, :perm_id, :int ],
27
+ [ :order, :outside_rth, :boolean ],
28
+ [ :order, :hidden, :boolean ],
29
+ [ :order, :discretionary_amount, :decimal ],
30
+ [ :order, :good_after_time, :string ],
31
+ [ :shares_allocation, :string ], # skip_share_allocation
32
+
33
+ [ :order, :fa_group, :string ], # fa_params
34
+ [ :order, :fa_method, :string ], # fa_params
35
+ [ :order, :fa_percentage, :string ], # fa_params
36
+ [ :order, :fa_profile, :string ], # fa_params
37
+
38
+ [ :order, :model_code, :string ],
39
+ [ :order, :good_till_date, :string ],
40
+ [ :order, :rule_80a, :string ],
41
+ [ :order, :percent_offset, :decimal ],
42
+ [ :order, :settling_firm, :string ],
43
+ [ :order, :short_sale_slot, :int ], # short_sale_parameter
44
+ [ :order, :designated_location, :string ], # short_sale_parameter
45
+ [ :order, :exempt_code, :int ], # short_sale_parameter
46
+ [ :order, :auction_strategy, :int ], # auction_strategy
47
+ [ :order, :starting_price, :decimal ], # auction_strategy
48
+ [ :order, :stock_ref_price, :decimal ], # auction_strategy
49
+ [ :order, :delta, :decimal ], # auction_strategy
50
+ [ :order, :stock_range_lower, :decimal ], # auction_strategy
51
+ [ :order, :stock_range_upper, :decimal ], # auction_strategy
52
+ [ :order, :display_size, :int ],
53
+ #@order.rth_only = @socket.read_boolean
54
+ [ :order, :block_order, :boolean ],
55
+ [ :order, :sweep_to_fill, :boolean ],
56
+ [ :order, :all_or_none, :boolean ],
57
+ [ :order, :min_quantity, :int ],
58
+ [ :order, :oca_type, :int ],
59
+ [ :order, :etrade_only, :boolean ], # skip etrade only
60
+ [ :order, :firm_quote_only, :boolean ], # skip firm quote only
61
+ [ :order, :nbbo_price_cap, :string ], # skip nbbo_price_cap
62
+ [ :order, :parent_id, :int ],
63
+ [ :order, :trigger_method, :int ],
64
+ [ :order, :volatility, :decimal ], # vol_order_params
65
+ [ :order, :volatility_type, :int ], # vol_order_params
66
+ [ :order, :delta_neutral_order_type,:string ], # vol_order_params
67
+ [ :order, :delta_neutral_aux_price, :decimal ] # vol_order_params
68
+
69
+ class OpenOrder
70
+
71
+ # Accessors to make OpenOrder API-compatible with OrderStatus message
72
+
73
+ def client_id
74
+ order.client_id
75
+ end
76
+
77
+ def parent_id
78
+ order.parent_id
79
+ end
80
+
81
+ def perm_id
82
+ order.perm_id
83
+ end
84
+
85
+ def local_id
86
+ order.local_id
87
+ end
88
+
89
+ alias order_id local_id
90
+
91
+ def status
92
+ order.status
93
+ end
94
+
95
+ def conditions
96
+ order.conditions
97
+ end
98
+
99
+ # Object accessors
100
+
101
+ def order
102
+ @order ||= IB::Order.new @data[ :order].merge(:order_state => order_state)
103
+ end
104
+
105
+ def order_state
106
+ @order_state ||= IB::OrderState.new(
107
+ @data[ :order_state].merge(
108
+ :local_id => @data[ :order ][ :local_id ],
109
+ :perm_id => @data[ :order ][ :perm_id ],
110
+ :parent_id => @data[ :order ][ :parent_id],
111
+ :client_id => @data[ :order ][ :client_id] ) )
112
+ end
113
+
114
+ def contract
115
+ @contract ||= IB::Contract.build( @data[ :contract].merge(:underlying => underlying))
116
+ end
117
+
118
+ def underlying
119
+ @underlying = @data[ :underlying_present ] ? IB::Underlying.new(@data[ :underlying ] ) : nil
120
+ end
121
+
122
+ alias under_comp underlying
123
+
124
+ def load
125
+ super
126
+
127
+ # load_map [proc { | | (@data[ :order][:delta_neutral_order_type] != 'None') },
128
+ load_map [ proc { | | filled?(@data[ :order][:delta_neutral_order_type ] ) }, # todo Testcase!
129
+ # As of client v.52, we may receive delta... params in openOrder
130
+ [ :order, :delta_neutral_con_id, :int ],
131
+ [ :order, :delta_neutral_settling_firm, :string ],
132
+ [ :order, :delta_neutral_clearing_account, :string ],
133
+ [ :order, :delta_neutral_clearing_intent, :string ],
134
+ [ :order, :delta_neutral_open_close, :string ],
135
+ [ :order, :delta_neutral_short_sale, :bool ],
136
+ [ :order, :delta_neutral_short_sale_slot, :int ],
137
+ [ :order, :delta_neutral_designated_location, :string ] ], # end proc
138
+ [ :order, :continuous_update, :int ],
139
+ [ :order, :reference_price_type, :int ], ### end VolOrderParams (Python)
140
+ [ :order, :trail_stop_price, :decimal ], # not trail-orders. see below
141
+ [ :order, :trailing_percent, :decimal ],
142
+ [ :order, :basis_points, :decimal ],
143
+ [ :order, :basis_points_type, :int ],
144
+
145
+ [ :contract, :legs_description, :string ],
146
+
147
+ # As of client v.55, we receive in OpenOrder for Combos:
148
+ # Contract.orderComboLegs Array
149
+ # Order.leg_prices Array
150
+ [ :contract, :combo_legs, :array, proc do |_|
151
+ IB::ComboLeg.new :con_id => @buffer.read_int,
152
+ :ratio => @buffer.read_int,
153
+ :action => @buffer.read_string,
154
+ :exchange => @buffer.read_string,
155
+ :open_close => @buffer.read_int,
156
+ :short_sale_slot => @buffer.read_int,
157
+ :designated_location => @buffer.read_string,
158
+ :exempt_code => @buffer.read_int
159
+ end ],
160
+ [ :order, :leg_prices, :array, proc { |_| buffer.read_decimal } ], # needs testing
161
+ [ :order, :combo_params, :hash ],
162
+ #, proc do |_|
163
+ # { tag: buffer.read_string, value: buffer.read_string } # needs testing
164
+ # end],
165
+
166
+ [ :order, :scale_init_level_size, :int ],
167
+ [ :order, :scale_subs_level_size, :int ],
168
+
169
+ [ :order, :scale_price_increment, :decimal ],
170
+ [ proc { | | filled?( @data[ :order ][ :scale_price_increment ] ) }, # true or false
171
+ [ :order, :scale_price_adjust_value, :decimal ], # if true
172
+ [ :order, :scale_price_adjust_interval, :int ] ,
173
+ [ :order, :scale_profit_offset, :decimal ],
174
+ [ :order, :scale_auto_reset, :boolean ],
175
+ [ :order, :scale_init_position, :int ],
176
+ [ :order, :scale_init_fill_qty, :decimal ],
177
+ [ :order, :scale_random_percent, :boolean ] ], # end of scale price increment
178
+
179
+ [ :order, :hedge_type, :string ], # can be nil
180
+ [ proc { | | filled?(@data[ :order ][ :hedge_type ] ) }, # true or false
181
+ [ :order, :hedge_param, :string ] ], # if true
182
+
183
+ [ :order, :opt_out_smart_routing, :boolean ],
184
+ [ :order, :clearing_account, :string ],
185
+ [ :order, :clearing_intent, :string ],
186
+ [ :order, :not_held, :boolean ],
187
+
188
+ [ :underlying_present, :boolean ],
189
+ [ proc { | | filled?(@data[ :underlying_present ] ) }, # true or false
190
+ [ :underlying, :con_id, :int ],
191
+ [ :underlying, :delta, :decimal ],
192
+ [ :underlying, :price, :decimal ] ], # end of underlying present?
193
+
194
+ # TODO: Test Order with algo_params, scale and legs!
195
+ [ :order, :algo_strategy, :string],
196
+ [ proc { | | filled?(@data[ :order ][ :algo_strategy ] ) }, # true of false
197
+ [ :order, :algo_params, :hash ] ], # of true
198
+
199
+ [ :order, :solicided, :boolean ],
200
+
201
+ ## whatif serverVersion >= MIN_SERVER_VER_WHAT_IF_EXT_FIELDS
202
+ [ :order, :what_if, :boolean ],
203
+ [ :order_state, :status, :string ],
204
+ [ :order_state, :init_margin_before, :decimal ], # nil unless what_if is true
205
+ [ :order_state, :maint_margin_before, :decimal ], # nil unless what_if is true
206
+ [ :order_state, :equity_with_loan_before, :decimal ], # nil unless what_if is true
207
+ [ :order_state, :init_margin_change, :decimal ], # nil unless what_if is true
208
+ [ :order_state, :maint_margin_change, :decimal ], # nil unless what_if is true
209
+ [ :order_state, :equity_with_loan_change, :decimal ], # nil unless what_if is true
210
+ [ :order_state, :init_margin_after, :decimal ], # nil unless what_if is true
211
+ [ :order_state, :maint_margin_after, :decimal ], # nil unless what_if is true
212
+ [ :order_state, :equity_with_loan_after, :decimal ], # nil unless what_if is true
213
+ [ :order_state, :commission, :decimal ], # nil unless what_if is true
214
+ [ :order_state, :min_commission, :decimal ], # nil unless what_if is true
215
+ [ :order_state, :max_commission, :decimal ], # nil unless what_if is true
216
+ [ :order_state, :commission_currency, :string ], # nil unless what_if is true
217
+ [ :order_state, :warning_text, :string ], # nil unless what_if is true
218
+
219
+
220
+ [ :order, :random_size, :boolean ],
221
+ [ :order, :random_price, :boolean ],
222
+
223
+ ## todo: ordertype = PEG BENCH -- -> test!
224
+ [ proc { @data[ :order ][ :order_type ] == 'PEG BENCH' }, # true of false
225
+ [ :order, :reference_contract_id, :int ],
226
+ [ :order, :is_pegged_change_amount_decrease, :bool ],
227
+ [ :order, :pegged_change_amount, :decimal ],
228
+ [ :order, :reference_change_amount, :decimal ],
229
+ [ :order, :reference_exchange_id, :string ] ], # end special parameters PEG BENCH
230
+
231
+ [ :order , :conditions, :array, proc { IB::OrderCondition.make_from( @buffer ) } ],
232
+ [ proc { !@data[ :order ][ :conditions ].blank? }, # true or false
233
+ [ :order, :conditions_ignore_rth, :bool ],
234
+ [ :order, :conditions_cancel_order,:bool ] ],
235
+ #AdjustedOrderParams
236
+ [ :order, :adjusted_order_type, :string ],
237
+ [ :order, :trigger_price, :decimal ],
238
+ [ :order, :trail_stop_price, :decimal ], # Traillimit orders
239
+ [ :order, :limit_price_offset, :decimal ],
240
+ [ :order, :adjusted_stop_price, :decimal ],
241
+ [ :order, :adjusted_stop_limit_price, :decimal ],
242
+ [ :order, :adjusted_trailing_amount, :decimal ],
243
+ [ :order, :adjustable_trailing_unit, :int ],
244
+ # SoftDollarTier
245
+ [ :order, :soft_dollar_tier_name, :string_not_null ],
246
+ [ :order, :soft_dollar_tier_value, :string_not_null ],
247
+ [ :order, :soft_dollar_tier_display_name, :string_not_null ],
248
+ [ :order, :cash_qty, :decimal ],
249
+ [ :order, :dont_use_auto_price_for_hedge, :bool ],
250
+ [ :order, :is_O_ms_container, :bool ],
251
+ [ :order, :discretionary_up_to_limit_price, :bool ],
252
+ [ :order, :use_price_management_algo, :bool ],
253
+ [ :order, :duration, :int ],
254
+ [ :order, :post_to_ats, :int ],
255
+ [ :order, :auto_cancel_parent, :bool ]
256
+ # not implemented now > Server Version 170
257
+ # PEGBEST_PEGMID_OFFSETS:
258
+ # [:order, :min_trade_qty, :int ],
259
+ # [:order, :min_compete_size, :int ],
260
+ # [:order, :compete_against_best_offset, :decimal],
261
+ # [:order, :mid_offset_at_whole, :decimal ],
262
+ # [:order, :mid_offset_at_half, :decimal ]
263
+ # not implemented now > Server Version 183
264
+ # [:order, :customer_account, :string]
265
+ # not implemented now > Server Version 184
266
+ # [:order, :professional_customer, :bool]
267
+
268
+ end
269
+
270
+ # Check if given value was set by TWS to something vaguely "positive"
271
+ def filled? value
272
+ # puts "filled: #{value.class} --> #{value.to_s}"
273
+ case value
274
+ when String
275
+ (!value.empty?)# && (value != :none) && (value !='None')
276
+ when Float, Integer, BigDecimal
277
+ value > 0
278
+ else
279
+ !!value # to_bool
280
+ end
281
+ end
282
+
283
+ def to_human
284
+ "<OpenOrder: #{contract.to_human} #{order.to_human}>"
285
+ end
286
+
287
+ end # class OpenOrder
288
+ end # module Incoming
289
+ end # module Messages
290
+ end # module IB
@@ -0,0 +1,85 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ # :status - Displays the order status. Possible values include:
6
+ # - PendingSubmit - indicates that you have transmitted the order, but
7
+ # have not yet received confirmation that it has been accepted by the
8
+ # order destination. NOTE: This order status is NOT sent back by TWS
9
+ # and should be explicitly set by YOU when an order is submitted.
10
+ # - PendingCancel - indicates that you have sent a request to cancel
11
+ # the order but have not yet received cancel confirmation from the
12
+ # order destination. At this point, your order cancel is not confirmed.
13
+ # You may still receive an execution while your cancellation request
14
+ # is pending. NOTE: This order status is not sent back by TWS and
15
+ # should be explicitly set by YOU when an order is canceled.
16
+ # - PreSubmitted - indicates that a simulated order type has been
17
+ # accepted by the IB system and that this order has yet to be elected.
18
+ # The order is held in the IB system until the election criteria are
19
+ # met. At that time the order is transmitted to the order destination
20
+ # as specified.
21
+ # - Submitted - indicates that your order has been accepted at the order
22
+ # destination and is working.
23
+ # - Cancelled - indicates that the balance of your order has been
24
+ # confirmed canceled by the IB system. This could occur unexpectedly
25
+ # when IB or the destination has rejected your order.
26
+ # - ApiCancelled - canceled via API
27
+ # - Filled - indicates that the order has been completely filled.
28
+ # - Inactive - indicates that the order has been accepted by the system
29
+ # (simulated orders) or an exchange (native orders) but that currently
30
+ # the order is inactive due to system, exchange or other issues.
31
+ # :why_held - This property contains the comma-separated list of reasons for
32
+ # order to be held. For example, when TWS is trying to locate shares for
33
+ # a short sell, the value used to indicate this is 'locate'.
34
+ # As of Api 9.72, no version is given anymore
35
+ #
36
+ OrderStatus = def_message [3, 0],
37
+ [:order_state, :local_id, :int],
38
+ [:order_state, :status, :string],
39
+ [:order_state, :filled, :decimal],
40
+ [:order_state, :remaining, :decimal],
41
+ [:order_state, :average_fill_price, :decimal],
42
+ [:order_state, :perm_id, :int],
43
+ [:order_state, :parent_id, :int],
44
+ [:order_state, :last_fill_price, :decimal],
45
+ [:order_state, :client_id, :int],
46
+ [:order_state, :why_held, :string],
47
+ [:order_state, :market_cap_price, :decimal]
48
+ class OrderStatus
49
+
50
+
51
+ def order_state
52
+ @order_state ||= IB::OrderState.new @data[:order_state]
53
+ end
54
+
55
+ # Accessors to make OpenOrder and OrderStatus messages API-compatible
56
+ def client_id
57
+ order_state.client_id
58
+ end
59
+
60
+ def parent_id
61
+ order_state.parent_id
62
+ end
63
+
64
+ def perm_id
65
+ order_state.perm_id
66
+ end
67
+
68
+ def local_id
69
+ order_state.local_id
70
+ end
71
+
72
+ alias order_id local_id
73
+
74
+ def status
75
+ order_state.status
76
+ end
77
+
78
+ def to_human
79
+ order_state.to_human
80
+ end
81
+
82
+ end # class OrderStatus
83
+ end # module Incoming
84
+ end # module Messages
85
+ end # module IB
@@ -0,0 +1,47 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+
6
+ PortfolioValue = def_message [7, 8], ContractMessage,
7
+ [:contract, :contract], # read standard-contract
8
+ [:portfolio_value, :position, :decimal],
9
+ [:portfolio_value,:market_price, :decimal],
10
+ [:portfolio_value,:market_value, :decimal],
11
+ [:portfolio_value,:average_cost, :decimal],
12
+ [:portfolio_value,:unrealized_pnl, :decimal], # May be nil!
13
+ [:portfolio_value,:realized_pnl, :decimal], # May be nil!
14
+ [:account, :string]
15
+
16
+
17
+ class PortfolioValue
18
+
19
+
20
+ def to_human
21
+ # "<PortfolioValue: #{contract.to_human} #{portfolio_value}>"
22
+ portfolio_value.to_human
23
+ end
24
+ def portfolio_value
25
+ unless @portfolio_value.present?
26
+ @portfolio_value = IB::PortfolioValue.new @data[:portfolio_value]
27
+ @portfolio_value.contract = contract
28
+ @portfolio_value.account = account
29
+ end
30
+ @portfolio_value # return_value
31
+ end
32
+
33
+ def account_name
34
+ @account_name = @data[:account]
35
+ end
36
+
37
+ # alias :to_human :portfolio_value
38
+ end # PortfolioValue
39
+
40
+
41
+
42
+
43
+
44
+
45
+ end # module Incoming
46
+ end # module Messages
47
+ end # module IB
@@ -0,0 +1,21 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ PositionData =
6
+ def_message( [61,3] , ContractMessage,
7
+ [:account, :string],
8
+ [:contract, :contract], # read standard-contract
9
+ # [ con_id, symbol,. sec_type, expiry, strike, right, multiplier,
10
+ # primary_exchange, currency, local_symbol, trading_class ]
11
+ [:position, :decimal], # changed from int after Server Vers. MIN_SERVER_VER_FRACTIONAL_POSITIONS
12
+ [:price, :decimal]
13
+ ) do
14
+ # def to_human
15
+ "<PositionValue: #{account} -> #{contract.to_human} ( Amount #{position}) : Market-Price #{price} >"
16
+ end
17
+
18
+
19
+ end # module Incoming
20
+ end # module Messages
21
+ end # module IB
@@ -0,0 +1,15 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+
6
+ PositionsMulti = def_message( 71, ContractMessage,
7
+ [ :request_id, :int ],
8
+ [ :account, :string ],
9
+ [:contract, :contract], # read standard-contract
10
+ [ :position, :decimal], # changed from int after Server Vers. MIN_SERVER_VER_FRACTIONAL_POSITIONS
11
+ [ :average_cost, :decimal],
12
+ [ :model_code, :string ])
13
+ end # module Incoming
14
+ end # module Messages
15
+ end # module IB
@@ -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,30 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ extend Messages # def_message macros
6
+
7
+
8
+ # Receives previously requested FA configuration information from TWS.
9
+ ReceiveFA =
10
+ def_message 16, [:type, :int], # type of Financial Advisor configuration data
11
+ # being received from TWS. Valid values include:
12
+ # 1 = GROUPS, 2 = PROFILE, 3 = ACCOUNT ALIASES
13
+ [:xml, :xml] # XML string with requested FA configuration information.
14
+
15
+ class ReceiveFA
16
+ def accounts
17
+ if( a= xml[:ListOfAccountAliases][:AccountAlias]).is_a? Array
18
+ a.map{|x| Account.new x }
19
+ elsif a.is_a? Hash ## only one account (soley financial advisor)
20
+ [ Account.new( a ) ]
21
+ end
22
+ end
23
+
24
+ def to_human
25
+ "<FA: #{accounts.map(&:to_human).join(" - ")}>"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -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 IB::Support # 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,77 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+ extend Messages # def_message macros
5
+
6
+ TickByTick = def_message [99, 0], [:ticker_id, :int ],
7
+ [ :tick_type, :int],
8
+ [ :time, :int_date ]
9
+
10
+ ## error messages: (10189) "Failed to request tick-by-tick data:Historical data request pacing violation"
11
+ #
12
+ class TickByTick
13
+ using IB::Support # extended Array-Class from abstract_message
14
+ def resolve_mask
15
+ @data[:mask].present? ? [ @data[:mask] & 1 , @data[:mask] & 2 ] : []
16
+ end
17
+
18
+ def load
19
+ super
20
+ case @data[:tick_type ]
21
+ when 0
22
+ # do nothing
23
+ when 1, 2 # Last, AllLast
24
+ load_map [ :price, :decimal ] ,
25
+ [ :size, :int ] ,
26
+ [ :mask, :int ] ,
27
+ [ :exchange, :string ],
28
+ [ :special_conditions, :string ]
29
+ when 3 # bid/ask
30
+ load_map [ :bid_price, :decimal ],
31
+ [ :ask_price, :decimal],
32
+ [ :bid_size, :int ],
33
+ [ :ask_size, :int] ,
34
+ [ :mask, :int ]
35
+ when 4
36
+ load_map [ :mid_point, :decimal ]
37
+ end
38
+
39
+ @out_labels = case @data[ :tick_tpye ]
40
+ when 1, 2
41
+ [ "PastLimit", "Unreported" ]
42
+ when 3
43
+ [ "BitPastLow", "BidPastHigh" ]
44
+ else
45
+ []
46
+ end
47
+ end
48
+ def to_human
49
+ "< TickByTick:" + case @data[ :tick_type ]
50
+ when 1,2
51
+ "(Last) #{size} @ #{price} [#{exchange}] "
52
+ when 3
53
+ "(Bid/Ask) #{bid_size} @ #{bid_price} / #{ask_size } @ #{ask_price} "
54
+ when 4
55
+ "(Midpoint) #{mid_point } "
56
+ else
57
+ ""
58
+ end + @out_labels.zip(resolve_mask).join( "/" )
59
+ end
60
+
61
+ [:price, :size, :mask, :exchange, :specialConditions, :bid_price, :ask_price, :bid_size, :ask_size, :mid_point].each do |name|
62
+ define_method name do
63
+ @data[name]
64
+ end
65
+ end
66
+ # def method_missing method, *args
67
+ # if @data.keys.include? method
68
+ # @data[method]
69
+ # else
70
+ # error "method #{method} not known"
71
+ # end
72
+ # end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,18 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+ extend Messages # def_message macros
5
+
6
+
7
+ TickEFP = def_message [47, 6], AbstractTick,
8
+ [:ticker_id, :int],
9
+ [:tick_type, :int],
10
+ [:basis_points, :decimal],
11
+ [:formatted_basis_points, :string],
12
+ [:implied_futures_price, :decimal],
13
+ [:hold_days, :int],
14
+ [:dividend_impact, :decimal],
15
+ [:dividends_to_expiry, :decimal]
16
+ end
17
+ end
18
+ end