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,44 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ MarketDepth =
6
+ def_message 12, [:request_id, :int],
7
+ [:position, :int], # The row Id of this market depth entry.
8
+ [:operation, :int], # How it should be applied to the market depth:
9
+ # 0 = insert this new order into the row identified by :position
10
+ # 1 = update the existing order in the row identified by :position
11
+ # 2 = delete the existing order at the row identified by :position
12
+ [:side, :int], # side of the book: 0 = ask, 1 = bid
13
+ [:price, :decimal],
14
+ [:size, :int]
15
+
16
+ class MarketDepth
17
+ def side
18
+ @data[:side] == 0 ? :ask : :bid
19
+ end
20
+
21
+ def operation
22
+ @data[:operation] == 0 ? :insert : @data[:operation] == 1 ? :update : :delete
23
+ end
24
+
25
+ def to_human
26
+ "<#{self.message_type}: #{operation} #{side} @ "+
27
+ "#{position} = #{price} x #{size}>"
28
+ end
29
+ end
30
+
31
+ MarketDepthL2 =
32
+ def_message 13, MarketDepth, # Fields descriptions - see above
33
+ [:request_id, :int],
34
+ [:position, :int],
35
+ [:market_maker, :string], # The exchange hosting this order.
36
+ [:operation, :int],
37
+ [:side, :int],
38
+ [:price, :decimal],
39
+ [:size, :int]
40
+
41
+
42
+ end # module Incoming
43
+ end # module Messages
44
+ end # module IB
@@ -0,0 +1,18 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ # This message is always sent by TWS automatically at connect.
6
+ # The IB::Connection class subscribes to it automatically and stores
7
+ # the order id in its @next_local_id attribute.
8
+ NextValidID = NextValidId = def_message(9, [:local_id, :int])
9
+
10
+ class NextValidId
11
+
12
+ # Legacy accessor
13
+ alias order_id local_id
14
+
15
+ end # class NextValidId
16
+ end # module Incoming
17
+ end # module Messages
18
+ end # module IB
@@ -0,0 +1,277 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+ using IBSupport
5
+ # OpenOrder is the longest message with complex processing logics
6
+ OpenOrder =
7
+ def_message [5, 34], # 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], # (@socket.read_int == 1)
28
+ [:order, :hidden, :boolean], # (@socket.read_int == 1)
29
+ [:order, :discretionary_amount, :decimal],
30
+ [:order, :good_after_time, :string],
31
+ [:shares_allocation, :string], # deprecated! field
32
+
33
+ [:order, :fa_group, :string],
34
+ [:order, :fa_method, :string],
35
+ [:order, :fa_percentage, :string],
36
+ [:order, :fa_profile, :string],
37
+ [:order, :model_code, :string],
38
+ [:order, :good_till_date, :string],
39
+ [:order, :rule_80a, :string],
40
+ [:order, :percent_offset, :decimal],
41
+ [:order, :settling_firm, :string],
42
+ [:order, :short_sale_slot, :int],
43
+ [:order, :designated_location, :string],
44
+ [:order, :exempt_code, :int],
45
+ [:order, :auction_strategy, :int],
46
+ [:order, :starting_price, :decimal],
47
+ [:order, :stock_ref_price, :decimal],
48
+ [:order, :delta, :decimal],
49
+ [:order, :stock_range_lower, :decimal],
50
+ [:order, :stock_range_upper, :decimal],
51
+ [:order, :display_size, :int],
52
+ #@order.rth_only = @socket.read_boolean
53
+ [:order, :block_order, :boolean],
54
+ [:order, :sweep_to_fill, :boolean],
55
+ [:order, :all_or_none, :boolean],
56
+ [:order, :min_quantity, :int],
57
+ [:order, :oca_type, :int],
58
+ [:order, :etrade_only, :boolean],
59
+ [:order, :firm_quote_only, :boolean],
60
+ [:order, :nbbo_price_cap, :decimal],
61
+ [:order, :parent_id, :int],
62
+ [:order, :trigger_method, :int],
63
+ [:order, :volatility, :decimal],
64
+ [:order, :volatility_type, :int],
65
+ [:order, :delta_neutral_order_type, :string],
66
+ [:order, :delta_neutral_aux_price, :decimal]
67
+
68
+ class OpenOrder
69
+
70
+ # Accessors to make OpenOrder API-compatible with OrderStatus message
71
+
72
+ def client_id
73
+ order.client_id
74
+ end
75
+
76
+ def parent_id
77
+ order.parent_id
78
+ end
79
+
80
+ def perm_id
81
+ order.perm_id
82
+ end
83
+
84
+ def local_id
85
+ order.local_id
86
+ end
87
+
88
+ alias order_id local_id
89
+
90
+ def status
91
+ order.status
92
+ end
93
+
94
+ def conditions
95
+ order.conditions
96
+ end
97
+
98
+ # Object accessors
99
+
100
+ def order
101
+ @order ||= IB::Order.new @data[:order].merge(:order_state => order_state)
102
+ end
103
+
104
+ def order_state
105
+ @order_state ||= IB::OrderState.new(
106
+ @data[:order_state].merge(
107
+ :local_id => @data[:order][:local_id],
108
+ :perm_id => @data[:order][:perm_id],
109
+ :parent_id => @data[:order][:parent_id],
110
+ :client_id => @data[:order][:client_id]))
111
+ end
112
+
113
+ def contract
114
+ @contract ||= IB::Contract.build(
115
+ @data[:contract].merge(:underlying => underlying)
116
+ )
117
+ end
118
+
119
+ def underlying
120
+ @underlying = @data[:underlying_present] ? IB::Underlying.new(@data[:underlying]) : nil
121
+ end
122
+
123
+ alias under_comp underlying
124
+
125
+ def load
126
+ super
127
+
128
+ # load_map [proc { | | (@data[:order][:delta_neutral_order_type] != 'None') },
129
+ load_map [proc { | | filled?(@data[:order][:delta_neutral_order_type]) }, # todo Testcase!
130
+ # As of client v.52, we may receive delta... params in openOrder
131
+ [:order, :delta_neutral_con_id, :int],
132
+ [:order, :delta_neutral_settling_firm, :string],
133
+ [:order, :delta_neutral_clearing_account, :string],
134
+ [:order, :delta_neutral_clearing_intent, :string],
135
+ [:order, :delta_neutral_open_close, :string],
136
+ [:order, :delta_neutral_short_sale, :bool],
137
+ [:order, :delta_neutral_short_sale_slot, :int],
138
+ [:order, :delta_neutral_designated_location, :string] ], # end proc
139
+ [:order, :continuous_update, :int],
140
+ [:order, :reference_price_type, :int],
141
+ [:order, :trail_stop_price, :decimal], # not trail-orders. see below
142
+ [:order, :trailing_percent, :decimal],
143
+ [:order, :basis_points, :decimal],
144
+ [:order, :basis_points_type, :int],
145
+
146
+ [:contract, :legs_description, :string],
147
+
148
+ # As of client v.55, we receive in OpenOrder for Combos:
149
+ # Contract.orderComboLegs Array
150
+ # Order.leg_prices Array
151
+ [:contract, :combo_legs, :array, proc do |_|
152
+ IB::ComboLeg.new :con_id => @buffer.read_int,
153
+ :ratio => @buffer.read_int,
154
+ :action => @buffer.read_string,
155
+ :exchange => @buffer.read_string,
156
+ :open_close => @buffer.read_int,
157
+ :short_sale_slot => @buffer.read_int,
158
+ :designated_location => @buffer.read_string,
159
+ :exempt_code => @buffer.read_int
160
+ end],
161
+ [:order, :leg_prices, :array, proc { |_| buffer.read_decimal }], # needs testing
162
+ [:order, :combo_params, :hash ],
163
+ #, proc do |_|
164
+ # { tag: buffer.read_string, value: buffer.read_string } # needs testing
165
+ # end],
166
+
167
+ [:order, :scale_init_level_size, :int],
168
+ [:order, :scale_subs_level_size, :int],
169
+
170
+ [:order, :scale_price_increment, :decimal],
171
+ [proc { | | filled?(@data[:order][:scale_price_increment]) },
172
+ # As of client v.54, we may receive scale order fields
173
+ [:order, :scale_price_adjust_value, :decimal],
174
+ [:order, :scale_price_adjust_interval, :int],
175
+ [:order, :scale_profit_offset, :decimal],
176
+ [:order, :scale_auto_reset, :boolean],
177
+ [:order, :scale_init_position, :int],
178
+ [:order, :scale_init_fill_qty, :decimal],
179
+ [:order, :scale_random_percent, :boolean]
180
+ ],
181
+
182
+ [:order, :hedge_type, :string],
183
+ [proc { | | filled?(@data[:order][:hedge_type]) },
184
+ # As of client v.49/50, we can receive hedgeType, hedgeParam
185
+ [:order, :hedge_param, :string]
186
+ ],
187
+
188
+ [:order, :opt_out_smart_routing, :boolean],
189
+ [:order, :clearing_account, :string],
190
+ [:order, :clearing_intent, :string],
191
+ [:order, :not_held, :boolean],
192
+
193
+ [:underlying_present, :boolean],
194
+ [proc { | | filled?(@data[:underlying_present]) },
195
+ [:underlying, :con_id, :int],
196
+ [:underlying, :delta, :decimal],
197
+ [:underlying, :price, :decimal]
198
+ ],
199
+
200
+ # TODO: Test Order with algo_params, scale and legs!
201
+ [:order, :algo_strategy, :string],
202
+ [proc { | | filled?(@data[:order][:algo_strategy]) },
203
+ [:order, :algo_params, :hash]
204
+ ],
205
+ [:order, :solicided, :boolean],
206
+ [:order, :what_if, :boolean],
207
+ [:order_state, :status, :string],
208
+ # IB uses weird String with Java Double.MAX_VALUE to indicate no value here
209
+ [:order_state, :init_margin, :decimal], # :string],
210
+ [:order_state, :maint_margin, :decimal], # :string],
211
+ [:order_state, :equity_with_loan, :decimal], # :string],
212
+ [:order_state, :commission, :decimal], # May be nil!
213
+ [:order_state, :min_commission, :decimal], # May be nil!
214
+ [:order_state, :max_commission, :decimal], # May be nil!
215
+ [:order_state, :commission_currency, :string],
216
+ [:order_state, :warning_text, :string],
217
+
218
+
219
+ [:order, :random_size, :boolean],
220
+ [:order, :random_price, :boolean],
221
+
222
+ ## todo: ordertype = PEG BENCH -- -> test!
223
+ [proc{ @data[:order][:order_type] == 'PEG BENCH' },
224
+ [:order, :reference_contract_id, :int ],
225
+ [:order, :is_pegged_change_amount_decrease, :bool ],
226
+ [:order, :pegged_change_amount, :decimal ],
227
+ [:order, :reference_change_amount, :decimal ],
228
+ [:order, :reference_exchange_id, :string ]
229
+ ],
230
+ [:order , :conditions, :array, proc { IB::OrderCondition.make_from( @buffer ) } ],
231
+ [proc { !@data[:order][:conditions].blank? },
232
+ [:order, :conditions_ignore_rth, :bool],
233
+ [:order, :conditions_cancel_order,:bool]
234
+ ],
235
+ [:order, :adjusted_order_type, :string],
236
+ [:order, :trigger_price, :decimal],
237
+ [:order, :trail_stop_price, :decimal], # cpp -source: Traillimit orders
238
+ [:order, :adjusted_stop_limit_price, :decimal],
239
+ [:order, :adjusted_trailing_amount, :decimal],
240
+ [:order, :adjustable_trailing_unit, :int],
241
+
242
+ [:order, :soft_dollar_tier_name, :string_not_null],
243
+ [:order, :soft_dollar_tier_value, :string_not_null],
244
+ [:order, :soft_dollar_tier_display_name, :string_not_null],
245
+ [:order, :cash_qty, :decimal],
246
+ [:order, :mifid_2_decision_maker, :string_not_null ], ## correct appearance of fields below
247
+ [:order, :mifid_2_decision_algo, :string_not_null ], ## is not tested yet
248
+ [:order, :mifid_2_execution_maker, :string ],
249
+ [:order, :mifid_2_execution_algo, :string_not_null ],
250
+ [:order, :dont_use_auto_price_for_hedge, :string ],
251
+ [:order, :is_O_ms_container, :bool ],
252
+ [ :order, :discretionary_up_to_limit_price, :decimal ]
253
+
254
+
255
+ end
256
+
257
+ # Check if given value was set by TWS to something vaguely "positive"
258
+ def filled? value
259
+ # puts "filled: #{value.class} --> #{value.to_s}"
260
+ case value
261
+ when String
262
+ (!value.empty?)# && (value != :none) && (value !='None')
263
+ when Float, Integer, BigDecimal
264
+ value > 0
265
+ else
266
+ !!value # to_bool
267
+ end
268
+ end
269
+
270
+ def to_human
271
+ "<OpenOrder: #{contract.to_human} #{order.to_human}>"
272
+ end
273
+
274
+ end # class OpenOrder
275
+ end # module Incoming
276
+ end # module Messages
277
+ 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,78 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ class ContractMessage < AbstractMessage
6
+ def contract
7
+ @contract = IB::Contract.build @data[:contract]
8
+ end
9
+ end
10
+
11
+ PortfolioValue = def_message [7, 8], ContractMessage,
12
+ [:contract, :contract], # read standard-contract
13
+ [:portfolio_value, :position, :decimal],
14
+ [:portfolio_value,:market_price, :decimal],
15
+ [:portfolio_value,:market_value, :decimal],
16
+ [:portfolio_value,:average_cost, :decimal],
17
+ [:portfolio_value,:unrealized_pnl, :decimal], # May be nil!
18
+ [:portfolio_value,:realized_pnl, :decimal], # May be nil!
19
+ [:account, :string]
20
+
21
+
22
+ class PortfolioValue
23
+
24
+
25
+ def to_human
26
+ # "<PortfolioValue: #{contract.to_human} #{portfolio_value}>"
27
+ portfolio_value.to_human
28
+ end
29
+
30
+ def portfolio_value
31
+ unless @portfolio_value.present?
32
+ @portfolio_value = IB::PortfolioValue.new @data[:portfolio_value]
33
+ @portfolio_value.contract = contract
34
+ @portfolio_value.account = account
35
+ end
36
+ @portfolio_value # return_value
37
+ end
38
+
39
+ def account_name
40
+ @account_name = @data[:account]
41
+ end
42
+
43
+ # alias :to_human :portfolio_value
44
+ end # PortfolioValue
45
+
46
+
47
+
48
+ PositionData =
49
+ def_message( [61,3] , ContractMessage,
50
+ [:account, :string],
51
+ [:contract, :contract], # read standard-contract
52
+ # [ con_id, symbol,. sec_type, expiry, strike, right, multiplier,
53
+ # primary_exchange, currency, local_symbol, trading_class ]
54
+ [:position, :decimal], # changed from int after Server Vers. MIN_SERVER_VER_FRACTIONAL_POSITIONS
55
+ [:price, :decimal]
56
+ ) do
57
+ # def to_human
58
+ "<PositionValue: #{account} -> #{contract.to_human} ( Amount #{position}) : Market-Price #{price} >"
59
+ end
60
+
61
+ PositionDataEnd = def_message( 62 )
62
+ PositionsMulti = def_message( 71, ContractMessage,
63
+ [ :request_id, :int ],
64
+ [ :account, :string ],
65
+ [:contract, :contract], # read standard-contract
66
+ [ :position, :decimal], # changed from int after Server Vers. MIN_SERVER_VER_FRACTIONAL_POSITIONS
67
+ [ :average_cost, :decimal],
68
+ [ :model_code, :string ])
69
+
70
+ PositionsMultiEnd = def_message 72
71
+
72
+
73
+
74
+
75
+
76
+ end # module Incoming
77
+ end # module Messages
78
+ end # module IB