Class: IB::Contract
- Includes:
- BaseProperties
- Defined in:
- lib/models/ib/contract.rb,
lib/models/ib/contract.rb
Overview
IB.send(:remove_const, ‘Contract’)
Constant Summary collapse
- Subclasses =
Contract subclasses representing specialized security types.
Hash.new(Contract)
Instance Attribute Summary collapse
-
#description ⇒ Object
NB: local to ib, not part of TWS.
Class Method Summary collapse
-
.build(opts = {}) ⇒ Object
the method is also used to copy Contract.values to new instances.
-
.from_ib_ruby ⇒ Object
This returns a Contract initialized from the serialize_ib_ruby format string.
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
creates a new Contract substituting attributes by the provided key-value pairs.
-
#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:.
- #to_human ⇒ Object
- #to_s ⇒ Object
- #to_short ⇒ Object
-
#verify ⇒ Object
:nodoc:.
Methods included from BaseProperties
#content_attributes, #invariant_attributes, #set_attribute_defaults, #update_missing
Instance Attribute Details
#description ⇒ Object
NB: local to ib, not part of TWS.
75 76 77 |
# File 'lib/models/ib/contract.rb', line 75 def description @description end |
Class Method Details
.build(opts = {}) ⇒ Object
the method is also used to copy Contract.values to new instances
408 409 410 411 |
# File 'lib/models/ib/contract.rb', line 408 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 |
.from_ib_ruby ⇒ Object
This returns a Contract initialized from the serialize_ib_ruby format string.
414 415 416 417 418 419 420 |
# File 'lib/models/ib/contract.rb', line 414 def self.from_ib_ruby keys = [:con_id, :symbol, :sec_type, :expiry, :strike, :right, :multiplier, :exchange, :primary_exchange, :currency, :local_symbol] props = Hash[keys.zip(string.split(":"))] props.delete_if { |k, v| v.nil? || v.empty? } Contract.build props end |
Instance Method Details
#==(other) ⇒ Object
Contract comparison
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/models/ib/contract.rb', line 247 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
319 320 321 |
# File 'lib/models/ib/contract.rb', line 319 def bag? # :nodoc: self[:sec_type] == 'BAG' end |
#bond? ⇒ Boolean
:nodoc:
323 324 325 326 |
# File 'lib/models/ib/contract.rb', line 323 def bond? # :nodoc: self[:sec_type] == 'BOND' end |
#default_attributes ⇒ Object
:nodoc:
120 121 122 123 124 125 126 |
# File 'lib/models/ib/contract.rb', line 120 def default_attributes # :nodoc: super.merge :con_id => 0, :strike => 0.0, :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.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/models/ib/contract.rb', line 218 def essential self_attributes = [ :sec_type] the_attributes = [ :symbol , :con_id, :exchange, :right, :currency, :expiry, :strike, :local_symbol, :last_trading_day, :multiplier, :primary_exchange, :trading_class ] the_hash= the_attributes.map{|x| y= self.send(x); [x,y] if y.present? }.compact.to_h the_hash[:description] = if @description.present? @description elsif contract_detail.present? contract_detail.long_name else "" end self.class.new the_hash.merge( self_attributes.map{|x| y = self.send(x); [x,y] unless y == :none }.compact.to_h ) 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’
366 367 368 369 370 371 372 |
# File 'lib/models/ib/contract.rb', line 366 def expiry if self.last_trading_day.present? last_trading_day.gsub(/-/,'') else @attributes[:expiry] end end |
#index? ⇒ Boolean
:nodoc:
338 339 340 341 |
# File 'lib/models/ib/contract.rb', line 338 def index? # :nodoc: self[:sec_type] == 'IND' end |
#merge(**new_attributes) ⇒ Object
creates a new Contract substituting attributes by the provided key-value pairs.
con_id is resetted
240 241 242 243 |
# File 'lib/models/ib/contract.rb', line 240 def merge **new_attributes self.con_id = 0 self.class.new attributes.merge new_attributes end |
#option? ⇒ Boolean
:nodoc:
333 334 335 336 |
# File 'lib/models/ib/contract.rb', line 333 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
376 377 378 |
# File 'lib/models/ib/contract.rb', line 376 def order_requirements Hash.new end |
#serialize(*fields) ⇒ Object
18/1/18: serialise always includes conid
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/models/ib/contract.rb', line 137 def serialize *fields # :nodoc: print_default = ->(field, default="") { field.blank? ? default : field } print_not_zero = ->(field, default="") { field.to_i.zero? ? 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], print_not_zero[strike], 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:
210 211 212 |
# File 'lib/models/ib/contract.rb', line 210 def serialize_ib_ruby serialize_long.join(":") end |
#serialize_legs(*fields) ⇒ Object
Defined in Contract, not BAG subclass to keep code DRY
185 186 187 188 189 190 191 192 193 194 |
# File 'lib/models/ib/contract.rb', line 185 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
161 162 163 |
# File 'lib/models/ib/contract.rb', line 161 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
169 170 171 |
# File 'lib/models/ib/contract.rb', line 169 def serialize_short *fields # :nodoc: serialize :option, :trading_class, :primary_exchange, *fields end |
#serialize_supershort(*fields) ⇒ Object
used by RequestMarketDepth
175 176 177 |
# File 'lib/models/ib/contract.rb', line 175 def serialize_supershort *fields # :nodoc: serialize :option, :trading_class, *fields end |
#serialize_under_comp(*args) ⇒ Object
Serialize under_comp parameters: EClientSocket.java, line 471
180 181 182 |
# File 'lib/models/ib/contract.rb', line 180 def serialize_under_comp *args # :nodoc: under_comp ? under_comp.serialize : [false] end |
#stock? ⇒ Boolean
:nodoc:
328 329 330 331 |
# File 'lib/models/ib/contract.rb', line 328 def stock? # :nodoc: self[:sec_type] == 'STK' end |
#to_human ⇒ Object
296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/models/ib/contract.rb', line 296 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
289 290 291 292 293 294 |
# File 'lib/models/ib/contract.rb', line 289 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
308 309 310 311 312 313 314 315 316 |
# File 'lib/models/ib/contract.rb', line 308 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 |
#verify ⇒ Object
:nodoc:
344 345 346 |
# File 'lib/models/ib/contract.rb', line 344 def verify # :nodoc: error "verify must be overloaded. Please require at least `ib/verify` from the `ib-extenstions` gem " end |