ib-ruby 0.7.4 → 0.7.6

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 (93) hide show
  1. data/.gitignore +3 -0
  2. data/HISTORY +8 -0
  3. data/README.md +2 -2
  4. data/Rakefile +15 -0
  5. data/TODO +7 -2
  6. data/VERSION +1 -1
  7. data/bin/account_info +1 -1
  8. data/bin/cancel_orders +1 -1
  9. data/bin/contract_details +1 -1
  10. data/bin/depth_of_market +1 -1
  11. data/bin/fa_accounts +1 -1
  12. data/bin/fundamental_data +42 -0
  13. data/bin/historic_data +1 -1
  14. data/bin/historic_data_cli +1 -1
  15. data/bin/list_orders +1 -2
  16. data/bin/market_data +1 -1
  17. data/bin/option_data +1 -1
  18. data/bin/place_combo_order +1 -1
  19. data/bin/place_order +1 -1
  20. data/bin/template +1 -4
  21. data/bin/tick_data +2 -2
  22. data/bin/time_and_sales +1 -1
  23. data/lib/ib-ruby.rb +4 -0
  24. data/lib/ib-ruby/connection.rb +50 -34
  25. data/lib/ib-ruby/constants.rb +232 -37
  26. data/lib/ib-ruby/db.rb +25 -0
  27. data/lib/ib-ruby/extensions.rb +51 -1
  28. data/lib/ib-ruby/messages/abstract_message.rb +0 -8
  29. data/lib/ib-ruby/messages/incoming.rb +18 -493
  30. data/lib/ib-ruby/messages/incoming/abstract_message.rb +100 -0
  31. data/lib/ib-ruby/messages/incoming/alert.rb +34 -0
  32. data/lib/ib-ruby/messages/incoming/contract_data.rb +82 -0
  33. data/lib/ib-ruby/messages/incoming/delta_neutral_validation.rb +20 -0
  34. data/lib/ib-ruby/messages/incoming/execution_data.rb +59 -0
  35. data/lib/ib-ruby/messages/incoming/historical_data.rb +55 -0
  36. data/lib/ib-ruby/messages/incoming/market_depths.rb +44 -0
  37. data/lib/ib-ruby/messages/incoming/open_order.rb +32 -16
  38. data/lib/ib-ruby/messages/incoming/order_status.rb +67 -0
  39. data/lib/ib-ruby/messages/incoming/portfolio_value.rb +39 -0
  40. data/lib/ib-ruby/messages/incoming/real_time_bar.rb +32 -0
  41. data/lib/ib-ruby/messages/incoming/scanner_data.rb +49 -0
  42. data/lib/ib-ruby/messages/outgoing.rb +25 -223
  43. data/lib/ib-ruby/messages/outgoing/abstract_message.rb +61 -0
  44. data/lib/ib-ruby/messages/outgoing/bar_requests.rb +149 -0
  45. data/lib/ib-ruby/messages/outgoing/place_order.rb +24 -0
  46. data/lib/ib-ruby/models.rb +4 -0
  47. data/lib/ib-ruby/models/bar.rb +31 -14
  48. data/lib/ib-ruby/models/combo_leg.rb +48 -23
  49. data/lib/ib-ruby/models/contracts.rb +2 -2
  50. data/lib/ib-ruby/models/contracts/bag.rb +11 -7
  51. data/lib/ib-ruby/models/contracts/contract.rb +90 -66
  52. data/lib/ib-ruby/models/contracts/option.rb +16 -7
  53. data/lib/ib-ruby/models/execution.rb +34 -18
  54. data/lib/ib-ruby/models/model.rb +15 -7
  55. data/lib/ib-ruby/models/model_properties.rb +101 -44
  56. data/lib/ib-ruby/models/order.rb +176 -187
  57. data/lib/ib-ruby/models/order_state.rb +99 -0
  58. data/lib/ib-ruby/symbols/forex.rb +10 -10
  59. data/lib/ib-ruby/symbols/futures.rb +6 -6
  60. data/lib/ib-ruby/symbols/stocks.rb +3 -3
  61. data/spec/account_helper.rb +4 -5
  62. data/spec/combo_helper.rb +4 -4
  63. data/spec/db.rb +18 -0
  64. data/spec/ib-ruby/messages/{incoming_spec.rb → incoming/alert_spec.rb} +1 -0
  65. data/spec/ib-ruby/messages/incoming/open_order_spec.rb +100 -0
  66. data/spec/ib-ruby/messages/incoming/order_status_spec.rb +74 -0
  67. data/spec/ib-ruby/messages/{outgoing_spec.rb → outgoing/account_data_spec.rb} +0 -0
  68. data/spec/ib-ruby/messages/outgoing/market_data_type_spec.rb +44 -0
  69. data/spec/ib-ruby/models/bag_spec.rb +97 -0
  70. data/spec/ib-ruby/models/bar_spec.rb +45 -0
  71. data/spec/ib-ruby/models/combo_leg_spec.rb +56 -40
  72. data/spec/ib-ruby/models/contract_spec.rb +134 -170
  73. data/spec/ib-ruby/models/execution_spec.rb +35 -50
  74. data/spec/ib-ruby/models/option_spec.rb +127 -0
  75. data/spec/ib-ruby/models/order_spec.rb +89 -68
  76. data/spec/ib-ruby/models/order_state_spec.rb +55 -0
  77. data/spec/integration/contract_info_spec.rb +4 -6
  78. data/spec/integration/fundamental_data_spec.rb +41 -0
  79. data/spec/integration/historic_data_spec.rb +4 -4
  80. data/spec/integration/market_data_spec.rb +1 -3
  81. data/spec/integration/orders/attached_spec.rb +8 -10
  82. data/spec/integration/orders/combo_spec.rb +2 -2
  83. data/spec/integration/orders/execution_spec.rb +0 -1
  84. data/spec/integration/orders/placement_spec.rb +1 -3
  85. data/spec/integration/orders/valid_ids_spec.rb +1 -2
  86. data/spec/message_helper.rb +1 -1
  87. data/spec/model_helper.rb +211 -0
  88. data/spec/order_helper.rb +44 -37
  89. data/spec/spec_helper.rb +36 -23
  90. data/spec/v.rb +7 -0
  91. data/tasks/doc.rake +1 -1
  92. metadata +116 -12
  93. data/spec/integration/orders/open_order +0 -98
