ib-ruby 0.8.5 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -20,6 +20,7 @@ tmtags
20
20
  *.iml
21
21
 
22
22
  ## PROJECT::GENERAL
23
+ config/flex.yml
23
24
  coverage
24
25
  data
25
26
  rdoc
data/HISTORY CHANGED
@@ -201,3 +201,7 @@
201
201
  == 0.8.5 / 2012-08-11
202
202
 
203
203
  * Complete Rails Engine, TWS 929 support
204
+
205
+ == 0.9.0 / 2012-10-31
206
+
207
+ * Support for API 967 final
data/README.md CHANGED
@@ -70,7 +70,8 @@ other API implementations. The choice is yours.
70
70
  | 0.5.21 | 918-920 | 965 |
71
71
  | 0.6.1 | 921-923 | 966 |
72
72
  | 0.7.1 | 924-925 | 966 |
73
- | 0.8.1+ | 926-929 | 967 |
73
+ | 0.8.1 | 926-930 | 967 beta |
74
+ | 0.9.0+ | 931-932 | 967 final |
74
75
 
75
76
  4. Start Interactive Broker's Trader Work Station or Gateway before your code
76
77
  attempts to connect to it. Note that TWS and Gateway listen to different ports,
@@ -119,23 +120,23 @@ See `lib/ib/messages` for a full list of supported incoming/outgoing messages
119
120
  and their attributes. The original TWS docs and code samples can also be found
120
121
  in `misc` directory.
121
122
 
122
- Sample scripts in `example` directory demonstrate common ib-ruby use cases. Examples
123
- show you how to access account info, print real time quotes, retrieve historic or
123
+ Sample scripts in `example` directory demonstrate common ib-ruby use cases. Examples
124
+ show you how to access account info, print real time quotes, retrieve historic or
124
125
  fundamental data, request options calculations, place, list, and cancel orders.
125
- You may also want to look into `spec/integration` directory for more scenarios,
126
+ You may also want to look into `spec/integration` directory for more scenarios,
126
127
  use cases and examples of handling IB messages.
127
128
 
128
129
  ## RAILS INTEGRATION:
129
130
 
130
131
  This gem has two operating modes: standalone and Rails-engine. If you require it in a
131
132
  Rails environment, it loads Rails engine automatically. Otherwise, it does not load any
132
- Rails integration.
133
+ Rails integration.
133
134
 
134
135
  To add ib-ruby to your Rails 3 project, follow these steps:
135
136
 
136
137
  Add to your Gemfile:
137
138
  ``` ruby
138
- gem 'ib-ruby', '~>0.8'
139
+ gem 'ib-ruby', '~>0.9'
139
140
  ```
140
141
  Add the require to your config/application.rb:
141
142
  ``` ruby
@@ -152,12 +153,12 @@ Now run:
152
153
 
153
154
  This will install ib-ruby gem and copy its migrations into your Rails apps migrations.
154
155
 
155
- You can now use or modify IB models, develop controllers and views for them in your Rails app.
156
+ You can now use or modify IB models, develop controllers and views for them in your Rails app.
156
157
 
157
158
  ## DB BACKEND:
158
159
 
159
- Even if you don't use Rails, you can still take advantage of its data persistance layer
160
- (ActiveRecord ORM). In order to use data persistance, you have to set up the database
160
+ Even if you don't use Rails, you can still take advantage of its data persistance layer
161
+ (ActiveRecord ORM). In order to use data persistance, you have to set up the database
161
162
  (SQLite recommended for simplicity) and run migrations located at gems 'db/migrate' folder.
162
163
  It is recommended that you use a gem like [standalone_migrations](https://github.com/thuss/standalone-migrations) for this.
163
164
 
@@ -169,25 +170,25 @@ You further need to:
169
170
  ```
170
171
  Only require 'ib' AFTER you've connected to DB, otherwise your Models will not
171
172
  inherit from ActiveRecord::Base and won't be persistent. If you are using Rails,
172
- you don't need IB::DB.connect part, Rails will take care of it for you.
173
+ you don't need IB::DB.connect part, Rails will take care of it for you.
173
174
 
174
175
  Now, all your IB Models are just ActiveRecords and you can save them to DB just
175
176
  like you would with Rails models.
176
177
 
