ib-ruby 0.7.4 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
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