@@ -0,0 +1,67 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ # :status - String: 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
+ OrderStatus = def_message [3, 6],
35
+ [:order_state, :order_id, :int],
36
+ [:order_state, :status, :string],
37
+ [:order_state, :filled, :int],
38
+ [:order_state, :remaining, :int],
39
+ [:order_state, :average_fill_price, :decimal],
40
+ [:order_state, :perm_id, :int],
41
+ [:order_state, :parent_id, :int],
42
+ [:order_state, :last_fill_price, :decimal],
43
+ [:order_state, :client_id, :int],
44
+ [:order_state, :why_held, :string]
45
+ class OrderStatus
46
+
47
+ def order_state
48
+ @order_state ||= IB::OrderState.new @data[:order_state]
49
+ end
50
+
51
+ # Accessors to make OpenOrder and OrderStatus messages API-compatible
52
+ def order_id
53
+ order_state.order_id
54
+ end
55
+
56
+ def status
57
+ order_state.status
58
+ end
59
+
60
+ def to_human
61
+ "<OrderStatus: #{order_state}>"
62
+ end
63
+
64
+ end # class OrderStatus
65
+ end # module Incoming
66
+ end # module Messages
67
+ end # module IB
@@ -0,0 +1,39 @@
1
+ module IB
2
+ module Messages
3
+ module Incoming
4
+
5
+ PortfolioValue = def_message [7, 7],
6
+ [:contract, :con_id, :int],
7
+ [:contract, :symbol, :string],
8
+ [:contract, :sec_type, :string],
9
+ [:contract, :expiry, :string],
10
+ [:contract, :strike, :decimal],
11
+ [:contract, :right, :string],
12
+ [:contract, :multiplier, :string],
13
+ [:contract, :primary_exchange, :string],
14
+ [:contract, :currency, :string],
15
+ [:contract, :local_symbol, :string],
16
+ [:position, :int],
17
+ [:market_price, :decimal],
18
+ [:market_value, :decimal],
19
+ [:average_cost, :decimal],
20
+ [:unrealized_pnl, :decimal_max], # May be nil!
21
+ [:realized_pnl, :decimal_max], # May be nil!
22
+ [:account_name, :string]
23
+ class PortfolioValue
24
+
25
+ def contract
26
+ @contract = IB::Contract.build @data[:contract]
27
+ end
28
+
29
+ def to_human
30
+ "<PortfolioValue: #{contract.to_human} (#{position}): Market #{market_price}" +
31
+ " price #{market_value} value; PnL: #{unrealized_pnl} unrealized," +
32
+ " #{realized_pnl} realized; account #{account_name}>"
33
+ end
34
+ end # PortfolioValue
35
+
36
+
37
+ end # module Incoming
38
+ end # module Messages
39
+ 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,
11
+ [:request_id, :int],
12
+ [:bar, :time, :int],
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} #{time}, #{bar}>"
27
+ end
28
+ end # RealTimeBar
29
+
30
+ end # module Incoming
31
+ end # module Messages
32
+ end # module IB
@@ -0,0 +1,49 @@
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
+
22
+ def load
23
+ super
24
+
25
+ @results = Array.new(@data[:count]) do |_|
26
+ {:rank => socket.read_int,
27
+ :contract => Contract.build(:con_id => socket.read_int,
28
+ :symbol => socket.read_str,
29
+ :sec_type => socket.read_str,
30
+ :expiry => socket.read_str,
31
+ :strike => socket.read_decimal,
32
+ :right => socket.read_str,
33
+ :exchange => socket.read_str,
34
+ :currency => socket.read_str,
35
+ :local_symbol => socket.read_str,
36
+ :market_name => socket.read_str,
37
+ :trading_class => socket.read_str),
38
+ :distance => socket.read_str,
39
+ :benchmark => socket.read_str,
40
+ :projection => socket.read_str,
41
+ :legs => socket.read_str,
42
+ }
43
+ end
44
+ end
45
+ end # ScannerData
46
+
47
+ end # module Incoming
48
+ end # module Messages
49
+ end # module IB
@@ -1,4 +1,4 @@
1
- require 'ib-ruby/messages/abstract_message'
1
+ require 'ib-ruby/messages/outgoing/abstract_message'
2
2
 
