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, #index?, #merge, #option?, #order_requirements, #serialize, #serialize_ib_ruby, #serialize_legs, #serialize_long, #serialize_short, #serialize_supershort, #serialize_under_comp, #stock?, #table_header, #table_row, #to_s, #to_short, #verify

Methods included from BaseProperties

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

Class Method Details

.build_from_json(container) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/models/ib/spread.rb', line 164

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'].clone.read_contract
    object.legs = container['legs'].map{|x| IB::Contract.build x.clone.read_contract}
    object.combo_legs = container['combo_legs'].map{ |x| read_leg[ x.clone ] } 
    object.description = container['misc'].clone.read_string
	object

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)



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/models/ib/spread.rb', line 23

def self.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

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



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/models/ib/spread.rb', line 81

def add_leg contract,  **leg_params
    error "need a IB::Contract as first argument" unless contract.is_a? IB::Contract
    self.legs <<  contract
    error "cannot add leg if no con_id is provided" if contract.con_id.blank?
	#			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)
    self.combo_legs <<  ComboLeg.new( contract.attributes.slice( :con_id, :exchange ).merge( leg_params ))
    self.description = "#{description.nil? ? "": description} added #{contract.to_human}" rescue "Spread: #{contract.to_human}"

	self  # return value to enable chaining


end

#as_tableObject



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

def as_table 
  t=  Terminal::Table.new title:  description[1..-2] ,
                      headings: table_header, 

                      style: { border: :unicode }

  t.add_row table_row
  legs.each{ |y| t.add_row y.table_row }
  t.render

end

#calculate_spread_value(array_of_portfolio_values) ⇒ Object



51
52
53
# File 'lib/models/ib/spread.rb', line 51

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



129
130
131
132
133
134
135
# File 'lib/models/ib/spread.rb', line 129

def con_id
	if attributes[:con_id].present? && attributes[] < 0
		attributes[:con_id]
	else
		-legs.map{ |x| x.is_a?(String) ? x.expand.con_id : x.con_id}.sum
	end
end

#essentialObject

essentail effectivley clones the object



116
117
118
119
120
121
122
# File 'lib/models/ib/spread.rb', line 116

def essential
    the_es = self.class.new invariant_attributes
    the_es.legs = legs.map{|y| IB::Contract.build y.invariant_attributes}
    the_es.combo_legs = combo_legs.map{|y| IB::ComboLeg.new y.invariant_attributes }
    the_es.description = description
    the_es  # return
end

#fake_portfolio_position(array_of_portfolio_values) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/models/ib/spread.rb', line 55

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



124
125
126
# File 'lib/models/ib/spread.rb', line 124

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

#non_guaranteedObject



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

def non_guaranteed
   	combo_params['NonGuaranteed']
end

#non_guaranteed=(x) ⇒ Object



138
139
140
# File 'lib/models/ib/spread.rb', line 138

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

#remove_leg(contract_or_position = nil) ⇒ Object

removes the contract from the spread definition



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/models/ib/spread.rb', line 97

def remove_leg contract_or_position = nil
    contract = if contract_or_position.is_a? (IB::Contract)
                 contract_or_position
               elsif contract_or_position.is_a? Numeric
                 legs.at contract_or_position
               else
                 error "Specify a contract to be removed or the position in the legs-array as parameter to remove a leg"
    end
    the_con_id = contract.verify.first &.con_id
    error "Invalid Contract specified" unless the_con_id.is_a? Numeric
    legs.delete_if { |x| x.con_id == the_con_id }
    combo_legs.delete_if { |x| x.con_id == the_con_id }
    self.description = description + " removed #{contract.to_human}"
    self   # make method chainable
end

#to_humanObject

def



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

def to_human
	self.description
end