ib-extensions 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,159 +0,0 @@
1
- require 'ib/verify'
2
- module IB
3
- class Spread < Bag
4
- has_many :legs
5
-
6
- using IBSupport
7
-
8
- =begin
9
- Parameters: front: YYYMM(DD)
10
- back: {n}w, {n}d or YYYYMM(DD)
11
-
12
- Adds (or substracts) relative (back) measures to the front month, just passes absolute YYYYMM(DD) value
13
-
14
- front: 201809 back: 2m (-1m) --> 201811 (201808)
15
- front: 20180908 back: 1w (-1w) --> 20180918 (20180902)
16
- =end
17
-
18
- def transform_distance front, back
19
- # Check Format of back: 201809 --> > 200.000
20
- # 20180989 ---> 20.000.000
21
- start_date = front.to_i < 20000000 ? Date.strptime(front.to_s,"%Y%m") : Date.strptime(front.to_s,"%Y%m%d")
22
- nb = if back.to_i > 200000
23
- back.to_i
24
- elsif back[-1] == "w" && front.to_i > 20000000
25
- start_date + (back.to_i * 7)
26
- elsif back[-1] == "m" && front.to_i > 200000
27
- start_date >> back.to_i
28
- else
29
- error "Wrong date #{back} required format YYYMM, YYYYMMDD ord {n}w or {n}m"
30
- end
31
- if nb.is_a?(Date)
32
- if back[-1]=='w'
33
- nb.strftime("%Y%m%d")
34
- else
35
- nb.strftime("%Y%m")
36
- end
37
- else
38
- nb
39
- end
40
- end # def
41
-
42
- def to_human
43
- self.description
44
- end
45
-
46
- def calculate_spread_value( array_of_portfolio_values )
47
- array_of_portfolio_values.map{|x| x.send yield }.sum if block_given?
48
- end
49
-
50
- def fake_portfolio_position( array_of_portfolio_values )
51
- calculate_spread_value= ->( a_o_p_v, attribute ) do
52
- a_o_p_v.map{|x| x.send attribute }.sum
53
- end
54
- ar=array_of_portfolio_values
55
- IB::PortfolioValue.new contract: self,
56
- average_cost: calculate_spread_value[ar, :average_cost],
57
- market_price: calculate_spread_value[ar, :market_price],
58
- market_value: calculate_spread_value[ar, :market_value],
59
- unrealized_pnl: calculate_spread_value[ar, :unrealized_pnl],
60
- realized_pnl: calculate_spread_value[ar, :realized_pnl],
61
- position: 0
62
-
63
- end
64
-
65
-
66
-
67
- def serialize_rabbit
68
- { "Spread" => serialize( :option, :trading_class ),
69
- 'legs' => legs.map{ |y| y.serialize :option, :trading_class }, 'combo_legs' => combo_legs.map(&:serialize),
70
- 'misc' => [description]
71
- }
72
- end
73
-
74
- # adds a leg to any spread
75
- #
76
- # Parameter:
77
- # contract: Will be verified. Contract.essential is added to legs-array
78
- # action: :buy or :sell
79
- # weight:
80
- # ratio:
81
- #
82
- # Default: action: :buy, weight: 1
83
-
84
- def add_leg contract, **leg_params
85
- evaluated_contracts = []
86
- nc = contract.verify.first.essential
87
- # weigth = 1 --> sets Combo.side to buy and overwrites the action statement
88
- # leg_params[:weight] = 1 unless leg_params.key?(:weight) || leg_params.key?(:ratio)
89
- if nc.is_a?( IB::Contract) && nc.con_id.present?
90
- the_leg= ComboLeg.new( nc.attributes.slice( :con_id, :exchange )
91
- .merge( leg_params ))
92
- self.combo_legs << the_leg
93
- self.description = description + " added #{nc.to_human}" rescue "Spread: #{nc.to_human}"
94
- self.legs << nc
95
- end
96
- self # return value to enable chaining
97
-
98
-
99
- end
100
-
101
- # removes the contract from the spread definition
102
- #
103
- def remove_leg contract
104
- contract.verify do |c|
105
- legs.delete_if { |x| x.con_id == c.con_id }
106
- combo_legs.delete_if { |x| x.con_id == c.con_id }
107
- self.description = description + " removed #{c.to_human}"
108
- end
109
- self
110
- end
111
-
112
-
113
- def essential
114
- legs.each{ |x| x.essential }
115
- self
116
- end
117
- def multiplier
118
- (legs.map(&:multiplier).sum/legs.size).to_i
119
- end
120
-
121
- # provide a negative con_id
122
- def con_id
123
- -legs.map(&:con_id).sum
124
- end
125
-
126
-
127
- def non_guaranteed= x
128
- super.merge combo_params: [ ['NonGuaranteed', x] ]
129
- end
130
-
131
-
132
- def non_guaranteed
133
- combo_params['NonGuaranteed']
134
- end
135
- # optional: specify default order prarmeters for all spreads
136
- # def order_requirements
137
- # super.merge symbol: symbol
138
- # end
139
-
140
-
141
- def self.build_from_json container
142
- read_leg = ->(a) do
143
- IB::ComboLeg.new :con_id => a.read_int,
144
- :ratio => a.read_int,
145
- :action => a.read_string,
146
- :exchange => a.read_string
147
-
148
- end
149
- object= self.new container['Spread'].read_contract
150
- object.legs = container['legs'].map{|x| IB::Contract.build x.read_contract}
151
- object.combo_legs = container['combo_legs'].map{ |x| read_leg[ x ] }
152
- object.description = container['misc'].read_string
153
- object
154
-
155
- end
156
- end
157
-
158
-
159
- end