ib-ruby 0.5.0 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|