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