177
178
  ## RUNNING TESTS:
178
179
 
179
- The gem comes with a spec suit that may be used to test ib-ruby compatibility with your
180
+ The gem comes with a spec suit that may be used to test ib-ruby compatibility with your
180
181
  specific TWS/Gateway installation. Please read 'spec/Readme.md' for more details about
181
182
  running specs.
182
183
 
183
184
  ## RUBY VERSION COMPATIBILITY:
184
185
 
185
- The library is continuously tested with JRuby 1.6.7 (ruby-1.8.7-p357-compatible mode) and
186
- JRuby head (ruby-1.9.3-p203-compatible mode). It is not JRuby-specific though, as it is currently used in a some MRI Ruby based projects. If there are any problems in any mode
186
+ The library is continuously tested with JRuby 1.6.7 (ruby-1.8.7-p357-compatible mode) and
187
+ JRuby head (ruby-1.9.3-p203-compatible mode). It is not JRuby-specific though, as it is currently used in a some MRI Ruby based projects. If there are any problems in any mode
187
188
  for either JRuby or MRI, please report an [issue](https://github.com/ib-ruby/ib-ruby/issues/new)
188
189
  and we will work on it.
189
190
 
190
- Please keep in mind that when using Ruby 1.8.7, you need to either explicitly:
191
+ Please keep in mind that when using Ruby 1.8.7, you need to either explicitly:
191
192
  ``` ruby
192
193
  require 'rubygems'
193
194
  require 'ib'
data/Rakefile CHANGED
@@ -39,7 +39,6 @@ rescue LoadError => e
39
39
  puts "gem install standalone_migrations to get db:migrate:* tasks! (Error: #{e})"
40
40
  end
41
41
 
42
-
43
42
  # rake db:redo DB=test"
44
43
  namespace :db do
45
44
  desc "Remake db from scratch: $ rake db:redo DB=test"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.5
1
+ 0.9.0
data/bin/scaffold.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # This script converts given migration file into rails scaffold command
3
+ # This script converts given migration file into a Rails scaffold command
4
4
 
5
5
  output = STDOUT
6
6
  ARGV.each do |file_name|
@@ -4,18 +4,20 @@ class AddIbExecutions < ActiveRecord::Migration
4
4
  create_table(:ib_executions) do |t|
5
5
  # TWS orders have fixed local_id of 0 AND client id of 0
6
6
  t.references :order
7
- t.integer :local_id # TWS orders have a fixed order id of 0
8
- t.integer :client_id # Id of the client that placed the order
9
- t.integer :perm_id # Permanent order id, remains the same over TWS sessions
10
- t.string :order_ref # Order reference
11
- t.string :exec_id # Unique order execution id
7
+ t.integer :local_id # TWS orders have a fixed order id of 0
8
+ t.integer :client_id # Id of the client that placed the order
9
+ t.integer :perm_id # Permanent order id, remains the same over TWS sessions
10
+ t.string :order_ref # Order reference
11
+ t.string :ev_rule # Australian products only
12
+ t.float :ev_multiplier # Australian products only
13
+ t.string :exec_id # Unique order execution id
12
14
  t.string :side, :limit => 1 # Was the transaction a buy or a sale: BOT|SLD
13
15
  t.integer :quantity # The number of shares filled
14
16
  t.integer :cumulative_quantity # Cumulative quantity
15
- t.float :price # double: The order execution price
16
- t.float :average_price # double: Average price (for all executions?)
17
- t.string :exchange # Exchange that executed the order
18
- t.string :account_name # The customer account number
17
+ t.float :price # double: The order execution price
18
+ t.float :average_price # double: Average price (for all executions?)
19
+ t.string :exchange # Exchange that executed the order
20
+ t.string :account_name # The customer account number
19
21
  t.boolean :liquidation, :limit => 1 # This position to be liquidated last should the need arise
20
22
  t.string :time, :limit => 18 # String! The order execution time
21
23
  t.timestamps
@@ -24,4 +26,7 @@ class AddIbExecutions < ActiveRecord::Migration
24
26
  end
25
27
 
26
28
  __END__
27
- rails generate scaffold execution order_id:integer local_id:integer client_id:integer perm_id:integer order_ref:string exec_id:string side:string quantity:integer cumulative_quantity:integer price:float average_price:float exchange:string account_name:string liquidation:boolean time:string
29
+ rails generate scaffold execution order_id:integer local_id:integer client_id:integer
30
+ perm_id:integer order_ref:string ev_rule:string ev_multiplier:float exec_id:string
31
+ side:string quantity:integer cumulative_quantity:integer price:float average_price:float
32
+ exchange:string account_name:string liquidation:boolean time:string
@@ -34,18 +34,25 @@ class AddIbContractDetails < ActiveRecord::Migration
34
34
  t.boolean :puttable, :limit => 1 # Can be sold back to the issuer under certain conditions
35
35
  t.boolean :convertible, :limit => 1 # Can be converted to stock under certain conditions.
36
36
  t.boolean :next_option_partial, :limit => 1 # # only if bond has embedded options.
37
+ t.string :valid_next_option_date # Bonds only
38
+ t.string :valid_next_option_type # Bonds only
39
+ t.string :valid_next_option_partial # Bonds only
40
+ t.string :ev_rule # Australian non-currency products only
41
+ t.float :ev_multiplier # Australian non-currency products only
42
+ t.text :sec_id_list
37
43
  t.timestamps
38
44
  end
39
45
  end
40
46
  end
41
47
 
42
48
  __END__
43
- rails generate scaffold contract_detail contract_id:integer market_name:string
44
- trading_class:string min_tick:float price_magnifier:integer order_types:string
45
- valid_exchanges:string under_con_id:integer long_name:string contract_month:string
46
- industry:string category:string subcategory:string time_zone:string trading_hours:string
47
- liquid_hours:string cusip:string ratings:string desc_append:string bond_type:string
48
- coupon_type:string coupon:float maturity:string issue_date:string next_option_date:string
49
- next_option_type:string notes:string callable:boolean puttable:boolean convertible:boolean
50
- next_option_partial:boolean
49
+ rails generate scaffold contract_detail contract_id:integer market_name:string
50
+ trading_class:string min_tick:float price_magnifier:integer order_types:string
51
+ valid_exchanges:string under_con_id:integer long_name:string contract_month:string
52
+ industry:string category:string subcategory:string time_zone:string trading_hours:string
53
+ liquid_hours:string cusip:string ratings:string desc_append:string bond_type:string
54
+ coupon_type:string coupon:float maturity:string issue_date:string next_option_date:string
55
+ next_option_type:string notes:string callable:boolean puttable:boolean convertible:boolean
56
+ next_option_partial:boolean valid_next_option_date:string valid_next_option_type:string
57
+ valid_next_option_partial:string ev_rule:string ev_multiplier:float sec_id_list:text
51
58
 
data/db/schema.rb CHANGED
@@ -70,12 +70,18 @@ ActiveRecord::Schema.define(:version => 171) do
70
70
  t.string "next_option_date"
71
71
  t.string "next_option_type"
72
72
  t.string "notes"
73
- t.boolean "callable", :limit => 1
74
- t.boolean "puttable", :limit => 1
75
- t.boolean "convertible", :limit => 1
76
- t.boolean "next_option_partial", :limit => 1
77
- t.datetime "created_at", :null => false
78
- t.datetime "updated_at", :null => false
73
+ t.boolean "callable", :limit => 1
74
+ t.boolean "puttable", :limit => 1
75
+ t.boolean "convertible", :limit => 1
76
+ t.boolean "next_option_partial", :limit => 1
77
+ t.string "valid_next_option_date"
78
+ t.string "valid_next_option_type"
79
+ t.string "valid_next_option_partial"
80
+ t.string "ev_rule"
81
+ t.float "ev_multiplier"
82
+ t.text "sec_id_list"
83
+ t.datetime "created_at", :null => false
84
+ t.datetime "updated_at", :null => false
79
85
  end
80
86
 
81
87
  create_table "ib_contracts", :force => true do |t|
@@ -105,6 +111,8 @@ ActiveRecord::Schema.define(:version => 171) do
105
111
  t.integer "client_id"
106
112
  t.integer "perm_id"
107
113
  t.string "order_ref"
114
+ t.string "ev_rule"
115
+ t.float "ev_multiplier"
108
116
  t.string "exec_id"
109
117
  t.string "side", :limit => 1
110
118
  t.integer "quantity"
data/lib/ib/connection.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'thread'
2
2
  require 'ib/socket'
3
3
  require 'ib/logger'
4
+ require 'ib/messages'
4
5
 
5
6
  module IB
6
7
  # Encapsulates API connection to TWS or Gateway
@@ -18,8 +19,8 @@ module IB
18
19
  :received => true, # Keep all received messages in a @received Hash
19
20
  :logger => nil,
20
21
  :client_id => nil, # Will be randomly assigned
21
- :client_version => 57, # 48, # 57 = can receive commissionReport message
22
- :server_version => 60 # 53? Minimal server version required
22
+ :client_version => IB::Messages::CLIENT_VERSION,
23
+ :server_version => IB::Messages::SERVER_VERSION
23
24
  }
24
25
 
25
26
  # Singleton to make active Connection universally accessible as IB::Connection.current
@@ -68,7 +69,7 @@ module IB
68
69
  server[:client_version] = options[:client_version]
69
70
  server[:server_version] = socket.read_int
70
71
  if server[:server_version] < options[:server_version]
71
- error "TWS version #{server[:server_version]}, #{options[:server_version]} required."
72
+ error "Server version #{server[:server_version]}, #{options[:server_version]} required."
72
73
  end
73
74
  server[:remote_connect_time] = socket.read_string
74
75
  server[:local_connect_time] = Time.now()
@@ -80,7 +81,7 @@ module IB
80
81
  socket.write_data server[:client_id]
81
82
 
82
83
  @connected = true
83
- log.info "Connected to server, version: #{server[:server_version]}, connection time: " +
84
+ log.info "Connected to server, ver: #{server[:server_version]}, connection time: " +
84
85
  "#{server[:local_connect_time]} local, " +
85
86
  "#{server[:remote_connect_time]} remote."
86
87
 
data/lib/ib/errors.rb CHANGED
@@ -13,6 +13,9 @@ module IB
13
13
  class LoadError < LoadError
14
14
  end
15
15
 
16
+ class FlexError < RuntimeError
17
+ end
18
+
16
19
  end # module IB
17
20
 
18
21
  # Patching Object with universally accessible top level error method.
@@ -29,6 +32,8 @@ def error message, type=:standard, backtrace=nil
29
32
  IB::SymbolError.new message
30
33
  when :load
31
34
  IB::LoadError.new message
35
+ when :flex
36
+ IB::FlexError.new message
32
37
  end
33
38
  e.set_backtrace(backtrace) if backtrace
34
39
  raise e
data/lib/ib/flex.rb ADDED
@@ -0,0 +1,105 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'xmlsimple'
4
+
5
+ module IB
6
+
7
+ # FLEX is a web-based service from IB that helps you to retrieve your activity,
8
+ # trades and positions. It is working independently from TWS or Gateway, using your
9
+ # internet connection directly. See /misc/flex for extended FLEX documentation.
10
+ #
11
+ # In order to use this service, activate it and configure your token first.
12
+ # Your Token is located at Account Management->Reports->Delivery Settings->Flex Web Service.
13
+ # You need to activate Flex Web Service and generate new token(s) there.
14
+ # Your Flex Query Ids are in Account Management->Reports->Activity->Flex Queries.
15
+ # Create new Flex query and make sure to set its output format to XML.
16
+ #
17
+ # IB::Flex object incapsulates a single pre-defined Flex query.
18
+ class Flex
19
+ class << self
20
+ attr_accessor :token, :uri
21
+
22
+ # By default, uri is a well known FLEX Web Service URI
23
+ def uri
24
+ @uri || 'https://www.interactivebrokers.com/Universal/servlet/FlexStatementService.SendRequest'
25
+ end
26
+ end
27
+
28
+ # Create new Flex query with options:
29
+ # :token => 1111111111111111111111111111111111 # CHANGE to your actual token!
30
+ # :query_id => 11111 # CHANGE to actual query id!
31
+ # :format => :xml (default) / :csv
32
+ # :verbose => true / false (default)
33
+ def initialize opts
34
+ @query_id = opts[:query_id]
35
+ @token = opts[:token] || Flex.token
36
+ @format = opts[:format] || :xml
37
+ @verbose = !!opts[:verbose]
38
+ yield self if block_given?
39
+ end
40
+
41
+ # Run a pre-defined Flex query against IB Flex Web Service
42
+ # Returns a (parsed) report or raises FlexError in case of problems
43
+ def run
44
+ # Initiate FLEX request at a known FLEX Web Service URI
45
+ resp = get_content Flex.uri, :t => @token, :q => @query_id, :v => 3
46
+ error("#{resp['ErrorCode']}: #{resp['ErrorMessage']}", :flex) if resp['Status'] == 'Fail'
47
+
48
+ reference_code = resp['ReferenceCode']
49
+ report_uri = resp['Url']
50
+
51
+ # Retrieve the FLEX report
52
+ report = nil
53
+ until report do
54
+ report = get_content(report_uri, :t => @token, :q => reference_code, :v => 3,
55
+ :text_ok => @format != :xml)
56
+
57
+ # If Status is specified, returned xml contains only error message, not actual report
58
+ if report.is_a?(Hash) && report['Status'] == 'Fail'
59
+ error_code = report['ErrorCode'].to_i
60
+ error_message = "#{error_code}: #{report['ErrorMessage']}"
61
+
62
+ case error_code
63
+ when 1001..1009, 1018, 1019, 1021
64
+ # Report is just not ready yet, wait and retry
65
+ puts error_message if @verbose
66
+ report = nil
67
+ sleep 1
68
+ else # Fatal error
69
+ error error_message, :flex
70
+ end
71
+ end
72
+ end
73
+ report
74
+ end
75
+
76
+ # Helper method to get (and parse XML) responses from IB Flex Web Service
77
+ def get_content address, fields
78
+ text_ok = fields.delete(:text_ok)
79
+ resp = get address, fields
80
+ if resp.content_type == 'text/xml'
81
+ XmlSimple.xml_in(resp.body, :ForceArray => false)
82
+ else
83
+ error("Expected xml, got #{resp.content_type}", :flex) unless text_ok
84
+ resp.body
85
+ end
86
+ end
87
+
88
+ # Helper method to get raw responses from IB Flex Web Service
89
+ def get address, fields
90
+ uri = URI("#{address}?" + fields.map { |k, v| "#{k}=#{URI.encode(v.to_s)}" }.join('&'))
91
+
92
+ server = Net::HTTP.new(uri.host, uri.port)
93
+ server.use_ssl = (uri.scheme == 'https')
94
+ server.verify_mode = OpenSSL::SSL::VERIFY_NONE if server.use_ssl? # Avoid OpenSSL failures
95
+
96
+ resp = server.start do |http|
97
+ req = Net::HTTP::Get.new(uri.request_uri)
98
+ http.request(req)
99
+ end
100
+ error("URI responded with #{resp.code}", :flex) unless resp.code.to_i == 200
101
+ resp
102
+ end
103
+
104
+ end
105
+ end
data/lib/ib/messages.rb CHANGED
@@ -1,8 +1,88 @@
1
1
  module IB
2
2
  module Messages
3
+ # This gem supports incoming/outgoing IB messages compatible with the following
4
+ # IB client/server versions:
5
+ CLIENT_VERSION = 59 # 59? Maximal client version implemented
6
+ SERVER_VERSION = 60 # 38? 53? 62? Minimal server version required
3
7
  end
4
8
  end
5
9
 
6
10
  require 'ib/messages/outgoing'
7
11
  require 'ib/messages/incoming'
8
12
 
13
+ __END__
14
+ // Client version history
15
+ //
16
+ // 6 = Added parentId to orderStatus
17
+ // 7 = The new execDetails event returned for an order filled status and reqExecDetails
18
+ // Also market depth is available.
19
+ // 8 = Added lastFillPrice to orderStatus() event and permId to execution details
20
+ // 9 = Added 'averageCost', 'unrealizedPNL', and 'unrealizedPNL' to updatePortfolio event
21
+ // 10 = Added 'serverId' to the 'open order' & 'order status' events.
22
+ // We send back all the API open orders upon connection.
23
+ // Added new methods reqAllOpenOrders, reqAutoOpenOrders()
24
+ // Added FA support - reqExecution has filter.
25
+ // - reqAccountUpdates takes acct code.
26
+ // 11 = Added permId to openOrder event.
27
+ // 12 = requsting open order attributes ignoreRth, hidden, and discretionary
28
+ // 13 = added goodAfterTime
29
+ // 14 = always send size on bid/ask/last tick
30
+ // 15 = send allocation description string on openOrder
31
+ // 16 = can receive account name in account and portfolio updates, and fa params in openOrder
32
+ // 17 = can receive liquidation field in exec reports, and notAutoAvailable field in mkt data
33
+ // 18 = can receive good till date field in open order messages, and request intraday backfill
34
+ // 19 = can receive rthOnly flag in ORDER_STATUS
35
+ // 20 = expects TWS time string on connection after server version >= 20.
36
+ // 21 = can receive bond contract details.
37
+ // 22 = can receive price magnifier in version 2 contract details message
38
+ // 23 = support for scanner
39
+ // 24 = can receive volatility order parameters in open order messages
40
+ // 25 = can receive HMDS query start and end times
41
+ // 26 = can receive option vols in option market data messages
42
+ // 27 = can receive delta neutral order type and delta neutral aux price in place order version 20: API 8.85
43
+ // 28 = can receive option model computation ticks: API 8.9
44
+ // 29 = can receive trail stop limit price in open order and can place them: API 8.91
45
+ // 30 = can receive extended bond contract def, new ticks, and trade count in bars
46
+ // 31 = can receive EFP extensions to scanner and market data, and combo legs on open orders
47
+ // ; can receive RT bars
48
+ // 32 = can receive TickType.LAST_TIMESTAMP
49
+ // ; can receive "whyHeld" in order status messages
50
+ // 33 = can receive ScaleNumComponents and ScaleComponentSize is open order messages
51
+ // 34 = can receive whatIf orders / order state
52
+ // 35 = can receive contId field for Contract objects
53
+ // 36 = can receive outsideRth field for Order objects
54
+ // 37 = can receive clearingAccount and clearingIntent for Order objects
55
+ // 38 = can receive multiplier and primaryExchange in portfolio updates
56
+ // ; can receive cumQty and avgPrice in execution
57
+ // ; can receive fundamental data
58
+ // ; can receive underComp for Contract objects
59
+ // ; can receive reqId and end marker in contractDetails/bondContractDetails
60
+ // ; can receive ScaleInitComponentSize and ScaleSubsComponentSize for Order objects
61
+ // 39 = can receive underConId in contractDetails
62
+ // 40 = can receive algoStrategy/algoParams in openOrder
63
+ // 41 = can receive end marker for openOrder
64
+ // ; can receive end marker for account download
65
+ // ; can receive end marker for executions download
66
+ // 42 = can receive deltaNeutralValidation
67
+ // 43 = can receive longName(companyName)
68
+ // ; can receive listingExchange
69
+ // ; can receive RTVolume tick
70
+ // 44 = can receive end market for ticker snapshot
71
+ // 45 = can receive notHeld field in openOrder
72
+ // 46 = can receive contractMonth, industry, category, subcategory fields in contractDetails
73
+ // ; can receive timeZoneId, tradingHours, liquidHours fields in contractDetails
74
+ // 47 = can receive gamma, vega, theta, undPrice fields in TICK_OPTION_COMPUTATION
75
+ // 48 = can receive exemptCode in openOrder
76
+ // 49 = can receive hedgeType and hedgeParam in openOrder
77
+ // 50 = can receive optOutSmartRouting field in openOrder
78
+ // 51 = can receive smartComboRoutingParams in openOrder
79
+ // 52 = can receive deltaNeutralConId, deltaNeutralSettlingFirm, deltaNeutralClearingAccount and deltaNeutralClearingIntent in openOrder
80
+ // 53 = can receive orderRef in execution
81
+ // 54 = can receive scale order fields (PriceAdjustValue, PriceAdjustInterval, ProfitOffset, AutoReset,
82
+ // InitPosition, InitFillQty and RandomPercent) in openOrder
83
+ // 55 = can receive orderComboLegs (price) in openOrder
84
+ // 56 = can receive trailingPercent in openOrder
85
+ // 57 = can receive commissionReport message
86
+ // 58 = can receive CUSIP/ISIN/etc. in contractDescription/bondContractDescription
87
+ // 59 = can receive evRule, evMultiplier in contractDescription/bondContractDescription/executionDetails
88
+ // can receive multiplier in executionDetails