3
3
  # TODO: Don't instantiate messages, use their classes as just namespace for .encode/decode
4
4
 
@@ -9,57 +9,6 @@ module IB
9
9
  module Outgoing
10
10
  extend Messages # def_message macros
11
11
 
12
- # Container for specific message classes, keyed by their message_ids
13
- Classes = {}
14
-
15
- class AbstractMessage < IB::Messages::AbstractMessage
16
-
17
- def initialize data={}
18
- @data = data
19
- @created_at = Time.now
20
- end
21
-
22
- # This causes the message to send itself over the server socket in server[:socket].
23
- # "server" is the @server instance variable from the IB object.
24
- # You can also use this to e.g. get the server version number.
25
- #
26
- # Subclasses can either override this method for precise control over how
27
- # stuff gets sent to the server, or else define a method encode() that returns
28
- # an Array of elements that ought to be sent to the server by calling to_s on
29
- # each one and postpending a '\0'.
30
- #
31
- def send_to server
32
- self.encode(server).flatten.each do |datum|
33
- server[:socket].write_data datum
34
- end
35
- end
36
-
37
- # At minimum, Outgoing message contains message_id and version.
38
- # Most messages also contain (ticker, request or order) :id.
39
- # Then, content of @data Hash is encoded per instructions in data_map.
40
- def encode server
41
- [self.class.message_id,
42
- self.class.version,
43
- @data[:id] || @data[:ticker_id] || @data[:request_id]|| @data[:order_id] || [],
44
- self.class.data_map.map do |(field, default_method, args)|
45
- case
46
- when default_method.nil?
47
- @data[field]
48
-
49
- when default_method.is_a?(Symbol) # method name with args
50
- @data[field].send default_method, *args
51
-
52
- when default_method.respond_to?(:call) # callable with args
53
- default_method.call @data[field], *args
54
-
55
- else # default
56
- @data[field].nil? ? default_method : @data[field] # may be false still
57
- end
58
- end
59
- ].flatten
60
- end
61
- end # AbstractMessage
62
-
63
12
  ### Defining (short) Outgoing Message classes for IB:
