Class: IB::Spread

Inherits:
Bag show all
Defined in:
lib/models/ib/spread.rb

Direct Known Subclasses

Vertical

Constant Summary

Constants inherited from Contract

Contract::Subclasses

Instance Attribute Summary

Attributes inherited from Contract

#description

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Bag

#==, #con_id=, #default_attributes, #legs_description, #same_legs?

Methods inherited from Contract

#==, #bag?, #bond?, build, #default_attributes, #expiry, from_ib_ruby, #index?, #merge, #option?, #order_requirements, #serialize, #serialize_ib_ruby, #serialize_legs, #serialize_long, #serialize_short, #serialize_supershort, #serialize_under_comp, #stock?, #to_s, #to_short, #verify

Methods included from BaseProperties

#==, #content_attributes, #default_attributes, #invariant_attributes, #set_attribute_defaults, #update_missing

Class Method Details

.build_from_json(container) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/models/ib/spread.rb', line 141

def self.build_from_json container
  read_leg = ->(a) do 
      IB::ComboLeg.new :con_id => a.read_int,
                         :ratio => a.read_int,
                         :action => a.read_string,
                         :exchange => a.read_string

  end
  object= self.new  container['Spread'].read_contract
  object.legs = container['legs'].map{|x| IB::Contract.build x.read_contract}
  object.combo_legs = container['combo_legs'].map{ |x| read_leg[ x ] } 
  object.description = container['misc'].read_string
  object

end

Instance Method Details

#add_leg(contract, **leg_params) ⇒ Object

adds a leg to any spread

Parameter: contract: Will be verified. Contract.essential is added to legs-array action: :buy or :sell weight: ratio: Default: action: :buy, weight: 1



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/models/ib/spread.rb', line 84

def add_leg contract,  **leg_params
  evaluated_contracts =  []
  nc = contract.verify.first.essential
  #      weigth = 1 --> sets Combo.side to buy and overwrites the action statement
#     leg_params[:weight] = 1 unless leg_params.key?(:weight) || leg_params.key?(:ratio)
  if nc.is_a?( IB::Contract) && nc.con_id.present?
      the_leg= ComboLeg.new( nc.attributes.slice( :con_id, :exchange )
                                      .merge( leg_params ))
      self.combo_legs << the_leg 
      self.description = description + " added #{nc.to_human}" rescue "Spread: #{nc.to_human}"
      self.legs << nc
  end
  self  # return value to enable chaining


end

#calculate_spread_value(array_of_portfolio_values) ⇒ Object



46
47
48
# File 'lib/models/ib/spread.rb', line 46

def calculate_spread_value( array_of_portfolio_values )
  array_of_portfolio_values.map{|x| x.send yield }.sum if block_given?
end

#con_idObject

provide a negative con_id



122
123
124
# File 'lib/models/ib/spread.rb', line 122

def con_id
  -legs.map(&:con_id).sum
end

#essentialObject



113
114
115
116
# File 'lib/models/ib/spread.rb', line 113

def essential
    legs.each{ |x| x.essential }
    self
end

#fake_portfolio_position(array_of_portfolio_values) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/models/ib/spread.rb', line 50

def fake_portfolio_position(  array_of_portfolio_values )
    calculate_spread_value= ->( a_o_p_v, attribute ) do
          a_o_p_v.map{|x| x.send attribute }.sum 
    end
    ar=array_of_portfolio_values
    IB::PortfolioValue.new  contract: self, 
      average_cost:  calculate_spread_value[ar, :average_cost],
      market_price:  calculate_spread_value[ar, :market_price],
      market_value:  calculate_spread_value[ar, :market_value],
      unrealized_pnl:  calculate_spread_value[ar, :unrealized_pnl],
      realized_pnl:  calculate_spread_value[ar, :realized_pnl],
      position: 0

end

#multiplierObject



117
118
119
# File 'lib/models/ib/spread.rb', line 117

def  multiplier
  (legs.map(&:multiplier).sum/legs.size).to_i
end

#non_guaranteedObject



132
133
134
# File 'lib/models/ib/spread.rb', line 132

def non_guaranteed
    combo_params['NonGuaranteed']
end

#non_guaranteed=(x) ⇒ Object



127
128
129
# File 'lib/models/ib/spread.rb', line 127

def non_guaranteed= x
    super.merge   combo_params: [ ['NonGuaranteed', x] ]
end

#remove_leg(contract) ⇒ Object

removes the contract from the spread definition



103
104
105
106
107
108
109
110
# File 'lib/models/ib/spread.rb', line 103

def remove_leg contract
  contract.verify do |c|
    legs.delete_if { |x| x.con_id == c.con_id }
    combo_legs.delete_if { |x| x.con_id == c.con_id }
    self.description = description + " removed #{c.to_human}"
  end
  self
end

#serialize_rabbitObject



67
68
69
70
71
72
# File 'lib/models/ib/spread.rb', line 67

def serialize_rabbit
  { "Spread" => serialize( :option, :trading_class ),
    'legs' => legs.map{ |y| y.serialize :option, :trading_class }, 'combo_legs' => combo_legs.map(&:serialize),
    'misc' => [description]
  }  
end

#to_humanObject

def



42
43
44
# File 'lib/models/ib/spread.rb', line 42

def to_human
  self.description
end

#transform_distance(front, back) ⇒ Object

Parameters: front: YYYMM(DD) back: nw, nd or YYYYMM(DD)

Adds (or substracts) relative (back) measures to the front month, just passes absolute YYYYMM(DD) value front: 201809 back: 2m (-1m) –> 201811 (201808) front: 20180908 back: 1w (-1w) –> 20180918 (20180902)



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/models/ib/spread.rb', line 18

def transform_distance front, back
  # Check Format of back: 201809 --> > 200.000
  #                        20180989 ---> 20.000.000
  start_date = front.to_i < 20000000 ?  Date.strptime(front.to_s,"%Y%m") :  Date.strptime(front.to_s,"%Y%m%d") 
  nb = if back.to_i > 200000 
         back.to_i
       elsif back[-1] == "w" && front.to_i > 20000000
         start_date + (back.to_i * 7)
       elsif back[-1] == "m" && front.to_i > 200000
         start_date >> back.to_i
       else
         error "Wrong date #{back} required format YYYMM, YYYYMMDD ord {n}w or {n}m"
       end
  if nb.is_a?(Date)  
    if back[-1]=='w'
      nb.strftime("%Y%m%d")
    else
      nb.strftime("%Y%m")
    end
  else
    nb
  end 
end