lib/ib-ruby/models/contract.rb in ib-ruby-0.5.18 vs lib/ib-ruby/models/contract.rb in ib-ruby-0.5.19
- old
+ new
@@ -1,9 +1,7 @@
require 'ib-ruby/models/model'
-# TODO: Implement equals() according to the criteria in IB's Java client.
-
module IB
module Models
class Contract < Model
# Specialized Contract subclasses representing different security types
@@ -240,19 +238,71 @@
else
[false]
end
end
+ ### Leg-related methods (better suited to BAG subclass?)
+
# Some messages send open_close too, some don't. WTF.
# "BAG" is not really a contract, but a combination (combo) of securities.
# AKA basket or bag of securities. Individual securities in combo are represented
# by ComboLeg objects.
def serialize_legs *fields
return [] unless sec_type.upcase == "BAG"
return [0] if legs.empty? || legs.nil?
[legs.size, legs.map { |leg| leg.serialize *fields }]
end
+ # Check if two Contracts have same legs (maybe in different order)
+ def same_legs? other
+ legs == other.legs ||
+ legs_description.split(',').sort == other.legs_description.split(',').sort
+ end
+
+ # IB-equivalent leg description. TODO: Rewrite with self[:legs_description]
+ def legs_description
+ @legs_description || legs.map { |leg| "#{leg.con_id}|#{leg.weight}" }.join(',')
+ end
+
+ # Contract comparison
+ def == other
+ # 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 under_comp
+ return false if under_comp && other.under_comp && under_comp != other.under_comp
+
+ # Different legs
+ return false unless same_legs? other
+
+ # 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 sec_type == SECURITY_TYPES[:bond] || sec_type == SECURITY_TYPES[:option]
+ return false unless right == other.right &&
+ strike == other.strike &&
+ expiry == other.expiry &&
+ multiplier == other.multiplier
+ end
+
+ # All else being equal...
+ sec_type == other.sec_type &&
+ symbol == other.symbol &&
+ currency == other.currency
+ end
+
+
+ # TODO: Remove @summary into reader method
def to_s
"<Contract: " + instance_variables.map do |key|
unless key == :@summary
value = send(key[1..-1])
" #{key}=#{value}" unless value.nil? || value == '' || value == 0