64
13
 
65
14
  ## Empty messages (no data)
@@ -118,10 +67,6 @@ module IB
118
67
  # data = { :fa_data_type => int, :xml => String }
119
68
  ReplaceFA = def_message 19, :fa_data_type, :xml
120
69
  # data = { :market_data_type => int }
121
- # The API can now receive frozen market data from Trader Workstation. Frozen
122
- # market data is the last data recorded in our system. Use this method with
123
- # :market_data_type = 1 for real-time streaming, 2 for frozen market data
124
- RequestMarketDataType = def_message 59, :market_data_type
125
70
 
126
71
  # @data = { :subscribe => boolean,
127
72
  # :account_code => Advisor accounts only. Empty ('') for a standard account. }
@@ -174,8 +119,8 @@ module IB
174
119
  # have override set to "yes" the natural action would be
175
120
  # overridden and the out-of-the money option would be
176
121
  # exercised. Values are:
177
- # 0 = do not override
178
- # 1 = override
122
+ # - 0 = do not override
123
+ # - 1 = override
179
124
  ExerciseOptions = def_message(21,
180
125
  [:contract, :serialize_short],
181
126
  :exercise_action,
@@ -214,13 +159,26 @@ module IB
214
159
  end, []],
215
160
  [:snapshot, false])
216
161
 
162
+ # The API can receive frozen market data from Trader Workstation. Frozen market
163
+ # data is the last data recorded in our system. During normal trading hours,
164
+ # the API receives real-time market data. If you use this function, you are
165
+ # telling TWS to automatically switch to frozen market data AFTER the close.
166
+ # Then, before the opening of the next trading day, market data will automatically
167
+ # switch back to real-time market data.
168
+ # :market_data_type = 1 for real-time streaming, 2 for frozen market data
169
+ RequestMarketDataType =
170
+ def_message 59, [:market_data_type,
171
+ lambda { |type| MARKET_DATA_TYPES.invert[type] || type }, []]
172
+
217
173
  # Send this message to receive Reuters global fundamental data. There must be
218
174
  # a subscription to Reuters Fundamental set up in Account Management before
219
175
  # you can receive this data.
220
176
  # data = { :id => int: :request_id,
221
177
  # :contract => Contract,
222
178
  # :report_type => String: one of the following:
223
- # 'Estimates', 'Financial Statements', 'Summary' }
179
+ # 'estimates' - Estimates
180
+ # 'finstat' - Financial statements
181
+ # 'snapshot' - Summary }
224
182
  RequestFundamentalData =
