Class: IB::Contract

Inherits:
Model show all
Includes:
BaseProperties
Defined in:
lib/models/ib/contract.rb,
lib/models/ib/contract.rb

Direct Known Subclasses

Bag, Option

Constant Summary collapse

Subclasses =

Contract subclasses representing specialized security types. Most security types do not have their own subclass, they use generic Contract class.

Hash.new(Contract)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from BaseProperties

#content_attributes, #set_attribute_defaults, #update_missing

Instance Attribute Details

#descriptionObject

NB: local to ib, not part of TWS.



65
66
67
# File 'lib/models/ib/contract.rb', line 65

def description
  @description
end

Class Method Details

.build(opts = {}) ⇒ Object

This builds an appropriate Contract subclass based on its type



278
279
280
281
# File 'lib/models/ib/contract.rb', line 278

def self.build opts = {}
  subclass = VALUES[:sec_type][opts[:sec_type]] || opts[:sec_type].to_sym
  Contract::Subclasses[subclass].new opts
end

.from_ib_ruby(string) ⇒ Object

This returns a Contract initialized from the serialize_ib_ruby format string.



284
285
286
287
288
289
290
# File 'lib/models/ib/contract.rb', line 284

def self.from_ib_ruby string
  keys = [: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



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/models/ib/contract.rb', line 181

def == other
  return true if super(other)

  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

Testing for type of contract:

Returns:

  • (Boolean)


246
247
248
# File 'lib/models/ib/contract.rb', line 246

def bag?
  self[:sec_type] == 'BAG'
end

#bond?Boolean

Returns:

  • (Boolean)


250
251
252
# File 'lib/models/ib/contract.rb', line 250

def bond?
  self[:sec_type] == 'BOND'
end

#default_attributesObject



109
110
111
112
113
114
115
# File 'lib/models/ib/contract.rb', line 109

def default_attributes
  super.merge :con_id => 0,
    :strike => 0.0,
    :right => :none, # Not an option
    :exchange => 'SMART',
    :include_expired => false
end

#option?Boolean

Returns:

  • (Boolean)


258
259
260
# File 'lib/models/ib/contract.rb', line 258

def option?
  self[:sec_type] == 'OPT'
end

#serialize(*fields) ⇒ Object

This returns an Array of data from the given contract. Different messages serialize contracts differently. Go figure. Note that it does NOT include the combo legs. serialize [:option, :con_id, :include_expired, :sec_id]



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/models/ib/contract.rb', line 121

def serialize *fields
  [(fields.include?(:con_id) ? [con_id] : []),
   symbol,
   self[:sec_type],
   (fields.include?(:option) ?
    [expiry,
     strike,
     self[:right],
     multiplier] : []),
   exchange,
   (fields.include?(:primary_exchange) ? [primary_exchange] : []),
   currency,
   local_symbol,
   (fields.include?(:sec_id) ? [sec_id_type, sec_id] : []),
   (fields.include?(:include_expired) ? [include_expired] : []),
   ].flatten
end

#serialize_ib_rubyObject

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:


176
177
178
# File 'lib/models/ib/contract.rb', line 176

def serialize_ib_ruby
  serialize_long.join(":")
end

#serialize_legs(*fields) ⇒ Object

Defined in Contract, not BAG subclass to keep code DRY



153
154
155
156
157
158
159
160
161
162
# File 'lib/models/ib/contract.rb', line 153

def serialize_legs *fields
  case
  when !bag?
    []
  when legs.empty?
    [0]
  else
    [legs.size, legs.map { |leg| leg.serialize *fields }].flatten
  end
end

#serialize_long(*fields) ⇒ Object



139
140
141
# File 'lib/models/ib/contract.rb', line 139

def serialize_long *fields
  serialize :option, :primary_exchange, *fields
end

#serialize_short(*fields) ⇒ Object



143
144
145
# File 'lib/models/ib/contract.rb', line 143

def serialize_short *fields
  serialize :option, *fields
end

#serialize_under_comp(*args) ⇒ Object

Serialize under_comp parameters: EClientSocket.java, line 471



148
149
150
# File 'lib/models/ib/contract.rb', line 148

def serialize_under_comp *args
  under_comp ? under_comp.serialize : [false]
end

#stock?Boolean

Returns:

  • (Boolean)


254
255
256
# File 'lib/models/ib/contract.rb', line 254

def stock?
  self[:sec_type] == 'STK'
end

#to_humanObject



228
229
230
231
232
233
234
235
236
237
238
# File 'lib/models/ib/contract.rb', line 228

def to_human
  "<Contract: " +
    [symbol,
     sec_type,
     (expiry == '' ? nil : expiry),
     (right == :none ? nil : right),
     (strike == 0 ? nil : strike),
     exchange,
     currency
     ].compact.join(" ") + ">"
end

#to_sObject



221
222
223
224
225
226
# File 'lib/models/ib/contract.rb', line 221

def to_s
  "<Contract: " + instance_variables.map do |key|
    value = send(key[1..-1])
    " #{key}=#{value}" unless value.nil? || value == '' || value == 0
  end.compact.join(',') + " >"
end

#to_shortObject



240
241
242
# File 'lib/models/ib/contract.rb', line 240

def to_short
  "#{symbol}#{expiry}#{strike}#{right}#{exchange}#{currency}"
end