ib-ruby 0.5.0 → 0.5.2
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 +8 -0
- data/README.rdoc +6 -6
- data/VERSION +1 -1
- data/bin/contract_details +3 -3
- data/bin/depth_of_market +6 -3
- data/bin/historic_data +8 -8
- data/bin/historic_data_cli +23 -46
- data/bin/market_data +2 -7
- data/bin/time_and_sales +1 -2
- data/lib/ib-ruby/connection.rb +59 -38
- data/lib/ib-ruby/messages/incoming.rb +34 -18
- data/lib/ib-ruby/messages/outgoing.rb +83 -133
- data/lib/ib-ruby/models/contract.rb +17 -18
- data/lib/ib-ruby/models/order.rb +69 -1
- data/lib/ib-ruby/socket.rb +1 -1
- data/lib/ib-ruby/symbols/options.rb +4 -4
- data/spec/ib-ruby/connection_spec.rb +60 -33
- data/spec/ib-ruby/models/contract_spec.rb +2 -2
- metadata +101 -101
@@ -83,7 +83,7 @@ module IB
|
|
83
83
|
end
|
84
84
|
|
85
85
|
# Macro that defines short message classes using a one-liner
|
86
|
-
def self.def_message message_id, *keys, &
|
86
|
+
def self.def_message message_id, *keys, &to_human
|
87
87
|
base = keys.first.is_a?(Class) ? keys.shift : AbstractMessage
|
88
88
|
Class.new(base) do
|
89
89
|
@message_id = message_id
|
@@ -93,7 +93,7 @@ module IB
|
|
93
93
|
load_map *keys
|
94
94
|
end
|
95
95
|
|
96
|
-
define_method(:to_human, &
|
96
|
+
define_method(:to_human, &to_human) if to_human
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -152,7 +152,7 @@ module IB
|
|
152
152
|
NewsBulletins =
|
153
153
|
def_message 14, [:id, :int], # unique incrementing bulletin ID.
|
154
154
|
[:type, :int], # Type of bulletin. Valid values include:
|
155
|
-
# 1 =
|
155
|
+
# 1 = Regular news bulletin
|
156
156
|
# 2 = Exchange no longer available for trading
|
157
157
|
# 3 = Exchange is available for trading
|
158
158
|
[:text, :string], # The bulletin's message text.
|
@@ -172,7 +172,7 @@ module IB
|
|
172
172
|
# FA configuration information.
|
173
173
|
|
174
174
|
# Receives an XML document that describes the valid parameters that a scanner
|
175
|
-
# subscription can have.
|
175
|
+
# subscription can have (for outgoing RequestScannerSubscription message).
|
176
176
|
ScannerParameters = def_message 19, [:xml, :string]
|
177
177
|
|
178
178
|
# Receives the current system time on the server side.
|
@@ -287,10 +287,11 @@ module IB
|
|
287
287
|
@message_id = 21
|
288
288
|
|
289
289
|
# Read @data[key] if it was computed (received value above limit)
|
290
|
-
# Leave @data[key] nil if received value below limit ("not yet computed"
|
290
|
+
# Leave @data[key] nil if received value below limit ("not yet computed")
|
291
291
|
def read_computed key, limit
|
292
|
-
value = @socket.read_decimal
|
293
|
-
|
292
|
+
value = @socket.read_decimal
|
293
|
+
# limit is the "not yet computed" indicator
|
294
|
+
@data[key] = value <= limit ? nil : value
|
294
295
|
end
|
295
296
|
|
296
297
|
def load
|
@@ -298,14 +299,14 @@ module IB
|
|
298
299
|
|
299
300
|
@data[:id] = @socket.read_int # ticker_id
|
300
301
|
@data[:tick_type] = @socket.read_int
|
301
|
-
read_computed :implied_volatility,
|
302
|
-
read_computed :delta, -
|
303
|
-
read_computed :option_price,
|
304
|
-
read_computed :pv_dividend,
|
305
|
-
read_computed :gamma, -
|
306
|
-
read_computed :vega, -
|
307
|
-
read_computed :theta, -
|
308
|
-
read_computed :under_price,
|
302
|
+
read_computed :implied_volatility, -1 #-1 is the "not yet computed" indicator
|
303
|
+
read_computed :delta, -2 # -2 is the "not yet computed" indicator
|
304
|
+
read_computed :option_price, -1 # -1 is the "not yet computed" indicator
|
305
|
+
read_computed :pv_dividend, -1 # -1 is the "not yet computed" indicator
|
306
|
+
read_computed :gamma, -2 # -2 is the "not yet computed" indicator
|
307
|
+
read_computed :vega, -2 # -2 is the "not yet computed" indicator
|
308
|
+
read_computed :theta, -2 # -2 is the "not yet computed" indicator
|
309
|
+
read_computed :under_price, -1 # -1 is the "not yet computed" indicator
|
309
310
|
end
|
310
311
|
|
311
312
|
def to_human
|
@@ -536,6 +537,7 @@ module IB
|
|
536
537
|
:order_types => @socket.read_string,
|
537
538
|
:valid_exchanges => @socket.read_string,
|
538
539
|
:price_magnifier => @socket.read_int,
|
540
|
+
|
539
541
|
:under_con_id => @socket.read_int,
|
540
542
|
:long_name => @socket.read_string,
|
541
543
|
:primary_exchange => @socket.read_string,
|
@@ -548,6 +550,7 @@ module IB
|
|
548
550
|
:liquid_hours => @socket.read_string
|
549
551
|
end
|
550
552
|
end # ContractData
|
553
|
+
ContractDetails = ContractData
|
551
554
|
|
552
555
|
class ExecutionData < AbstractMessage
|
553
556
|
@message_id = 11
|
@@ -587,11 +590,24 @@ module IB
|
|
587
590
|
end # ExecutionData
|
588
591
|
|
589
592
|
# HistoricalData contains following @data:
|
593
|
+
# General:
|
590
594
|
# :id - The ID of the request to which this is responding
|
591
|
-
# :count - Number of data points returned (size of :results).
|
595
|
+
# :count - Number of Historical data points returned (size of :results).
|
592
596
|
# :results - an Array of Historical Data Bars
|
593
|
-
# :start_date
|
594
|
-
# :end_date
|
597
|
+
# :start_date - beginning of returned Historical data period
|
598
|
+
# :end_date - end of returned Historical data period
|
599
|
+
# Each returned Bar in @data[:results] Array contains this data:
|
600
|
+
# :date - The date-time stamp of the start of the bar. The format is
|
601
|
+
# determined by the RequestHistoricalData formatDate parameter.
|
602
|
+
# :open - The bar opening price.
|
603
|
+
# :high - The high price during the time covered by the bar.
|
604
|
+
# :low - The low price during the time covered by the bar.
|
605
|
+
# :close - The bar closing price.
|
606
|
+
# :volume - The volume during the time covered by the bar.
|
607
|
+
# :trades - When TRADES historical data is returned, represents number of trades
|
608
|
+
# that occurred during the time period the bar covers
|
609
|
+
# :wap - The weighted average price during the time covered by the bar.
|
610
|
+
# :has_gaps - Whether or not there are gaps in the data.
|
595
611
|
class HistoricalData < AbstractMessage
|
596
612
|
@message_id = 17
|
597
613
|
|
@@ -78,16 +78,18 @@ module IB
|
|
78
78
|
CancelNewsBulletins = def_message 13
|
79
79
|
RequestAllOpenOrders = def_message 16
|
80
80
|
RequestManagedAccounts = def_message 17
|
81
|
+
# Requests an XML document that describes the valid parameters that a scanner
|
82
|
+
# subscription can have (for outgoing RequestScannerSubscription message).
|
81
83
|
RequestScannerParameters = def_message 24
|
82
84
|
RequestCurrentTime = def_message 49
|
83
85
|
RequestGlobalCancel = def_message 58
|
84
86
|
|
85
87
|
# Data format is: @data = { :id => ticker_id}
|
86
|
-
CancelScannerSubscription = def_message 23
|
87
88
|
CancelMarketData = def_message 2
|
89
|
+
CancelMarketDepth = def_message 11
|
90
|
+
CancelScannerSubscription = def_message 23
|
88
91
|
CancelHistoricalData = def_message 25
|
89
92
|
CancelRealTimeBars = def_message 51
|
90
|
-
CancelMarketDepth = def_message 11
|
91
93
|
|
92
94
|
# Data format is: @data = { :id => request_id }
|
93
95
|
CancelFundamentalData = def_message 53
|
@@ -112,53 +114,84 @@ module IB
|
|
112
114
|
RequestFA = def_message 18, 1, :fa_data_type
|
113
115
|
# data = { :fa_data_type => int, :xml => String }
|
114
116
|
ReplaceFA = def_message 19, 1, :fa_data_type, :xml
|
115
|
-
|
116
|
-
#
|
117
|
-
|
118
|
-
# to empty ('') for a standard account. }
|
119
|
-
class RequestAccountData < AbstractMessage
|
120
|
-
@message_id = 6
|
121
|
-
@version = 2
|
122
|
-
|
123
|
-
def encode
|
124
|
-
[super,
|
125
|
-
@data[:subscribe],
|
126
|
-
@data[:account_code] || '']
|
127
|
-
end
|
128
|
-
end
|
117
|
+
# @data = { :subscribe => boolean,
|
118
|
+
# :account_code => Advisor accounts only. Empty ('') for a standard account. }
|
119
|
+
RequestAccountData = def_message 6, 2, :subscribe, :account_code
|
129
120
|
RequestAccountUpdates = RequestAccountData
|
130
121
|
|
131
122
|
|
132
123
|
### Defining (complex) Outgoing Message classes for IB:
|
133
124
|
|
134
|
-
#
|
125
|
+
# Start receiving market scanner results through the ScannerData messages.
|
126
|
+
# @data = { :id => ticker_id (int),
|
127
|
+
# :number_of_rows => int: number of rows of data to return for a query.
|
128
|
+
# :instrument => The instrument type for the scan. Values include
|
129
|
+
# 'STK', - US stocks
|
130
|
+
# 'STOCK.HK' - Asian stocks
|
131
|
+
# 'STOCK.EU' - European stocks
|
132
|
+
# :location_code => Legal Values include:
|
133
|
+
# � STK.US - US stocks
|
134
|
+
# � STK.US.MAJOR - US stocks (without pink sheet)
|
135
|
+
# � STK.US.MINOR - US stocks (only pink sheet)
|
136
|
+
# � STK.HK.SEHK - Hong Kong stocks
|
137
|
+
# � STK.HK.ASX - Australian Stocks
|
138
|
+
# � STK.EU - European stocks
|
139
|
+
# :scan_code => The type of the scan, such as HIGH_OPT_VOLUME_PUT_CALL_RATIO.
|
140
|
+
# :above_price => double: Only contracts with a price above this value.
|
141
|
+
# :below_price => double: Only contracts with a price below this value.
|
142
|
+
# :above_volume => int: Only contracts with a volume above this value.
|
143
|
+
# :market_cap_above => double: Only contracts with a market cap above this
|
144
|
+
# :market_cap_below => double: Only contracts with a market cap below this value.
|
145
|
+
# :moody_rating_above => Only contracts with a Moody rating above this value.
|
146
|
+
# :moody_rating_below => Only contracts with a Moody rating below this value.
|
147
|
+
# :sp_rating_above => Only contracts with an S&P rating above this value.
|
148
|
+
# :sp_rating_below => Only contracts with an S&P rating below this value.
|
149
|
+
# :maturity_date_above => Only contracts with a maturity date later than this
|
150
|
+
# :maturity_date_below => Only contracts with a maturity date earlier than this
|
151
|
+
# :coupon_rate_above => double: Only contracts with a coupon rate above this
|
152
|
+
# :coupon_rate_below => double: Only contracts with a coupon rate below this
|
153
|
+
# :exclude_convertible => Exclude convertible bonds.
|
154
|
+
# :scanner_setting_pairs => Used with the scan_code to help further narrow your query.
|
155
|
+
# Scanner Setting Pairs are delimited by slashes, making
|
156
|
+
# this parameter open ended. Example is "Annual,true" -
|
157
|
+
# when used with 'Top Option Implied Vol % Gainers' scan
|
158
|
+
# would return annualized volatilities.
|
159
|
+
# :average_option_volume_above => int: Only contracts with average volume above this
|
160
|
+
# :stock_type_filter => Valid values are:
|
161
|
+
# 'ALL' (excludes nothing)
|
162
|
+
# 'STOCK' (excludes ETFs)
|
163
|
+
# 'ETF' (includes ETFs) }
|
164
|
+
# ------------
|
165
|
+
# To learn all valid parameter values that a scanner subscription can have,
|
166
|
+
# first subscribe to ScannerParameters and send RequestScannerParameters message.
|
167
|
+
# Available scanner parameters values will be listed in received XML document.
|
135
168
|
class RequestScannerSubscription < AbstractMessage
|
136
169
|
@message_id = 22
|
137
170
|
@version = 3
|
138
171
|
|
139
172
|
def encode
|
140
173
|
[super,
|
141
|
-
@data[:
|
142
|
-
@data[:
|
143
|
-
@data[:
|
144
|
-
@data[:
|
145
|
-
@data[:
|
146
|
-
@data[:
|
147
|
-
@data[:
|
148
|
-
@data[:
|
149
|
-
@data[:
|
150
|
-
@data[:
|
151
|
-
@data[:
|
152
|
-
@data[:
|
153
|
-
@data[:
|
154
|
-
@data[:
|
155
|
-
@data[:
|
156
|
-
@data[:
|
157
|
-
@data[:
|
158
|
-
@data[:
|
159
|
-
@data[:
|
160
|
-
@data[:
|
161
|
-
@data[:
|
174
|
+
@data[:number_of_rows] || -1, # was: EOL,
|
175
|
+
@data[:instrument],
|
176
|
+
@data[:location_code],
|
177
|
+
@data[:scan_code],
|
178
|
+
@data[:above_price] || EOL,
|
179
|
+
@data[:below_price] || EOL,
|
180
|
+
@data[:above_volume] || EOL,
|
181
|
+
@data[:market_cap_above] || EOL,
|
182
|
+
@data[:market_cap_below] || EOL,
|
183
|
+
@data[:moody_rating_above],
|
184
|
+
@data[:moody_rating_below],
|
185
|
+
@data[:sp_rating_above],
|
186
|
+
@data[:sp_rating_below],
|
187
|
+
@data[:maturity_date_above],
|
188
|
+
@data[:maturity_date_below],
|
189
|
+
@data[:coupon_rate_above] || EOL,
|
190
|
+
@data[:coupon_rate_below] || EOL,
|
191
|
+
@data[:exclude_convertible],
|
192
|
+
@data[:average_option_volume_above] || EOL, # ?
|
193
|
+
@data[:scanner_setting_pairs],
|
194
|
+
@data[:stock_type_filter]
|
162
195
|
]
|
163
196
|
end
|
164
197
|
end # RequestScannerSubscription
|
@@ -198,8 +231,7 @@ module IB
|
|
198
231
|
@data[:tick_list]
|
199
232
|
end
|
200
233
|
[super,
|
201
|
-
@data[:contract].con_id,
|
202
|
-
@data[:contract].serialize,
|
234
|
+
@data[:contract].serialize_long(:con_id),
|
203
235
|
@data[:contract].serialize_combo_legs,
|
204
236
|
@data[:contract].serialize_under_comp,
|
205
237
|
tick_list,
|
@@ -290,8 +322,7 @@ module IB
|
|
290
322
|
@data[:contract] : Models::Contract.from_ib_ruby(@data[:contract])
|
291
323
|
|
292
324
|
[super,
|
293
|
-
contract.
|
294
|
-
contract.include_expired,
|
325
|
+
contract.serialize_long(:include_expired),
|
295
326
|
@data[:end_date_time],
|
296
327
|
@data[:bar_size],
|
297
328
|
@data[:duration],
|
@@ -329,7 +360,7 @@ module IB
|
|
329
360
|
@data[:contract] : Models::Contract.from_ib_ruby(@data[:contract])
|
330
361
|
|
331
362
|
[super,
|
332
|
-
contract.
|
363
|
+
contract.serialize_long,
|
333
364
|
@data[:bar_size],
|
334
365
|
@data[:what_to_show].to_s.upcase,
|
335
366
|
@data[:use_rth]]
|
@@ -343,11 +374,7 @@ module IB
|
|
343
374
|
|
344
375
|
def encode
|
345
376
|
[super,
|
346
|
-
@data[:contract].con_id,
|
347
|
-
@data[:contract].serialize(:short),
|
348
|
-
@data[:contract].include_expired,
|
349
|
-
@data[:contract].sec_id_type,
|
350
|
-
@data[:contract].sec_id]
|
377
|
+
@data[:contract].serialize_short(:con_id, :include_expired, :sec_id)]
|
351
378
|
end
|
352
379
|
end # RequestContractData
|
353
380
|
RequestContractDetails = RequestContractData # alias
|
@@ -359,7 +386,7 @@ module IB
|
|
359
386
|
|
360
387
|
def encode
|
361
388
|
[super,
|
362
|
-
@data[:contract].
|
389
|
+
@data[:contract].serialize_short,
|
363
390
|
@data[:num_rows]]
|
364
391
|
end
|
365
392
|
end # RequestMarketDepth
|
@@ -384,7 +411,7 @@ module IB
|
|
384
411
|
|
385
412
|
def encode
|
386
413
|
[super,
|
387
|
-
@data[:contract].
|
414
|
+
@data[:contract].serialize_short,
|
388
415
|
@data[:exercise_action],
|
389
416
|
@data[:exercise_quantity],
|
390
417
|
@data[:account],
|
@@ -398,76 +425,10 @@ module IB
|
|
398
425
|
class PlaceOrder < AbstractMessage
|
399
426
|
@message_id = 3
|
400
427
|
@version = 31
|
401
|
-
# int VERSION = (m_serverVersion < MIN_SERVER_VER_NOT_HELD) ? 27 : 31;
|
402
428
|
|
403
429
|
def encode
|
404
430
|
[super,
|
405
|
-
@data[:contract]
|
406
|
-
@data[:contract].sec_id_type, # Unimplemented?
|
407
|
-
@data[:contract].sec_id, # Unimplemented?
|
408
|
-
@data[:order].action, # send main order fields
|
409
|
-
@data[:order].total_quantity,
|
410
|
-
@data[:order].order_type,
|
411
|
-
@data[:order].limit_price,
|
412
|
-
@data[:order].aux_price,
|
413
|
-
@data[:order].tif, # send extended order fields
|
414
|
-
@data[:order].oca_group,
|
415
|
-
@data[:order].account,
|
416
|
-
@data[:order].open_close,
|
417
|
-
@data[:order].origin,
|
418
|
-
@data[:order].order_ref,
|
419
|
-
@data[:order].transmit,
|
420
|
-
@data[:order].parent_id,
|
421
|
-
@data[:order].block_order,
|
422
|
-
@data[:order].sweep_to_fill,
|
423
|
-
@data[:order].display_size,
|
424
|
-
@data[:order].trigger_method,
|
425
|
-
@data[:order].outside_rth, # was: ignore_rth
|
426
|
-
@data[:order].hidden,
|
427
|
-
@data[:contract].serialize_combo_legs(:long),
|
428
|
-
'', # send deprecated shares_allocation field
|
429
|
-
@data[:order].discretionary_amount,
|
430
|
-
@data[:order].good_after_time,
|
431
|
-
@data[:order].good_till_date,
|
432
|
-
@data[:order].fa_group,
|
433
|
-
@data[:order].fa_method,
|
434
|
-
@data[:order].fa_percentage,
|
435
|
-
@data[:order].fa_profile,
|
436
|
-
# Institutional short sale slot fields:
|
437
|
-
@data[:order].short_sale_slot, # 0 only for retail, 1 or 2 for institution
|
438
|
-
@data[:order].designated_location, # only populate when short_sale_slot == 2
|
439
|
-
@data[:order].oca_type,
|
440
|
-
@data[:order].rule_80a,
|
441
|
-
@data[:order].settling_firm,
|
442
|
-
@data[:order].all_or_none,
|
443
|
-
@data[:order].min_quantity || EOL,
|
444
|
-
@data[:order].percent_offset || EOL,
|
445
|
-
@data[:order].etrade_only,
|
446
|
-
@data[:order].firm_quote_only,
|
447
|
-
@data[:order].nbbo_price_cap || EOL,
|
448
|
-
@data[:order].auction_strategy || EOL,
|
449
|
-
@data[:order].starting_price || EOL,
|
450
|
-
@data[:order].stock_ref_price || EOL,
|
451
|
-
@data[:order].delta || EOL,
|
452
|
-
@data[:order].stock_range_lower || EOL,
|
453
|
-
@data[:order].stock_range_upper || EOL,
|
454
|
-
@data[:order].override_percentage_constraints,
|
455
|
-
@data[:order].volatility || EOL, # Volatility orders
|
456
|
-
@data[:order].volatility_type || EOL, # Volatility orders
|
457
|
-
@data[:order].delta_neutral_order_type, # Volatility orders
|
458
|
-
@data[:order].delta_neutral_aux_price || EOL, # Volatility orders
|
459
|
-
@data[:order].continuous_update, # Volatility orders
|
460
|
-
@data[:order].reference_price_type || EOL, # Volatility orders
|
461
|
-
@data[:order].trail_stop_price || EOL, # TRAIL_STOP_LIMIT stop price
|
462
|
-
@data[:order].scale_init_level_size || EOL, # Scale Orders
|
463
|
-
@data[:order].scale_subs_level_size || EOL, # Scale Orders
|
464
|
-
@data[:order].scale_price_increment || EOL, # Scale Orders
|
465
|
-
@data[:order].clearing_account,
|
466
|
-
@data[:order].clearing_intent,
|
467
|
-
@data[:order].not_held,
|
468
|
-
@data[:contract].serialize_under_comp,
|
469
|
-
@data[:order].serialize_algo,
|
470
|
-
@data[:order].what_if]
|
431
|
+
@data[:order].serialize_with(@data[:contract])]
|
471
432
|
end
|
472
433
|
end # PlaceOrder
|
473
434
|
|
@@ -488,7 +449,6 @@ module IB
|
|
488
449
|
@version = 3
|
489
450
|
|
490
451
|
def encode
|
491
|
-
|
492
452
|
[super,
|
493
453
|
@data[:client_id],
|
494
454
|
@data[:acct_code],
|
@@ -497,7 +457,7 @@ module IB
|
|
497
457
|
@data[:sec_type],
|
498
458
|
@data[:exchange],
|
499
459
|
@data[:side]]
|
500
|
-
end
|
460
|
+
end
|
501
461
|
end # RequestExecutions
|
502
462
|
|
503
463
|
# Send this message to receive Reuters global fundamental data. There must be
|
@@ -506,22 +466,14 @@ module IB
|
|
506
466
|
# data = { :id => int: :request_id,
|
507
467
|
# :contract => Contract,
|
508
468
|
# :report_type => String: one of the following:
|
509
|
-
#
|
510
|
-
# Financial Statements
|
511
|
-
# Summary
|
512
|
-
# }
|
469
|
+
# 'Estimates', 'Financial Statements', 'Summary' }
|
513
470
|
class RequestFundamentalData < AbstractMessage
|
514
471
|
@message_id = 52
|
515
472
|
|
516
473
|
def encode
|
517
474
|
[super,
|
518
475
|
@data[:request_id],
|
519
|
-
@data[:contract].
|
520
|
-
@data[:contract].sec_type,
|
521
|
-
@data[:contract].exchange,
|
522
|
-
@data[:contract].primary_exchange,
|
523
|
-
@data[:contract].currency,
|
524
|
-
@data[:contract].local_symbol,
|
476
|
+
@data[:contract].serialize(:primary_exchange), # Minimal serialization set
|
525
477
|
@data[:report_type]]
|
526
478
|
end
|
527
479
|
end # RequestFundamentalData
|
@@ -534,8 +486,7 @@ module IB
|
|
534
486
|
def encode
|
535
487
|
[super,
|
536
488
|
@data[:request_id],
|
537
|
-
@data[:contract].con_id,
|
538
|
-
@data[:contract].serialize,
|
489
|
+
@data[:contract].serialize_long(:con_id),
|
539
490
|
@data[:option_price],
|
540
491
|
@data[:under_price]]
|
541
492
|
end
|
@@ -551,8 +502,7 @@ module IB
|
|
551
502
|
def encode
|
552
503
|
[super,
|
553
504
|
@data[:request_id],
|
554
|
-
@data[:contract].con_id,
|
555
|
-
@data[:contract].serialize,
|
505
|
+
@data[:contract].serialize_long(:con_id),
|
556
506
|
@data[:volatility],
|
557
507
|
@data[:under_price]]
|
558
508
|
end
|
@@ -165,30 +165,29 @@ module IB
|
|
165
165
|
@strike = 0
|
166
166
|
end
|
167
167
|
|
168
|
-
# This returns an Array of data from the given contract
|
168
|
+
# This returns an Array of data from the given contract.
|
169
169
|
# Different messages serialize contracts differently. Go figure.
|
170
|
-
# Note that it does
|
171
|
-
def serialize(
|
172
|
-
[
|
170
|
+
# Note that it does NOT include the combo legs.
|
171
|
+
def serialize(*fields)
|
172
|
+
[(fields.include?(:con_id) ? [con_id] : []),
|
173
|
+
symbol,
|
173
174
|
sec_type,
|
174
|
-
expiry,
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
175
|
+
(fields.include?(:option) ? [expiry, strike, right, multiplier] : []),
|
176
|
+
exchange,
|
177
|
+
(fields.include?(:primary_exchange) ? [primary_exchange] : []),
|
178
|
+
currency,
|
179
|
+
local_symbol,
|
180
|
+
(fields.include?(:sec_id) ? [sec_id_type, sec_id] : []),
|
181
|
+
(fields.include?(:include_expired) ? [include_expired] : []),
|
182
|
+
].flatten
|
182
183
|
end
|
183
184
|
|
184
|
-
|
185
|
-
|
186
|
-
serialize(:long)
|
185
|
+
def serialize_long(*fields)
|
186
|
+
serialize(:option, :primary_exchange, *fields)
|
187
187
|
end
|
188
188
|
|
189
|
-
|
190
|
-
|
191
|
-
serialize(:short)
|
189
|
+
def serialize_short(*fields)
|
190
|
+
serialize(:option, *fields)
|
192
191
|
end
|
193
192
|
|
194
193
|
# This produces a string uniquely identifying this contract, in the format used
|