225
183
  def_message(52,
226
184
  [:contract, :serialize, [:primary_exchange]],
@@ -251,12 +209,12 @@ module IB
251
209
  # 'STOCK.HK' - Asian stocks
252
210
  # 'STOCK.EU' - European stocks
253
211
  # :location_code => Legal Values include:
254
- # STK.US - US stocks
255
- # STK.US.MAJOR - US stocks (without pink sheet)
256
- # STK.US.MINOR - US stocks (only pink sheet)
257
- # STK.HK.SEHK - Hong Kong stocks
258
- # STK.HK.ASX - Australian Stocks
259
- # STK.EU - European stocks
212
+ # - STK.US - US stocks
213
+ # - STK.US.MAJOR - US stocks (without pink sheet)
214
+ # - STK.US.MINOR - US stocks (only pink sheet)
215
+ # - STK.HK.SEHK - Hong Kong stocks
216
+ # - STK.HK.ASX - Australian Stocks
217
+ # - STK.EU - European stocks
260
218
  # :scan_code => The type of the scan, such as HIGH_OPT_VOLUME_PUT_CALL_RATIO.
261
219
  # :above_price => double: Only contracts with a price above this value.
262
220
  # :below_price => double: Only contracts with a price below this value.
@@ -310,164 +268,8 @@ module IB
310
268
  :scanner_setting_pairs,
311
269
  :stock_type_filter)
312
270
 
