Class: IB::Contract
- Includes:
- BaseProperties
- Defined in:
- lib/models/ib/contract.rb,
lib/models/ib/contract.rb
Overview
puts Contract.ancestors IB.send(:remove_const, ‘Contract’)
Constant Summary collapse
- Subclasses =
Hash.new(Contract)
Instance Attribute Summary collapse
-
#description ⇒ Object
NB: local to ib, not part of TWS.
Class Method Summary collapse
-
.build(opts = {}) ⇒ Object
This builds an appropriate Contract subclass based on its type.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Contract comparison.
-
#bag? ⇒ Boolean
depreciated : use is_a?(IB::Stock, IB::Bond, IB::Bag etc) instead.
-
#bond? ⇒ Boolean
:nodoc:.
-
#default_attributes ⇒ Object
:nodoc:.
-
#essential ⇒ Object
extracts essential attributes of the contract, and returns a new contract.
-
#expiry ⇒ Object
IB-ruby uses expiry to query Contracts.
-
#index? ⇒ Boolean
:nodoc:.
-
#merge(**new_attributes) ⇒ Object
┌────────┬────────┬───────────┬──────────┬──────────┬────────────┬───────────────┬───────┬────────┬──────────┐ │ │ symbol │ con_id │ exchange │ expiry │ multiplier │ trading-class │ right │ strike │ currency │ ╞════════╪════════╪═══════════╪══════════╪══════════╪════════════╪═══════════════╪═══════╪════════╪══════════╡ │ Future │ ES │ 428520022 │ GLOBEX │ 20210917 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 446091461 │ GLOBEX │ 20211217 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 461318816 │ GLOBEX │ 20220318 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 477836957 │ GLOBEX │ 20220617 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512551 │ GLOBEX │ 20221216 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512552 │ GLOBEX │ 20231215 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512557 │ GLOBEX │ 20241220 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512563 │ GLOBEX │ 20251219 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512566 │ GLOBEX │ 20220916 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512569 │ GLOBEX │ 20230616 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512572 │ GLOBEX │ 20230317 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 497222760 │ GLOBEX │ 20230915 │ 50 │ ES │ │ │ USD │ └────────┴────────┴───────────┴──────────┴──────────┴────────────┴───────────────┴───────┴────────┴──────────┘.
-
#option? ⇒ Boolean
:nodoc:.
-
#order_requirements ⇒ Object
is read by Account#PlaceOrder to set requirements for contract-types, as NonGuaranteed for stock-spreads.
-
#serialize(*fields) ⇒ Object
18/1/18: serialise always includes conid.
-
#serialize_ib_ruby ⇒ Object
This produces a string uniquely identifying this contract, in the format used for command line arguments in the IB-Ruby examples.
-
#serialize_legs(*fields) ⇒ Object
Defined in Contract, not BAG subclass to keep code DRY.
-
#serialize_long(*fields) ⇒ Object
serialize contract con_id.
-
#serialize_short(*fields) ⇒ Object
serialize contract con_id.
-
#serialize_supershort(*fields) ⇒ Object
used by RequestMarketDepth.
-
#serialize_under_comp(*args) ⇒ Object
Serialize under_comp parameters: EClientSocket.java, line 471.
-
#stock? ⇒ Boolean
:nodoc:.
- #table_header(&b) ⇒ Object
- #table_row ⇒ Object
- #to_human ⇒ Object
- #to_s ⇒ Object
- #to_short ⇒ Object
-
#verify ⇒ Object
:nodoc:.
Methods included from BaseProperties
#as_table, #content_attributes, #invariant_attributes, #set_attribute_defaults, #update_missing
Instance Attribute Details
#description ⇒ Object
NB: local to ib, not part of TWS.
76 77 78 |
# File 'lib/models/ib/contract.rb', line 76 def description @description end |
Class Method Details
.build(opts = {}) ⇒ Object
This builds an appropriate Contract subclass based on its type
the method is also used to copy Contract.values to new instances
478 479 480 481 |
# File 'lib/models/ib/contract.rb', line 478 def self.build opts = {} subclass =( VALUES[:sec_type][opts[:sec_type]] || opts['sec_type'] || opts[:sec_type]).to_sym Contract::Subclasses[subclass].new opts end |
Instance Method Details
#==(other) ⇒ Object
Contract comparison
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/models/ib/contract.rb', line 282 def == other # :nodoc: return false if !other.is_a?(Contract) return true if super(other) return true if !con_id.to_i.zero? && con_id == other.con_id return false unless other.is_a?(self.class) # Different sec_id_type return false if sec_id_type && other.sec_id_type && sec_id_type != other.sec_id_type # Different sec_id return false if sec_id && other.sec_id && sec_id != other.sec_id # Different symbols return false if symbol && other.symbol && symbol != other.symbol # Different currency return false if currency && other.currency && currency != other.currency # Same con_id for all Bags, but unknown for new Contracts... # 0 or nil con_id matches any return false if con_id != 0 && other.con_id != 0 && con_id && other.con_id && con_id != other.con_id # SMART or nil exchange matches any return false if exchange != 'SMART' && other.exchange != 'SMART' && exchange && other.exchange && exchange != other.exchange # Comparison for Bonds and Options if bond? || option? return false if right != other.right || strike != other.strike return false if multiplier && other.multiplier && multiplier != other.multiplier return false if expiry && expiry[0..5] != other.expiry[0..5] return false unless expiry && (expiry[6..7] == other.expiry[6..7] || expiry[6..7].empty? || other.expiry[6..7].empty?) end # All else being equal... sec_type == other.sec_type end |
#bag? ⇒ Boolean
depreciated : use is_a?(IB::Stock, IB::Bond, IB::Bag etc) instead
354 355 356 |
# File 'lib/models/ib/contract.rb', line 354 def bag? # :nodoc: self[:sec_type] == 'BAG' end |
#bond? ⇒ Boolean
:nodoc:
358 359 360 361 |
# File 'lib/models/ib/contract.rb', line 358 def bond? # :nodoc: self[:sec_type] == 'BOND' end |
#default_attributes ⇒ Object
:nodoc:
121 122 123 124 125 126 127 |
# File 'lib/models/ib/contract.rb', line 121 def default_attributes # :nodoc: super.merge :con_id => 0, :strike => "", :right => :none, # Not an option # :exchange => 'SMART', :include_expired => false end |
#essential ⇒ Object
extracts essential attributes of the contract, and returns a new contract.
the link to contract-details is __not__ maintained.
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/models/ib/contract.rb', line 219 def essential the_attributes = [ :sec_type, :symbol , :con_id, :exchange, :right, :currency, :expiry, :strike, :local_symbol, :last_trading_day, :multiplier, :primary_exchange, :trading_class, :description ] new_contract= self.class.new invariant_attributes.select{|k,_| the_attributes.include? k }.compact new_contract[:description] = if @description.present? @description elsif contract_detail.present? contract_detail.long_name else "" end new_contract # return contract end |
#expiry ⇒ Object
IB-ruby uses expiry to query Contracts.
The response from the TWS is stored in ‘last_trading_day’ (Contract) and ‘real_expiration_data’ (ContractDetails)
However, after querying a contract, ‘expiry’ ist overwritten by ‘last_trading_day’. The original ‘expiry’ is still available through ‘attributes’
401 402 403 404 405 406 407 |
# File 'lib/models/ib/contract.rb', line 401 def expiry if self.last_trading_day.present? last_trading_day.gsub(/-/,'') else @attributes[:expiry] end end |
#index? ⇒ Boolean
:nodoc:
373 374 375 376 |
# File 'lib/models/ib/contract.rb', line 373 def index? # :nodoc: self[:sec_type] == 'IND' end |
#merge(**new_attributes) ⇒ Object
┌────────┬────────┬───────────┬──────────┬──────────┬────────────┬───────────────┬───────┬────────┬──────────┐ │ │ symbol │ con_id │ exchange │ expiry │ multiplier │ trading-class │ right │ strike │ currency │ ╞════════╪════════╪═══════════╪══════════╪══════════╪════════════╪═══════════════╪═══════╪════════╪══════════╡ │ Future │ ES │ 428520022 │ GLOBEX │ 20210917 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 446091461 │ GLOBEX │ 20211217 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 461318816 │ GLOBEX │ 20220318 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 477836957 │ GLOBEX │ 20220617 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512551 │ GLOBEX │ 20221216 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512552 │ GLOBEX │ 20231215 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512557 │ GLOBEX │ 20241220 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512563 │ GLOBEX │ 20251219 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512566 │ GLOBEX │ 20220916 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512569 │ GLOBEX │ 20230616 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 495512572 │ GLOBEX │ 20230317 │ 50 │ ES │ │ │ USD │ │ Future │ ES │ 497222760 │ GLOBEX │ 20230915 │ 50 │ ES │ │ │ USD │ └────────┴────────┴───────────┴──────────┴──────────┴────────────┴───────────────┴───────┴────────┴──────────┘
272 273 274 275 276 277 278 |
# File 'lib/models/ib/contract.rb', line 272 def merge **new_attributes resetted_attributes = [:con_id, :local_symbol, :contract_detail] ## last_trading_day / expiry needs special treatment resetted_attributes << :last_trading_day if new_attributes.keys.include? :expiry self.class.new attributes.reject{|k,_| resetted_attributes.include? k}.merge(new_attributes) end |
#option? ⇒ Boolean
:nodoc:
368 369 370 371 |
# File 'lib/models/ib/contract.rb', line 368 def option? # :nodoc: self[:sec_type] == 'OPT' end |
#order_requirements ⇒ Object
is read by Account#PlaceOrder to set requirements for contract-types, as NonGuaranteed for stock-spreads
411 412 413 |
# File 'lib/models/ib/contract.rb', line 411 def order_requirements Hash.new end |
#serialize(*fields) ⇒ Object
18/1/18: serialise always includes conid
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/models/ib/contract.rb', line 138 def serialize *fields # :nodoc: print_default = ->(field, default="") { field.blank? ? default : field } [(con_id.present? && !con_id.is_a?(Symbol) && con_id.to_i > 0 ? con_id : ""), print_default[symbol], print_default[self[:sec_type]], ( fields.include?(:option) ? [ print_default[expiry], ## a Zero-Strike-Option has to be defined with «strike: -1 » strike.present? && ( strike.is_a?(Numeric) && !strike.zero? && strike > 0 ) ? strike : strike<0 ? 0 : "", print_default[self[:right]], print_default[multiplier]] : nil ), print_default[exchange], ( fields.include?(:primary_exchange) ? print_default[primary_exchange] : nil ) , print_default[currency], print_default[local_symbol], ( fields.include?(:trading_class) ? print_default[trading_class] : nil ), ( fields.include?(:include_expired) ? print_default[include_expired,0] : nil ), ( fields.include?(:sec_id_type) ? [print_default[sec_id_type], print_default[sec_id]] : nil ) ].flatten.compact end |
#serialize_ib_ruby ⇒ Object
This produces a string uniquely identifying this contract, in the format used for command line arguments in the IB-Ruby examples. The format is:
symbol:sec_type:expiry:strike:right:multiplier:exchange:primary_exchange:currency:local_symbol
Fields not needed for a particular security should be left blank (e.g. strike and right are only relevant for options.)
For example, to query the British pound futures contract trading on Globex expiring in September, 2008, the string is:
GBP:FUT:200809:::62500:GLOBEX::USD:
211 212 213 |
# File 'lib/models/ib/contract.rb', line 211 def serialize_ib_ruby serialize_long.join(":") end |
#serialize_legs(*fields) ⇒ Object
Defined in Contract, not BAG subclass to keep code DRY
186 187 188 189 190 191 192 193 194 195 |
# File 'lib/models/ib/contract.rb', line 186 def serialize_legs *fields # :nodoc: case when !bag? [] when combo_legs.empty? [0] else [combo_legs.size, combo_legs.map { |the_leg| the_leg.serialize *fields }].flatten end end |
#serialize_long(*fields) ⇒ Object
serialize contract con_id. sec_type, expiry, strike, right, multiplier exchange, primary_exchange, currency, local_symbol, include_expired other fields on demand
162 163 164 |
# File 'lib/models/ib/contract.rb', line 162 def serialize_long *fields # :nodoc: serialize :option, :include_expired, :primary_exchange, :trading_class, *fields end |
#serialize_short(*fields) ⇒ Object
serialize contract con_id. sec_type, expiry, strike, right, multiplier, exchange, primary_exchange, currency, local_symbol other fields on demand acutal used by place_order, request_marketdata, request_market_depth, exercise_options
170 171 172 |
# File 'lib/models/ib/contract.rb', line 170 def serialize_short *fields # :nodoc: serialize :option, :trading_class, :primary_exchange, *fields end |
#serialize_supershort(*fields) ⇒ Object
used by RequestMarketDepth
176 177 178 |
# File 'lib/models/ib/contract.rb', line 176 def serialize_supershort *fields # :nodoc: serialize :option, :trading_class, *fields end |
#serialize_under_comp(*args) ⇒ Object
Serialize under_comp parameters: EClientSocket.java, line 471
181 182 183 |
# File 'lib/models/ib/contract.rb', line 181 def serialize_under_comp *args # :nodoc: under_comp ? under_comp.serialize : [false] end |
#stock? ⇒ Boolean
:nodoc:
363 364 365 366 |
# File 'lib/models/ib/contract.rb', line 363 def stock? # :nodoc: self[:sec_type] == 'STK' end |
#table_header(&b) ⇒ Object
416 417 418 419 420 421 422 |
# File 'lib/models/ib/contract.rb', line 416 def table_header( &b ) if block_given? [ yield(self) , 'symbol', 'con_id', 'exchange', 'expiry','multiplier', 'trading-class' , 'right', 'strike', 'currency' ] else [ '', 'symbol', 'con_id', 'exchange', 'expiry','multiplier', 'trading-class' , 'right', 'strike', 'currency' ] end end |
#table_row ⇒ Object
424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/models/ib/contract.rb', line 424 def table_row [ self.class.to_s.demodulize, symbol, { value: con_id.zero? ? '' : con_id , alignment: :right}, { value: exchange, alignment: :center}, expiry, { value: multiplier.zero?? "" : multiplier, alignment: :center}, { value: trading_class, alignment: :center}, {value: right == :none ? "": right, alignment: :center }, { value: strike.zero? ? "": strike, alignment: :right}, { value: currency, alignment: :center} ] end |
#to_human ⇒ Object
331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/models/ib/contract.rb', line 331 def to_human "<Contract: " + [symbol, sec_type, (expiry == '' ? nil : expiry), (right == :none ? nil : right), (strike == 0 ? nil : strike), exchange, currency ].compact.join(" ") + ">" end |
#to_s ⇒ Object
324 325 326 327 328 329 |
# File 'lib/models/ib/contract.rb', line 324 def to_s "<Contract: " + instance_variables.map do |key| value = send(key[1..-1]) " #{key}=#{value} (#{value.class}) " unless value.blank? end.compact.join(',') + " >" end |
#to_short ⇒ Object
343 344 345 346 347 348 349 350 351 |
# File 'lib/models/ib/contract.rb', line 343 def to_short if expiry.blank? && last_trading_day.blank? "#{symbol}# {exchange}# {currency}" elsif expiry.present? "#{symbol}(#{strike}) #{right} #{expiry} /#{exchange}/#{currency}" else "#{symbol}(#{strike}) #{right} #{last_trading_day} /#{exchange}/#{currency}" end end |