ib-ruby 0.7.3 → 0.7.4
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/HISTORY +4 -0
- data/README.md +60 -30
- data/TODO +1 -0
- data/VERSION +1 -1
- data/bin/account_info +1 -4
- data/bin/cancel_orders +0 -3
- data/bin/contract_details +2 -5
- data/bin/depth_of_market +1 -4
- data/bin/fa_accounts +22 -0
- data/bin/historic_data +1 -4
- data/bin/historic_data_cli +0 -4
- data/bin/list_orders +2 -6
- data/bin/market_data +1 -4
- data/bin/option_data +2 -5
- data/bin/place_combo_order +17 -22
- data/bin/place_order +6 -10
- data/bin/tick_data +6 -9
- data/bin/time_and_sales +2 -5
- data/lib/ib-ruby/connection.rb +10 -5
- data/lib/ib-ruby/messages/incoming/open_order.rb +15 -13
- data/lib/ib-ruby/messages/incoming/ticks.rb +1 -1
- data/lib/ib-ruby/messages/incoming.rb +18 -18
- data/lib/ib-ruby/messages/outgoing.rb +2 -2
- data/lib/ib-ruby/messages.rb +3 -7
- data/lib/ib-ruby/models/{contract → contracts}/bag.rb +5 -8
- data/lib/ib-ruby/models/contracts/contract.rb +296 -0
- data/lib/ib-ruby/models/{contract → contracts}/option.rb +2 -4
- data/lib/ib-ruby/models/contracts.rb +27 -0
- data/lib/ib-ruby/models/execution.rb +1 -1
- data/lib/ib-ruby/models/order.rb +6 -17
- data/lib/ib-ruby/models.rb +9 -7
- data/lib/ib-ruby/symbols/forex.rb +50 -50
- data/lib/ib-ruby/symbols/futures.rb +47 -47
- data/lib/ib-ruby/symbols/options.rb +23 -23
- data/lib/ib-ruby/symbols/stocks.rb +14 -14
- data/lib/ib-ruby.rb +17 -9
- data/spec/README.md +6 -0
- data/spec/account_helper.rb +1 -1
- data/spec/combo_helper.rb +31 -0
- data/spec/ib-ruby/models/combo_leg_spec.rb +4 -4
- data/spec/ib-ruby/models/contract_spec.rb +37 -26
- data/spec/ib-ruby/models/execution_spec.rb +5 -5
- data/spec/ib-ruby/models/order_spec.rb +16 -16
- data/spec/integration/contract_info_spec.rb +8 -10
- data/spec/integration/historic_data_spec.rb +1 -1
- data/spec/integration/market_data_spec.rb +5 -5
- data/spec/integration/orders/attached_spec.rb +87 -0
- data/spec/integration/orders/combo_spec.rb +52 -65
- data/spec/integration/orders/placement_spec.rb +8 -8
- data/spec/order_helper.rb +97 -28
- data/spec/spec_helper.rb +2 -2
- metadata +12 -5
- data/lib/ib-ruby/models/contract.rb +0 -308
@@ -343,8 +343,8 @@ module IB
|
|
343
343
|
error ":bar_size must be one of #{BAR_SIZES.inspect}", :args
|
344
344
|
end
|
345
345
|
|
346
|
-
contract = data[:contract].is_a?(
|
347
|
-
data[:contract] :
|
346
|
+
contract = data[:contract].is_a?(IB::Contract) ?
|
347
|
+
data[:contract] : IB::Contract.from_ib_ruby(data[:contract])
|
348
348
|
|
349
349
|
[data_type, bar_size, contract]
|
350
350
|
end
|
data/lib/ib-ruby/messages.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
module IB
|
2
|
-
|
3
2
|
module Messages
|
4
3
|
end
|
4
|
+
end
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
IncomingMessages = Messages::Incoming # Legacy alias
|
10
|
-
OutgoingMessages = Messages::Outgoing # Legacy alias
|
6
|
+
require 'ib-ruby/messages/outgoing'
|
7
|
+
require 'ib-ruby/messages/incoming'
|
11
8
|
|
12
|
-
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'ib-ruby/models/contract'
|
1
|
+
require 'ib-ruby/models/contracts/contract'
|
2
2
|
|
3
3
|
module IB
|
4
4
|
module Models
|
5
|
-
|
5
|
+
module Contracts
|
6
6
|
|
7
7
|
# "BAG" is not really a contract, but a combination (combo) of securities.
|
8
8
|
# AKA basket or bag of securities. Individual securities in combo are represented
|
@@ -53,9 +53,6 @@ module IB
|
|
53
53
|
end
|
54
54
|
|
55
55
|
end # class Bag
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end # class Contract
|
60
|
-
end # module Models
|
61
|
-
end # module IB
|
56
|
+
end # Contracts
|
57
|
+
end # Models
|
58
|
+
end # IB
|
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'ib-ruby/models/model'
|
2
|
+
|
3
|
+
module IB
|
4
|
+
module Models
|
5
|
+
module Contracts
|
6
|
+
class Contract < Model
|
7
|
+
|
8
|
+
# This returns a Contract initialized from the serialize_ib_ruby format string.
|
9
|
+
def self.build opts = {}
|
10
|
+
Contracts::TYPES[opts[:sec_type]].new opts
|
11
|
+
end
|
12
|
+
|
13
|
+
# This returns a Contract initialized from the serialize_ib_ruby format string.
|
14
|
+
def self.from_ib_ruby string
|
15
|
+
keys = [:symbol, :sec_type, :expiry, :strike, :right, :multiplier,
|
16
|
+
:exchange, :primary_exchange, :currency, :local_symbol]
|
17
|
+
props = Hash[keys.zip(string.split(":"))]
|
18
|
+
props.delete_if { |k, v| v.nil? || v.empty? }
|
19
|
+
Contract.new props
|
20
|
+
end
|
21
|
+
|
22
|
+
# Fields are Strings unless noted otherwise
|
23
|
+
prop :con_id, # int: The unique contract identifier.
|
24
|
+
:symbol, # This is the symbol of the underlying asset.
|
25
|
+
:sec_type, # Security type. Valid values are: SECURITY_TYPES
|
26
|
+
:strike, # double: The strike price.
|
27
|
+
:exchange, # The order destination, such as Smart.
|
28
|
+
:currency, # Only needed if there is an ambiguity, e.g. when SMART exchange
|
29
|
+
# and IBM is being requested (IBM can trade in GBP or USD).
|
30
|
+
|
31
|
+
:local_symbol, # Local exchange symbol of the underlying asset
|
32
|
+
:include_expired, # When true, contract details requests and historical
|
33
|
+
# data queries can be performed pertaining to expired contracts.
|
34
|
+
# Note: Historical data queries on expired contracts are
|
35
|
+
# limited to the last year of the contracts life, and are
|
36
|
+
# only supported for expired futures contracts.
|
37
|
+
# This field can NOT be set to true for orders.
|
38
|
+
|
39
|
+
:sec_id_type, # Security identifier, when querying contract details or
|
40
|
+
# when placing orders. Supported identifiers are:
|
41
|
+
# - ISIN (Example: Apple: US0378331005)
|
42
|
+
# - CUSIP (Example: Apple: 037833100)
|
43
|
+
# - SEDOL (6-AN + check digit. Example: BAE: 0263494)
|
44
|
+
# - RIC (exchange-independent RIC Root and exchange-
|
45
|
+
# identifying suffix. Ex: AAPL.O for Apple on NASDAQ.)
|
46
|
+
:sec_id, # Unique identifier of the given secIdType.
|
47
|
+
|
48
|
+
# COMBOS
|
49
|
+
:legs_description, # received in OpenOrder for all combos
|
50
|
+
|
51
|
+
:multiplier => :i,
|
52
|
+
# Future/option contract multiplier (only needed when multiple possibilities exist)
|
53
|
+
|
54
|
+
:primary_exchange =>
|
55
|
+
# non-aggregate (ie not the SMART) exchange that the contract trades on.
|
56
|
+
proc { |val|
|
57
|
+
val.upcase! if val.is_a?(String)
|
58
|
+
error "Don't set primary_exchange to smart", :args if val == 'SMART'
|
59
|
+
self[:primary_exchange] = val
|
60
|
+
},
|
61
|
+
|
62
|
+
:right => # Specifies a Put or Call. Valid input values are: P, PUT, C, CALL
|
63
|
+
proc { |val|
|
64
|
+
self[:right] =
|
65
|
+
case val.to_s.upcase
|
66
|
+
when '', '0', '?'
|
67
|
+
nil
|
68
|
+
when 'PUT', 'P'
|
69
|
+
'PUT'
|
70
|
+
when 'CALL', 'C'
|
71
|
+
'CALL'
|
72
|
+
else
|
73
|
+
error "Right must be one of PUT, CALL, P, C - not '#{val}'", :args
|
74
|
+
end
|
75
|
+
},
|
76
|
+
|
77
|
+
:expiry => # The expiration date. Use the format YYYYMM.
|
78
|
+
proc { |val|
|
79
|
+
self[:expiry] =
|
80
|
+
case val.to_s
|
81
|
+
when /\d{6,8}/
|
82
|
+
val.to_s
|
83
|
+
when nil, ''
|
84
|
+
nil
|
85
|
+
else
|
86
|
+
error "Invalid expiry '#{val}' (must be in format YYYYMM or YYYYMMDD)", :args
|
87
|
+
end
|
88
|
+
},
|
89
|
+
|
90
|
+
:sec_type => # Security type. Valid values are: SECURITY_TYPES
|
91
|
+
proc { |val|
|
92
|
+
val = nil if !val.nil? && val.empty?
|
93
|
+
unless val.nil? || SECURITY_TYPES.values.include?(val)
|
94
|
+
error "Invalid security type '#{val}' (must be one of #{SECURITY_TYPES.values}", :args
|
95
|
+
end
|
96
|
+
self[:sec_type] = val
|
97
|
+
}
|
98
|
+
|
99
|
+
# ContractDetails fields are bundled into Contract proper, as it should be
|
100
|
+
# All fields Strings, unless specified otherwise:
|
101
|
+
prop :market_name, # The market name for this contract.
|
102
|
+
:trading_class, # The trading class name for this contract.
|
103
|
+
:min_tick, # double: The minimum price tick.
|
104
|
+
:price_magnifier, # int: Allows execution and strike prices to be
|
105
|
+
# reported consistently with market data, historical data and the
|
106
|
+
# order price: Z on LIFFE is reported in index points, not GBP.
|
107
|
+
|
108
|
+
:order_types, # The list of valid order types for this contract.
|
109
|
+
:valid_exchanges, # The list of exchanges this contract is traded on.
|
110
|
+
:under_con_id, # int: The underlying contract ID.
|
111
|
+
:long_name, # Descriptive name of the asset.
|
112
|
+
:contract_month, # The contract month of the underlying for a futures contract.
|
113
|
+
|
114
|
+
# The industry classification of the underlying/product:
|
115
|
+
:industry, # Wide industry. For example, Financial.
|
116
|
+
:category, # Industry category. For example, InvestmentSvc.
|
117
|
+
:subcategory, # Subcategory. For example, Brokerage.
|
118
|
+
:time_zone, # Time zone for the trading hours of the product. For example, EST.
|
119
|
+
:trading_hours, # The trading hours of the product. For example:
|
120
|
+
# 20090507:0700-1830,1830-2330;20090508:CLOSED.
|
121
|
+
:liquid_hours, # The liquid trading hours of the product. For example,
|
122
|
+
# 20090507:0930-1600;20090508:CLOSED.
|
123
|
+
|
124
|
+
# Bond values:
|
125
|
+
:cusip, # The nine-character bond CUSIP or the 12-character SEDOL.
|
126
|
+
:ratings, # Credit rating of the issuer. Higher rating is less risky investment.
|
127
|
+
# Bond ratings are from Moody's and S&P respectively.
|
128
|
+
:desc_append, # Additional descriptive information about the bond.
|
129
|
+
:bond_type, # The type of bond, such as "CORP."
|
130
|
+
:coupon_type, # The type of bond coupon.
|
131
|
+
:callable, # bool: Can be called by the issuer under certain conditions.
|
132
|
+
:puttable, # bool: Can be sold back to the issuer under certain conditions
|
133
|
+
:coupon, # double: The interest rate used to calculate the amount you
|
134
|
+
# will receive in interest payments over the year. default 0
|
135
|
+
:convertible, # bool: Can be converted to stock under certain conditions.
|
136
|
+
:maturity, # The date on which the issuer must repay bond face value
|
137
|
+
:issue_date, # The date the bond was issued.
|
138
|
+
:next_option_date, # only if bond has embedded options.
|
139
|
+
:next_option_type, # only if bond has embedded options.
|
140
|
+
:next_option_partial, # bool: # only if bond has embedded options.
|
141
|
+
:notes # Additional notes, if populated for the bond in IB's database
|
142
|
+
|
143
|
+
# Used for Delta-Neutral Combo contracts only!
|
144
|
+
# UnderComp fields are bundled into Contract proper, as it should be.
|
145
|
+
prop :under_comp, # if not nil, attributes below are sent to server
|
146
|
+
#:under_con_id is is already defined in ContractDetails section
|
147
|
+
:under_delta, # double: The underlying stock or future delta.
|
148
|
+
:under_price # double: The price of the underlying.
|
149
|
+
|
150
|
+
# Legs arriving via OpenOrder message, need to define them here
|
151
|
+
attr_accessor :legs # leg definitions for this contract.
|
152
|
+
alias combo_legs legs
|
153
|
+
alias combo_legs= legs=
|
154
|
+
alias combo_legs_description legs_description
|
155
|
+
alias combo_legs_description= legs_description=
|
156
|
+
|
157
|
+
attr_accessor :description # NB: local to ib-ruby, not part of TWS.
|
158
|
+
|
159
|
+
DEFAULT_PROPS = {:con_id => 0,
|
160
|
+
:strike => 0,
|
161
|
+
:exchange => 'SMART',
|
162
|
+
:include_expired => false,
|
163
|
+
|
164
|
+
# These properties are from ContractDetails
|
165
|
+
:under_con_id => 0,
|
166
|
+
:min_tick => 0,
|
167
|
+
:callable => false,
|
168
|
+
:puttable => false,
|
169
|
+
:coupon => 0,
|
170
|
+
:convertible => false,
|
171
|
+
:next_option_partial => false, }
|
172
|
+
|
173
|
+
# NB: ContractDetails reference - to self!
|
174
|
+
def summary
|
175
|
+
self
|
176
|
+
end
|
177
|
+
|
178
|
+
# This returns an Array of data from the given contract.
|
179
|
+
# Different messages serialize contracts differently. Go figure.
|
180
|
+
# Note that it does NOT include the combo legs.
|
181
|
+
def serialize *fields
|
182
|
+
[(fields.include?(:con_id) ? [con_id] : []),
|
183
|
+
symbol,
|
184
|
+
sec_type,
|
185
|
+
(fields.include?(:option) ? [expiry, strike, right, multiplier] : []),
|
186
|
+
exchange,
|
187
|
+
(fields.include?(:primary_exchange) ? [primary_exchange] : []),
|
188
|
+
currency,
|
189
|
+
local_symbol,
|
190
|
+
(fields.include?(:sec_id) ? [sec_id_type, sec_id] : []),
|
191
|
+
(fields.include?(:include_expired) ? [include_expired] : []),
|
192
|
+
].flatten
|
193
|
+
end
|
194
|
+
|
195
|
+
def serialize_long *fields
|
196
|
+
serialize :option, :primary_exchange, *fields
|
197
|
+
end
|
198
|
+
|
199
|
+
def serialize_short *fields
|
200
|
+
serialize :option, *fields
|
201
|
+
end
|
202
|
+
|
203
|
+
# Serialize under_comp parameters
|
204
|
+
def serialize_under_comp *args
|
205
|
+
# EClientSocket.java, line 471:
|
206
|
+
if under_comp
|
207
|
+
[true,
|
208
|
+
under_con_id,
|
209
|
+
under_delta,
|
210
|
+
under_price]
|
211
|
+
else
|
212
|
+
[false]
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Redefined in BAG subclass
|
217
|
+
def serialize_legs *fields
|
218
|
+
[]
|
219
|
+
end
|
220
|
+
|
221
|
+
# This produces a string uniquely identifying this contract, in the format used
|
222
|
+
# for command line arguments in the IB-Ruby examples. The format is:
|
223
|
+
#
|
224
|
+
# symbol:security_type:expiry:strike:right:multiplier:exchange:primary_exchange:currency:local_symbol
|
225
|
+
#
|
226
|
+
# Fields not needed for a particular security should be left blank
|
227
|
+
# (e.g. strike and right are only relevant for options.)
|
228
|
+
#
|
229
|
+
# For example, to query the British pound futures contract trading on Globex
|
230
|
+
# expiring in September, 2008, the string is:
|
231
|
+
#
|
232
|
+
# GBP:FUT:200809:::62500:GLOBEX::USD:
|
233
|
+
def serialize_ib_ruby
|
234
|
+
serialize_long.join(":")
|
235
|
+
end
|
236
|
+
|
237
|
+
# Contract comparison
|
238
|
+
def == other
|
239
|
+
return false unless other.is_a?(self.class)
|
240
|
+
|
241
|
+
# Different sec_id_type
|
242
|
+
return false if sec_id_type && other.sec_id_type && sec_id_type != other.sec_id_type
|
243
|
+
|
244
|
+
# Different sec_id
|
245
|
+
return false if sec_id && other.sec_id && sec_id != other.sec_id
|
246
|
+
|
247
|
+
# Different under_comp
|
248
|
+
return false if under_comp && other.under_comp && under_comp != other.under_comp
|
249
|
+
|
250
|
+
# Different symbols
|
251
|
+
return false if symbol && other.symbol && symbol != other.symbol
|
252
|
+
|
253
|
+
# Different currency
|
254
|
+
return false if currency && other.currency && currency != other.currency
|
255
|
+
|
256
|
+
# Same con_id for all Bags, but unknown for new Contracts...
|
257
|
+
# 0 or nil con_id matches any
|
258
|
+
return false if con_id != 0 && other.con_id != 0 &&
|
259
|
+
con_id && other.con_id && con_id != other.con_id
|
260
|
+
|
261
|
+
# SMART or nil exchange matches any
|
262
|
+
return false if exchange != 'SMART' && other.exchange != 'SMART' &&
|
263
|
+
exchange && other.exchange && exchange != other.exchange
|
264
|
+
|
265
|
+
# Comparison for Bonds and Options
|
266
|
+
if sec_type == SECURITY_TYPES[:bond] || sec_type == SECURITY_TYPES[:option]
|
267
|
+
return false if right != other.right || strike != other.strike
|
268
|
+
return false if multiplier && other.multiplier && multiplier != other.multiplier
|
269
|
+
return false if expiry[0..5] != other.expiry[0..5]
|
270
|
+
return false unless expiry[6..7] == other.expiry[6..7] ||
|
271
|
+
expiry[6..7].empty? || other.expiry[6..7].empty?
|
272
|
+
end
|
273
|
+
|
274
|
+
# All else being equal...
|
275
|
+
sec_type == other.sec_type
|
276
|
+
end
|
277
|
+
|
278
|
+
def to_s
|
279
|
+
"<Contract: " + instance_variables.map do |key|
|
280
|
+
value = send(key[1..-1])
|
281
|
+
" #{key}=#{value}" unless value.nil? || value == '' || value == 0
|
282
|
+
end.compact.join(',') + " >"
|
283
|
+
end
|
284
|
+
|
285
|
+
def to_human
|
286
|
+
"<Contract: " + [symbol, sec_type, expiry, strike, right, exchange, currency].join("-") + ">"
|
287
|
+
end
|
288
|
+
|
289
|
+
def to_short
|
290
|
+
"#{symbol}#{expiry}#{strike}#{right}#{exchange}#{currency}"
|
291
|
+
end
|
292
|
+
|
293
|
+
end # class Contract
|
294
|
+
end # module Contracts
|
295
|
+
end # module Models
|
296
|
+
end # module IB
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'ib-ruby/models/contract'
|
1
|
+
require 'ib-ruby/models/contracts/contract'
|
2
2
|
|
3
3
|
module IB
|
4
4
|
module Models
|
5
|
-
|
5
|
+
module Contracts
|
6
6
|
class Option < Contract
|
7
7
|
|
8
8
|
# For Options, this is contract's OSI (Option Symbology Initiative) name/code
|
@@ -52,8 +52,6 @@ module IB
|
|
52
52
|
"<Option: " + [symbol, expiry, right, strike, exchange, currency].join("-") + ">"
|
53
53
|
end
|
54
54
|
end # class Option
|
55
|
-
|
56
|
-
TYPES[IB::SECURITY_TYPES[:option]] = Option
|
57
55
|
end # class Contract
|
58
56
|
end # module Models
|
59
57
|
end # module IB
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module IB
|
2
|
+
module Models
|
3
|
+
module Contracts
|
4
|
+
end
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'ib-ruby/models/contracts/contract'
|
9
|
+
require 'ib-ruby/models/contracts/option'
|
10
|
+
require 'ib-ruby/models/contracts/bag'
|
11
|
+
|
12
|
+
module IB
|
13
|
+
module Models
|
14
|
+
# This module contains Contract subclasses
|
15
|
+
module Contracts
|
16
|
+
# Specialized Contract subclasses representing different security types
|
17
|
+
TYPES = Hash.new(Contract)
|
18
|
+
TYPES[IB::SECURITY_TYPES[:bag]] = Bag
|
19
|
+
TYPES[IB::SECURITY_TYPES[:option]] = Option
|
20
|
+
|
21
|
+
# Returns concrete subclass for this sec_type, or default Contract
|
22
|
+
def [] sec_type
|
23
|
+
TYPES[sec_type]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -35,7 +35,7 @@ module IB
|
|
35
35
|
def to_s
|
36
36
|
"<Execution #{time}: #{side} #{shares} @ #{price} on #{exchange}, " +
|
37
37
|
"cumulative: #{cumulative_quantity} @ #{average_price}, " +
|
38
|
-
"
|
38
|
+
"order: #{order_id}/#{perm_id}#{order_ref}, exec: #{exec_id}>"
|
39
39
|
end
|
40
40
|
end # Execution
|
41
41
|
end # module Models
|
data/lib/ib-ruby/models/order.rb
CHANGED
@@ -316,16 +316,9 @@ module IB
|
|
316
316
|
:min_commission,
|
317
317
|
:max_commission,
|
318
318
|
:warning_text, # String: Displays a warning message if warranted.
|
319
|
-
|
320
|
-
#
|
321
|
-
:
|
322
|
-
|
323
|
-
# String: Shows the impact the order would have on your maintenance margin.
|
324
|
-
:maint_margin => proc { |val| self[:maint_margin] = filter_max val },
|
325
|
-
|
326
|
-
# String: Shows the impact the order would have on your equity with loan value.
|
327
|
-
:equity_with_loan => proc { |val| self[:equity_with_loan] = filter_max val }
|
328
|
-
|
319
|
+
:init_margin, # Float: The impact the order would have on your initial margin.
|
320
|
+
:maint_margin, # Float: The impact the order would have on your maintenance margin.
|
321
|
+
:equity_with_loan # Float: The impact the order would have on your equity
|
329
322
|
|
330
323
|
# Returned in OpenOrder for Bag Contracts
|
331
324
|
# public Vector<OrderComboLeg> m_orderComboLegs
|
@@ -333,11 +326,6 @@ module IB
|
|
333
326
|
alias order_combo_legs leg_prices
|
334
327
|
alias smart_combo_routing_params combo_params
|
335
328
|
|
336
|
-
# IB uses weird String with Java Double.MAX_VALUE to indicate no value here
|
337
|
-
def filter_max val
|
338
|
-
val == "1.7976931348623157E308" ? nil : val.to_f
|
339
|
-
end
|
340
|
-
|
341
329
|
DEFAULT_PROPS = {:aux_price => 0.0,
|
342
330
|
:parent_id => 0,
|
343
331
|
:tif => 'DAY',
|
@@ -465,14 +453,15 @@ module IB
|
|
465
453
|
# Order comparison
|
466
454
|
def == other
|
467
455
|
perm_id && other.perm_id && perm_id == other.perm_id ||
|
468
|
-
order_id == other.order_id && #
|
456
|
+
order_id == other.order_id && # ((p __LINE__)||true) &&
|
469
457
|
(client_id == other.client_id || client_id == 0 || other.client_id == 0) &&
|
470
458
|
parent_id == other.parent_id &&
|
471
459
|
tif == other.tif &&
|
472
460
|
action == other.action &&
|
473
461
|
order_type == other.order_type &&
|
474
462
|
total_quantity == other.total_quantity &&
|
475
|
-
limit_price == other.limit_price
|
463
|
+
(limit_price == other.limit_price || # TODO Floats should be Decimals!
|
464
|
+
(limit_price - other.limit_price).abs < 0.00001) &&
|
476
465
|
aux_price == other.aux_price &&
|
477
466
|
outside_rth == other.outside_rth &&
|
478
467
|
origin == other.origin &&
|
data/lib/ib-ruby/models.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module IB
|
2
2
|
module Models
|
3
|
+
require 'ib-ruby/models/contracts'
|
4
|
+
# Flatten namespace (IB::Models::Option instead of IB::Models::Contracts::Option)
|
5
|
+
include Contracts
|
6
|
+
|
7
|
+
require 'ib-ruby/models/order'
|
8
|
+
require 'ib-ruby/models/combo_leg'
|
9
|
+
require 'ib-ruby/models/execution'
|
10
|
+
require 'ib-ruby/models/bar'
|
11
|
+
|
3
12
|
end
|
4
|
-
Datatypes = Models # Legacy alias
|
5
13
|
end
|
6
14
|
|
7
|
-
require 'ib-ruby/models/order'
|
8
|
-
require 'ib-ruby/models/contract'
|
9
|
-
require 'ib-ruby/models/combo_leg'
|
10
|
-
require 'ib-ruby/models/execution'
|
11
|
-
require 'ib-ruby/models/bar'
|
12
|
-
|
@@ -7,65 +7,65 @@ module IB
|
|
7
7
|
# IDEAL is for smaller orders, and has wider spreads/slower execution... generally
|
8
8
|
# used for smaller currency conversions.
|
9
9
|
Forex = {
|
10
|
-
:audusd =>
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
:audusd => IB::Contract.new(:symbol => "AUD",
|
11
|
+
:exchange => "IDEALPRO",
|
12
|
+
:currency => "USD",
|
13
|
+
:sec_type => SECURITY_TYPES[:forex],
|
14
|
+
:description => "AUDUSD"),
|
15
15
|
|
16
|
-
:gbpusd =>
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
:gbpusd => IB::Contract.new(:symbol => "GBP",
|
17
|
+
:exchange => "IDEALPRO",
|
18
|
+
:currency => "USD",
|
19
|
+
:sec_type => SECURITY_TYPES[:forex],
|
20
|
+
:description => "GBPUSD"),
|
21
21
|
|
22
|
-
:euraud =>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
:euraud => IB::Contract.new(:symbol => "EUR",
|
23
|
+
:exchange => "IDEALPRO",
|
24
|
+
:currency => "AUD",
|
25
|
+
:sec_type => SECURITY_TYPES[:forex],
|
26
|
+
:description => "EURAUD"),
|
27
27
|
|
28
|
-
:eurgbp =>
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
:eurgbp => IB::Contract.new(:symbol => "EUR",
|
29
|
+
:exchange => "IDEALPRO",
|
30
|
+
:currency => "GBP",
|
31
|
+
:sec_type => SECURITY_TYPES[:forex],
|
32
|
+
:description => "EURGBP"),
|
33
33
|
|
34
|
-
:eurjpy =>
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
:eurjpy => IB::Contract.new(:symbol => "EUR",
|
35
|
+
:exchange => "IDEALPRO",
|
36
|
+
:currency => "JPY",
|
37
|
+
:sec_type => SECURITY_TYPES[:forex],
|
38
|
+
:description => "EURJPY"),
|
39
39
|
|
40
|
-
:eurusd =>
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
:eurusd => IB::Contract.new(:symbol => "EUR",
|
41
|
+
:exchange => "IDEALPRO",
|
42
|
+
:currency => "USD",
|
43
|
+
:sec_type => SECURITY_TYPES[:forex],
|
44
|
+
:description => "EURUSD"),
|
45
45
|
|
46
|
-
:eurcad =>
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
:eurcad => IB::Contract.new(:symbol => "EUR",
|
47
|
+
:exchange => "IDEALPRO",
|
48
|
+
:currency => "CAD",
|
49
|
+
:sec_type => SECURITY_TYPES[:forex],
|
50
|
+
:description => "EURCAD"),
|
51
51
|
|
52
|
-
:usdchf =>
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
:usdchf => IB::Contract.new(:symbol => "USD",
|
53
|
+
:exchange => "IDEALPRO",
|
54
|
+
:currency => "CHF",
|
55
|
+
:sec_type => SECURITY_TYPES[:forex],
|
56
|
+
:description => "USDCHF"),
|
57
57
|
|
58
|
-
:usdcad =>
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
:usdcad => IB::Contract.new(:symbol => "USD",
|
59
|
+
:exchange => "IDEALPRO",
|
60
|
+
:currency => "CAD",
|
61
|
+
:sec_type => SECURITY_TYPES[:forex],
|
62
|
+
:description => "USDCAD"),
|
63
63
|
|
64
|
-
:usdjpy =>
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
:usdjpy => IB::Contract.new(:symbol => "USD",
|
65
|
+
:exchange => "IDEALPRO",
|
66
|
+
:currency => "JPY",
|
67
|
+
:sec_type => SECURITY_TYPES[:forex],
|
68
|
+
:description => "USDJPY")
|
69
69
|
}
|
70
70
|
end
|
71
71
|
end
|