313
- ### Even more complex Outgoing Message classes, overriding #encode method:
314
-
315
-
316
- # Data format is { :id => int: order_id,
317
- # :contract => Contract,
318
- # :order => Order }
319
- PlaceOrder = def_message [3, 31] # 38 Need to set up Classes Hash properly
320
-
321
- class PlaceOrder
322
- def encode server
323
-
324
- # Old server version supports no enhancements
325
- @version = 31 if server[:server_version] <= 60
326
-
327
- [super,
328
- @data[:order].serialize_with(server, @data[:contract])].flatten
329
- end
330
- end # PlaceOrder
331
-
332
- # Messages that request bar data have special processing of @data
333
- class BarRequestMessage < AbstractMessage
334
- # Preprocessor for some data fields
335
- def parse data
336
- data_type = DATA_TYPES[data[:what_to_show]] || data[:what_to_show]
337
- unless DATA_TYPES.values.include?(data_type)
338
- error ":what_to_show must be one of #{DATA_TYPES.inspect}", :args
339
- end
340
-
341
- bar_size = BAR_SIZES[data[:bar_size]] || data[:bar_size]
342
- unless BAR_SIZES.values.include?(bar_size)
343
- error ":bar_size must be one of #{BAR_SIZES.inspect}", :args
344
- end
345
-
346
- contract = data[:contract].is_a?(IB::Contract) ?
347
- data[:contract] : IB::Contract.from_ib_ruby(data[:contract])
348
-
349
- [data_type, bar_size, contract]
350
- end
351
- end
352
-
353
- # data = { :id => ticker_id (int),
354
- # :contract => Contract ,
355
- # :bar_size => int/Symbol? Currently only 5 second bars are supported,
356
- # if any other value is used, an exception will be thrown.,
357
- # :what_to_show => Symbol: Determines the nature of data being extracted.
358
- # Valid values:
359
- # :trades, :midpoint, :bid, :ask, :bid_ask,
360
- # :historical_volatility, :option_implied_volatility,
361
- # :option_volume, :option_open_interest
362
- # - converts to "TRADES," "MIDPOINT," "BID," etc...
363
- # :use_rth => int: 0 - all data available during the time span requested
364
- # is returned, even data bars covering time intervals where the
365
- # market in question was illiquid. 1 - only data within the
366
- # "Regular Trading Hours" of the product in question is returned,
367
- # even if the time span requested falls partially or completely
368
- # outside of them.
369
- RequestRealTimeBars = def_message 50, BarRequestMessage
370
-
371
- class RequestRealTimeBars
372
- def encode server
373
- data_type, bar_size, contract = parse @data
374
-
375
- [super,
376
- contract.serialize_long,
377
- bar_size,
378
- data_type.to_s.upcase,
379
- @data[:use_rth]].flatten
380
- end
381
- end # RequestRealTimeBars
382
-
383
- # data = { :id => int: Ticker id, needs to be different than the reqMktData ticker
384
- # id. If you use the same ticker ID you used for the symbol when
385
- # you did ReqMktData, nothing comes back for the historical data call
386
- # :contract => Contract: requested ticker description
387
- # :end_date_time => String: "yyyymmdd HH:mm:ss", with optional time zone
388
- # allowed after a space: "20050701 18:26:44 GMT"
389
- # :duration => String, time span the request will cover, and is specified
390
- # using the format: <integer> <unit>, eg: '1 D', valid units are:
391
- # '1 S' (seconds, default if no unit is specified)
392
- # '1 D' (days)
393
- # '1 W' (weeks)
394
- # '1 M' (months)
395
- # '1 Y' (years, currently limited to one)
396
- # :bar_size => String: Specifies the size of the bars that will be returned
397
- # (within IB/TWS limits). Valid values include:
398
- # '1 sec'
399
- # '5 secs'
400
- # '15 secs'
401
- # '30 secs'
402
- # '1 min'
403
- # '2 mins'
404
- # '3 mins'
405
- # '5 mins'
406
- # '15 mins'
407
- # '30 min'
408
- # '1 hour'
409
- # '1 day'
410
- # :what_to_show => Symbol: Determines the nature of data being extracted.
411
- # Valid values:
412
- # :trades, :midpoint, :bid, :ask, :bid_ask,
413
- # :historical_volatility, :option_implied_volatility,
414
- # :option_volume, :option_open_interest
415
- # - converts to "TRADES," "MIDPOINT," "BID," etc...
416
- # :use_rth => int: 0 - all data available during the time span requested
417
- # is returned, even data bars covering time intervals where the
418
- # market in question was illiquid. 1 - only data within the
419
- # "Regular Trading Hours" of the product in question is returned,
420
- # even if the time span requested falls partially or completely
421
- # outside of them.
422
- # :format_date => int: 1 - text format, like "20050307 11:32:16".
423
- # 2 - offset in seconds from the beginning of 1970,
424
- # which is the same format as the UNIX epoch time.
425
- # }
426
- #
427
- # Note that as of 4/07 there is no historical data available for forex spot.
428
- #
429
- # data[:contract] may either be a Contract object or a String. A String should be
430
- # in serialize_ib_ruby format; that is, it should be a colon-delimited string in
431
- # the format (e.g. for Globex British pound futures contract expiring in Sep-2008):
432
- #
433
- # symbol:security_type:expiry:strike:right:multiplier:exchange:primary_exchange:currency:local_symbol
434
- # GBP:FUT:200809:::62500:GLOBEX::USD:
435
- #
436
- # Fields not needed for a particular security should be left blank (e.g. strike
437
- # and right are only relevant for options.)
438
- #
439
- # A Contract object will be automatically serialized into the required format.
440
- #
441
- # See also http://chuckcaplan.com/twsapi/index.php/void%20reqIntradayData%28%29
442
- # for general information about how TWS handles historic data requests, whence
443
- # the following has been adapted:
444
- #
445
- # The server providing historical prices appears to not always be
446
- # available outside of market hours. If you call it outside of its
447
- # supported time period, or if there is otherwise a problem with
448
- # it, you will receive error #162 "Historical Market Data Service
449
- # query failed.:HMDS query returned no data."
450
- #
451
- # For backfill on futures data, you may need to leave the Primary
452
- # Exchange field of the Contract structure blank; see
453
- # http://www.interactivebrokers.com/discus/messages/2/28477.html?1114646754
454
- RequestHistoricalData = def_message [20, 4], BarRequestMessage
455
-
456
- class RequestHistoricalData
457
- def encode server
458
- data_type, bar_size, contract = parse @data
459
-
460
- [super,
461
- contract.serialize_long(:include_expired),
462
- @data[:end_date_time],
463
- bar_size,
464
- @data[:duration],
465
- @data[:use_rth],
466
- data_type.to_s.upcase,
467
- @data[:format_date],
468
- contract.serialize_legs].flatten
469
- end
470
- end # RequestHistoricalData
271
+ require 'ib-ruby/messages/outgoing/place_order'
272
+ require 'ib-ruby/messages/outgoing/bar_requests'
471
273
 
472
274
  end # module Outgoing
473
275
  end # module Messages