ib-api 972.0

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 (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