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.
- data/.gitignore +3 -0
- data/HISTORY +8 -0
- data/README.md +2 -2
- data/Rakefile +15 -0
- data/TODO +7 -2
- data/VERSION +1 -1
- data/bin/account_info +1 -1
- data/bin/cancel_orders +1 -1
- data/bin/contract_details +1 -1
- data/bin/depth_of_market +1 -1
- data/bin/fa_accounts +1 -1
- data/bin/fundamental_data +42 -0
- data/bin/historic_data +1 -1
- data/bin/historic_data_cli +1 -1
- data/bin/list_orders +1 -2
- data/bin/market_data +1 -1
- data/bin/option_data +1 -1
- data/bin/place_combo_order +1 -1
- data/bin/place_order +1 -1
- data/bin/template +1 -4
- data/bin/tick_data +2 -2
- data/bin/time_and_sales +1 -1
- data/lib/ib-ruby.rb +4 -0
- data/lib/ib-ruby/connection.rb +50 -34
- data/lib/ib-ruby/constants.rb +232 -37
- data/lib/ib-ruby/db.rb +25 -0
- data/lib/ib-ruby/extensions.rb +51 -1
- data/lib/ib-ruby/messages/abstract_message.rb +0 -8
- data/lib/ib-ruby/messages/incoming.rb +18 -493
- data/lib/ib-ruby/messages/incoming/abstract_message.rb +100 -0
- data/lib/ib-ruby/messages/incoming/alert.rb +34 -0
- data/lib/ib-ruby/messages/incoming/contract_data.rb +82 -0
- data/lib/ib-ruby/messages/incoming/delta_neutral_validation.rb +20 -0
- data/lib/ib-ruby/messages/incoming/execution_data.rb +59 -0
- data/lib/ib-ruby/messages/incoming/historical_data.rb +55 -0
- data/lib/ib-ruby/messages/incoming/market_depths.rb +44 -0
- data/lib/ib-ruby/messages/incoming/open_order.rb +32 -16
- data/lib/ib-ruby/messages/incoming/order_status.rb +67 -0
- data/lib/ib-ruby/messages/incoming/portfolio_value.rb +39 -0
- data/lib/ib-ruby/messages/incoming/real_time_bar.rb +32 -0
- data/lib/ib-ruby/messages/incoming/scanner_data.rb +49 -0
- data/lib/ib-ruby/messages/outgoing.rb +25 -223
- data/lib/ib-ruby/messages/outgoing/abstract_message.rb +61 -0
- data/lib/ib-ruby/messages/outgoing/bar_requests.rb +149 -0
- data/lib/ib-ruby/messages/outgoing/place_order.rb +24 -0
- data/lib/ib-ruby/models.rb +4 -0
- data/lib/ib-ruby/models/bar.rb +31 -14
- data/lib/ib-ruby/models/combo_leg.rb +48 -23
- data/lib/ib-ruby/models/contracts.rb +2 -2
- data/lib/ib-ruby/models/contracts/bag.rb +11 -7
- data/lib/ib-ruby/models/contracts/contract.rb +90 -66
- data/lib/ib-ruby/models/contracts/option.rb +16 -7
- data/lib/ib-ruby/models/execution.rb +34 -18
- data/lib/ib-ruby/models/model.rb +15 -7
- data/lib/ib-ruby/models/model_properties.rb +101 -44
- data/lib/ib-ruby/models/order.rb +176 -187
- data/lib/ib-ruby/models/order_state.rb +99 -0
- data/lib/ib-ruby/symbols/forex.rb +10 -10
- data/lib/ib-ruby/symbols/futures.rb +6 -6
- data/lib/ib-ruby/symbols/stocks.rb +3 -3
- data/spec/account_helper.rb +4 -5
- data/spec/combo_helper.rb +4 -4
- data/spec/db.rb +18 -0
- data/spec/ib-ruby/messages/{incoming_spec.rb → incoming/alert_spec.rb} +1 -0
- data/spec/ib-ruby/messages/incoming/open_order_spec.rb +100 -0
- data/spec/ib-ruby/messages/incoming/order_status_spec.rb +74 -0
- data/spec/ib-ruby/messages/{outgoing_spec.rb → outgoing/account_data_spec.rb} +0 -0
- data/spec/ib-ruby/messages/outgoing/market_data_type_spec.rb +44 -0
- data/spec/ib-ruby/models/bag_spec.rb +97 -0
- data/spec/ib-ruby/models/bar_spec.rb +45 -0
- data/spec/ib-ruby/models/combo_leg_spec.rb +56 -40
- data/spec/ib-ruby/models/contract_spec.rb +134 -170
- data/spec/ib-ruby/models/execution_spec.rb +35 -50
- data/spec/ib-ruby/models/option_spec.rb +127 -0
- data/spec/ib-ruby/models/order_spec.rb +89 -68
- data/spec/ib-ruby/models/order_state_spec.rb +55 -0
- data/spec/integration/contract_info_spec.rb +4 -6
- data/spec/integration/fundamental_data_spec.rb +41 -0
- data/spec/integration/historic_data_spec.rb +4 -4
- data/spec/integration/market_data_spec.rb +1 -3
- data/spec/integration/orders/attached_spec.rb +8 -10
- data/spec/integration/orders/combo_spec.rb +2 -2
- data/spec/integration/orders/execution_spec.rb +0 -1
- data/spec/integration/orders/placement_spec.rb +1 -3
- data/spec/integration/orders/valid_ids_spec.rb +1 -2
- data/spec/message_helper.rb +1 -1
- data/spec/model_helper.rb +211 -0
- data/spec/order_helper.rb +44 -37
- data/spec/spec_helper.rb +36 -23
- data/spec/v.rb +7 -0
- data/tasks/doc.rake +1 -1
- metadata +116 -12
- 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
|
-
#
|
178
|
-
#
|
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
|
-
#
|
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
|
-
#
|
255
|
-
#
|
256
|
-
#
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
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
|
-
|
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
|