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,100 @@
|
|
1
|
+
require 'ib-ruby/messages/abstract_message'
|
2
|
+
|
3
|
+
module IB
|
4
|
+
module Messages
|
5
|
+
module Incoming
|
6
|
+
|
7
|
+
# Container for specific message classes, keyed by their message_ids
|
8
|
+
Classes = {}
|
9
|
+
|
10
|
+
class AbstractMessage < IB::Messages::AbstractMessage
|
11
|
+
|
12
|
+
def version # Per message, received messages may have the different versions
|
13
|
+
@data[:version]
|
14
|
+
end
|
15
|
+
|
16
|
+
def check_version actual, expected
|
17
|
+
unless actual == expected || expected.is_a?(Array) && expected.include?(actual)
|
18
|
+
error "Unsupported version #{actual} received, expected #{expected}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create incoming message from a given source (IB server or data Hash)
|
23
|
+
def initialize source
|
24
|
+
@created_at = Time.now
|
25
|
+
if source[:socket] # Source is a server
|
26
|
+
@server = source
|
27
|
+
@data = Hash.new
|
28
|
+
begin
|
29
|
+
self.load
|
30
|
+
rescue => e
|
31
|
+
error "Reading #{self.class}: #{e.class}: #{e.message}", :load, e.backtrace
|
32
|
+
ensure
|
33
|
+
@server = nil
|
34
|
+
end
|
35
|
+
else # Source is a @data Hash
|
36
|
+
@data = source
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def socket
|
41
|
+
@server[:socket]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Every message loads received message version first
|
45
|
+
# Override the load method in your subclass to do actual reading into @data.
|
46
|
+
def load
|
47
|
+
@data[:version] = socket.read_int
|
48
|
+
|
49
|
+
check_version @data[:version], self.class.version
|
50
|
+
|
51
|
+
load_map *self.class.data_map
|
52
|
+
end
|
53
|
+
|
54
|
+
# Load @data from the socket according to the given data map.
|
55
|
+
#
|
56
|
+
# map is a series of Arrays in the format of
|
57
|
+
# [ :name, :type ], [ :group, :name, :type]
|
58
|
+
# type identifiers must have a corresponding read_type method on socket (read_int, etc.).
|
59
|
+
# group is used to lump together aggregates, such as Contract or Order fields
|
60
|
+
def load_map(*map)
|
61
|
+
map.each do |instruction|
|
62
|
+
# We determine the function of the first element
|
63
|
+
head = instruction.first
|
64
|
+
case head
|
65
|
+
when Integer # >= Version condition: [ min_version, [map]]
|
66
|
+
load_map *instruction.drop(1) if version >= head
|
67
|
+
|
68
|
+
when Proc # Callable condition: [ condition, [map]]
|
69
|
+
load_map *instruction.drop(1) if head.call
|
70
|
+
|
71
|
+
when true # Pre-condition already succeeded!
|
72
|
+
load_map *instruction.drop(1)
|
73
|
+
|
74
|
+
when nil, false # Pre-condition already failed! Do nothing...
|
75
|
+
|
76
|
+
when Symbol # Normal map
|
77
|
+
group, name, type, block =
|
78
|
+
if instruction[2].nil? || instruction[2].is_a?(Proc)
|
79
|
+
[nil] + instruction # No group, [ :name, :type, (:block) ]
|
80
|
+
else
|
81
|
+
instruction # [ :group, :name, :type, (:block)]
|
82
|
+
end
|
83
|
+
|
84
|
+
data = socket.__send__("read_#{type}", &block)
|
85
|
+
if group
|
86
|
+
@data[group] ||= {}
|
87
|
+
@data[group][name] = data
|
88
|
+
else
|
89
|
+
@data[name] = data
|
90
|
+
end
|
91
|
+
else
|
92
|
+
error "Unrecognized instruction #{instruction}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end # class AbstractMessage
|
98
|
+
end # module Incoming
|
99
|
+
end # module Messages
|
100
|
+
end # module IB
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module IB
|
2
|
+
module Messages
|
3
|
+
module Incoming
|
4
|
+
|
5
|
+
# Called Error in Java code, but in fact this type of messages also
|
6
|
+
# deliver system alerts and additional (non-error) info from TWS.
|
7
|
+
ErrorMessage = Error = Alert = def_message([4, 2],
|
8
|
+
[:error_id, :int],
|
9
|
+
[:code, :int],
|
10
|
+
[:message, :string])
|
11
|
+
class Alert
|
12
|
+
# Is it an Error message?
|
13
|
+
def error?
|
14
|
+
code < 1000
|
15
|
+
end
|
16
|
+
|
17
|
+
# Is it a System message?
|
18
|
+
def system?
|
19
|
+
code > 1000 && code < 2000
|
20
|
+
end
|
21
|
+
|
22
|
+
# Is it a Warning message?
|
23
|
+
def warning?
|
24
|
+
code > 2000
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_human
|
28
|
+
"TWS #{ error? ? 'Error' : system? ? 'System' : 'Warning'} #{code}: #{message}"
|
29
|
+
end
|
30
|
+
end # class Alert
|
31
|
+
|
32
|
+
end # module Incoming
|
33
|
+
end # module Messages
|
34
|
+
end # module IB
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module IB
|
2
|
+
module Messages
|
3
|
+
module Incoming
|
4
|
+
|
5
|
+
ContractDetails = ContractData =
|
6
|
+
def_message([10, 6],
|
7
|
+
[:request_id, :int], # request id
|
8
|
+
[:contract, :symbol, :string],
|
9
|
+
[:contract, :sec_type, :string],
|
10
|
+
[:contract, :expiry, :string],
|
11
|
+
[:contract, :strike, :decimal],
|
12
|
+
[:contract, :right, :string],
|
13
|
+
[:contract, :exchange, :string],
|
14
|
+
[:contract, :currency, :string],
|
15
|
+
[:contract, :local_symbol, :string],
|
16
|
+
|
17
|
+
[:contract, :market_name, :string], # extended
|
18
|
+
[:contract, :trading_class, :string],
|
19
|
+
[:contract, :con_id, :int],
|
20
|
+
[:contract, :min_tick, :decimal],
|
21
|
+
[:contract, :multiplier, :string],
|
22
|
+
[:contract, :order_types, :string],
|
23
|
+
[:contract, :valid_exchanges, :string],
|
24
|
+
[:contract, :price_magnifier, :int],
|
25
|
+
[:contract, :under_con_id, :int],
|
26
|
+
[:contract, :long_name, :string],
|
27
|
+
[:contract, :primary_exchange, :string],
|
28
|
+
[:contract, :contract_month, :string],
|
29
|
+
[:contract, :industry, :string],
|
30
|
+
[:contract, :category, :string],
|
31
|
+
[:contract, :subcategory, :string],
|
32
|
+
[:contract, :time_zone, :string],
|
33
|
+
[:contract, :trading_hours, :string],
|
34
|
+
[:contract, :liquid_hours, :string])
|
35
|
+
|
36
|
+
class ContractData
|
37
|
+
|
38
|
+
def contract
|
39
|
+
@contract = IB::Contract.build @data[:contract]
|
40
|
+
end
|
41
|
+
end # ContractData
|
42
|
+
|
43
|
+
BondContractData =
|
44
|
+
def_message [18, 4],
|
45
|
+
[:request_id, :int],
|
46
|
+
[:contract, :symbol, :string],
|
47
|
+
[:contract, :sec_type, :string],
|
48
|
+
[:contract, :cusip, :string],
|
49
|
+
[:contract, :coupon, :decimal],
|
50
|
+
[:contract, :maturity, :string],
|
51
|
+
[:contract, :issue_date, :string],
|
52
|
+
[:contract, :ratings, :string],
|
53
|
+
[:contract, :bond_type, :string],
|
54
|
+
[:contract, :coupon_type, :string],
|
55
|
+
[:contract, :convertible, :boolean],
|
56
|
+
[:contract, :callable, :boolean],
|
57
|
+
[:contract, :puttable, :boolean],
|
58
|
+
[:contract, :desc_append, :string],
|
59
|
+
[:contract, :exchange, :string],
|
60
|
+
[:contract, :currency, :string],
|
61
|
+
[:contract, :market_name, :string], # extended
|
62
|
+
[:contract, :trading_class, :string],
|
63
|
+
[:contract, :con_id, :int],
|
64
|
+
[:contract, :min_tick, :decimal],
|
65
|
+
[:contract, :order_types, :string],
|
66
|
+
[:contract, :valid_exchanges, :string],
|
67
|
+
[:contract, :valid_next_option_date, :string],
|
68
|
+
[:contract, :valid_next_option_type, :string],
|
69
|
+
[:contract, :valid_next_option_partial, :string],
|
70
|
+
[:contract, :notes, :string],
|
71
|
+
[:contract, :long_name, :string]
|
72
|
+
|
73
|
+
class BondContractData
|
74
|
+
|
75
|
+
def contract
|
76
|
+
@contract = IB::Contract.build @data[:contract]
|
77
|
+
end
|
78
|
+
end # BondContractData
|
79
|
+
|
80
|
+
end # module Incoming
|
81
|
+
end # module Messages
|
82
|
+
end # module IB
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module IB
|
2
|
+
module Messages
|
3
|
+
module Incoming
|
4
|
+
|
5
|
+
# The server sends this message upon accepting a Delta-Neutral DN RFQ
|
6
|
+
# - see API Reference p. 26
|
7
|
+
DeltaNeutralValidation = def_message 56,
|
8
|
+
[:request_id, :int],
|
9
|
+
[:contract, :under_con_id, :int],
|
10
|
+
[:contract, :under_delta, :decimal],
|
11
|
+
[:contract, :under_price, :decimal]
|
12
|
+
class DeltaNeutralValidation
|
13
|
+
def contract
|
14
|
+
@contract = IB::Contract.build @data[:contract].merge(:under_comp => true)
|
15
|
+
end
|
16
|
+
end # DeltaNeutralValidation
|
17
|
+
|
18
|
+
end # module Incoming
|
19
|
+
end # module Messages
|
20
|
+
end # module IB
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module IB
|
2
|
+
module Messages
|
3
|
+
module Incoming
|
4
|
+
|
5
|
+
ExecutionData =
|
6
|
+
def_message [11, 8],
|
7
|
+
# The reqID that was specified previously in the call to reqExecution()
|
8
|
+
[:request_id, :int],
|
9
|
+
[:execution, :order_id, :int],
|
10
|
+
[:contract, :con_id, :int],
|
11
|
+
[:contract, :symbol, :string],
|
12
|
+
[:contract, :sec_type, :string],
|
13
|
+
[:contract, :expiry, :string],
|
14
|
+
[:contract, :strike, :decimal],
|
15
|
+
[:contract, :right, :string],
|
16
|
+
[:contract, :exchange, :string],
|
17
|
+
[:contract, :currency, :string],
|
18
|
+
[:contract, :local_symbol, :string],
|
19
|
+
|
20
|
+
[:execution, :exec_id, :string], # Weird format
|
21
|
+
[:execution, :time, :string],
|
22
|
+
[:execution, :account_name, :string],
|
23
|
+
[:execution, :exchange, :string],
|
24
|
+
[:execution, :side, :string],
|
25
|
+
[:execution, :shares, :int],
|
26
|
+
[:execution, :price, :decimal],
|
27
|
+
[:execution, :perm_id, :int],
|
28
|
+
[:execution, :client_id, :int],
|
29
|
+
[:execution, :liquidation, :int],
|
30
|
+
[:execution, :cumulative_quantity, :int],
|
31
|
+
[:execution, :average_price, :decimal]
|
32
|
+
|
33
|
+
class ExecutionData
|
34
|
+
|
35
|
+
def contract
|
36
|
+
@contract = IB::Contract.build @data[:contract]
|
37
|
+
end
|
38
|
+
|
39
|
+
def execution
|
40
|
+
@execution = IB::Execution.new @data[:execution]
|
41
|
+
end
|
42
|
+
|
43
|
+
def load
|
44
|
+
super
|
45
|
+
|
46
|
+
# As of client v.53, we can receive orderRef in ExecutionData
|
47
|
+
load_map [proc { | | @server[:client_version] >= 53 },
|
48
|
+
[:execution, :order_ref, :string]
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_human
|
53
|
+
"<ExecutionData #{request_id}: #{contract.to_human}, #{execution}>"
|
54
|
+
end
|
55
|
+
|
56
|
+
end # ExecutionData
|
57
|
+
end # module Incoming
|
58
|
+
end # module Messages
|
59
|
+
end # module IB
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module IB
|
2
|
+
module Messages
|
3
|
+
module Incoming
|
4
|
+
|
5
|
+
# HistoricalData contains following @data:
|
6
|
+
# General:
|
7
|
+
# :request_id - The ID of the request to which this is responding
|
8
|
+
# :count - Number of Historical data points returned (size of :results).
|
9
|
+
# :results - an Array of Historical Data Bars
|
10
|
+
# :start_date - beginning of returned Historical data period
|
11
|
+
# :end_date - end of returned Historical data period
|
12
|
+
# Each returned Bar in @data[:results] Array contains this data:
|
13
|
+
# :date - The date-time stamp of the start of the bar. The format is
|
14
|
+
# determined by the RequestHistoricalData formatDate parameter.
|
15
|
+
# :open - The bar opening price.
|
16
|
+
# :high - The high price during the time covered by the bar.
|
17
|
+
# :low - The low price during the time covered by the bar.
|
18
|
+
# :close - The bar closing price.
|
19
|
+
# :volume - The volume during the time covered by the bar.
|
20
|
+
# :trades - When TRADES historical data is returned, represents number of trades
|
21
|
+
# that occurred during the time period the bar covers
|
22
|
+
# :wap - The weighted average price during the time covered by the bar.
|
23
|
+
# :has_gaps - Whether or not there are gaps in the data.
|
24
|
+
|
25
|
+
HistoricalData = def_message [17, 3],
|
26
|
+
[:request_id, :int],
|
27
|
+
[:start_date, :string],
|
28
|
+
[:end_date, :string],
|
29
|
+
[:count, :int]
|
30
|
+
class HistoricalData
|
31
|
+
attr_accessor :results
|
32
|
+
|
33
|
+
def load
|
34
|
+
super
|
35
|
+
|
36
|
+
@results = Array.new(@data[:count]) do |_|
|
37
|
+
IB::Bar.new :time => socket.read_string,
|
38
|
+
:open => socket.read_decimal,
|
39
|
+
:high => socket.read_decimal,
|
40
|
+
:low => socket.read_decimal,
|
41
|
+
:close => socket.read_decimal,
|
42
|
+
:volume => socket.read_int,
|
43
|
+
:wap => socket.read_decimal,
|
44
|
+
:has_gaps => socket.read_string,
|
45
|
+
:trades => socket.read_int
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_human
|
50
|
+
"<HistoricalData: #{request_id}, #{count} items, #{start_date} to #{end_date}>"
|
51
|
+
end
|
52
|
+
end # HistoricalData
|
53
|
+
end # module Incoming
|
54
|
+
end # module Messages
|
55
|
+
end # module IB
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module IB
|
2
|
+
module Messages
|
3
|
+
module Incoming
|
4
|
+
|
5
|
+
MarketDepth =
|
6
|
+
def_message 12, [:request_id, :int],
|
7
|
+
[:position, :int], # The row Id of this market depth entry.
|
8
|
+
[:operation, :int], # How it should be applied to the market depth:
|
9
|
+
# 0 = insert this new order into the row identified by :position
|
10
|
+
# 1 = update the existing order in the row identified by :position
|
11
|
+
# 2 = delete the existing order at the row identified by :position
|
12
|
+
[:side, :int], # side of the book: 0 = ask, 1 = bid
|
13
|
+
[:price, :decimal],
|
14
|
+
[:size, :int]
|
15
|
+
|
16
|
+
class MarketDepth
|
17
|
+
def side
|
18
|
+
@data[:side] == 0 ? :ask : :bid
|
19
|
+
end
|
20
|
+
|
21
|
+
def operation
|
22
|
+
@data[:operation] == 0 ? :insert : @data[:operation] == 1 ? :update : :delete
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_human
|
26
|
+
"<#{self.message_type}: #{operation} #{side} @ "+
|
27
|
+
"#{position} = #{price} x #{size}>"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
MarketDepthL2 =
|
32
|
+
def_message 13, MarketDepth, # Fields descriptions - see above
|
33
|
+
[:request_id, :int],
|
34
|
+
[:position, :int],
|
35
|
+
[:market_maker, :string], # The exchange hosting this order.
|
36
|
+
[:operation, :int],
|
37
|
+
[:side, :int],
|
38
|
+
[:price, :decimal],
|
39
|
+
[:size, :int]
|
40
|
+
|
41
|
+
|
42
|
+
end # module Incoming
|
43
|
+
end # module Messages
|
44
|
+
end # module IB
|
@@ -1,8 +1,8 @@
|
|
1
|
-
# OpenOrder is the longest message with complex processing logics, it is isolated here
|
2
1
|
module IB
|
3
2
|
module Messages
|
4
3
|
module Incoming
|
5
4
|
|
5
|
+
# OpenOrder is the longest message with complex processing logics
|
6
6
|
OpenOrder =
|
7
7
|
def_message [5, [23, 28]],
|
8
8
|
[:order, :order_id, :int],
|
@@ -73,13 +73,32 @@ module IB
|
|
73
73
|
|
74
74
|
class OpenOrder
|
75
75
|
|
76
|
+
|
76
77
|
# Accessors to make OpenOrder API-compatible with OrderStatus message
|
78
|
+
|
79
|
+
def order
|
80
|
+
@order ||= IB::Order.new @data[:order].merge(:order_state => order_state)
|
81
|
+
end
|
82
|
+
|
83
|
+
def order_state
|
84
|
+
@order_state ||= IB::OrderState.new(
|
85
|
+
@data[:order_state].merge(
|
86
|
+
:order_id => @data[:order][:order_id],
|
87
|
+
:perm_id => @data[:order][:perm_id],
|
88
|
+
:parent_id => @data[:order][:parent_id],
|
89
|
+
:client_id => @data[:order][:client_id]))
|
90
|
+
end
|
91
|
+
|
92
|
+
def contract
|
93
|
+
@contract ||= IB::Contract.build @data[:contract]
|
94
|
+
end
|
95
|
+
|
77
96
|
def order_id
|
78
|
-
order
|
97
|
+
order.order_id
|
79
98
|
end
|
80
99
|
|
81
100
|
def status
|
82
|
-
order
|
101
|
+
order.status
|
83
102
|
end
|
84
103
|
|
85
104
|
def load
|
@@ -166,20 +185,17 @@ module IB
|
|
166
185
|
],
|
167
186
|
|
168
187
|
[:order, :what_if, :boolean],
|
169
|
-
[:order, :status, :string],
|
170
188
|
|
189
|
+
[:order_state, :status, :string],
|
171
190
|
# IB uses weird String with Java Double.MAX_VALUE to indicate no value here
|
172
|
-
[:
|
173
|
-
[:
|
174
|
-
[:
|
175
|
-
[:
|
176
|
-
[:
|
177
|
-
[:
|
178
|
-
[:
|
179
|
-
[:
|
180
|
-
|
181
|
-
@order = IB::Order.new @data[:order]
|
182
|
-
@contract = IB::Contract.build @data[:contract]
|
191
|
+
[:order_state, :init_margin, :decimal_max], # :string],
|
192
|
+
[:order_state, :maint_margin, :decimal_max], # :string],
|
193
|
+
[:order_state, :equity_with_loan, :decimal_max], # :string],
|
194
|
+
[:order_state, :commission, :decimal_max], # May be nil!
|
195
|
+
[:order_state, :min_commission, :decimal_max], # May be nil!
|
196
|
+
[:order_state, :max_commission, :decimal_max], # May be nil!
|
197
|
+
[:order_state, :commission_currency, :string],
|
198
|
+
[:order_state, :warning_text, :string]
|
183
199
|
end
|
184
200
|
|
185
201
|
# Check if given value was set by TWS to something vaguely "positive"
|
@@ -195,7 +211,7 @@ module IB
|
|
195
211
|
end
|
196
212
|
|
197
213
|
def to_human
|
198
|
-
"<OpenOrder: #{
|
214
|
+
"<OpenOrder: #{contract.to_human} #{order.to_human}>"
|
199
215
|
end
|
200
216
|
|
201
217
|
end # class OpenOrder
|