iron_warbler 2.0.7.25 → 2.0.7.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/iron_warbler/Card.scss +6 -0
- data/app/assets/stylesheets/iron_warbler/positions.scss +1 -1
- data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
- data/app/controllers/iro/application_controller.rb +6 -0
- data/app/controllers/iro/positions_controller.rb +183 -200
- data/app/controllers/iro/purses_controller.rb +3 -1
- data/app/controllers/iro/stocks_controller.rb +2 -2
- data/app/models/iro/option.rb +38 -150
- data/app/models/iro/option_black_scholes.rb +149 -0
- data/app/models/iro/position.rb +154 -209
- data/app/models/iro/purse.rb +34 -4
- data/app/models/iro/strategy.rb +49 -47
- data/app/views/iro/_main_header.haml +4 -2
- data/app/views/iro/options/_show_mini.haml +8 -0
- data/app/views/iro/positions/_form.haml +8 -3
- data/app/views/iro/positions/_formpart_4data.haml +41 -38
- data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +4 -4
- data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
- data/app/views/iro/positions/_header.haml +2 -0
- data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
- data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +2 -3
- data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
- data/app/views/iro/positions/_table.haml +25 -26
- data/app/views/iro/positions/prepare.haml +6 -4
- data/app/views/iro/positions/prepare2.haml +15 -4
- data/app/views/iro/purses/_form_extra_fields.haml +7 -3
- data/app/views/iro/purses/_header.haml +19 -5
- data/app/views/iro/purses/_summary.haml +69 -62
- data/app/views/iro/purses/show.haml +1 -1
- data/app/views/iro/strategies/_form.haml +26 -19
- data/app/views/iro/strategies/_show.haml +6 -4
- data/config/routes.rb +5 -3
- metadata +7 -2
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4afc65383198cc16143683cc82db6ee65604f14a8d13d4d7bc262210ceb14940
|
4
|
+
data.tar.gz: 04c7d9a3585dd1036c8f227a1cbbe38fbc6e7d71f68977f3183ac07bdbaba3cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a905e844e0542aa1f7500c1c1bc25a234f2698bc8bfb1e75d83fb7ab2ba24dcc28ed261a876f1add4d9dec80decb32cb84ed1694ac3b8e3657be48f8a36b86bc
|
7
|
+
data.tar.gz: d9478f1d454dbcbee3b6fc703233f7d72049ac128f1ad2e550e38286483ccc51a863e8ace598511c2c28a6ce8a26240215d97ff2d524e5a3e03dcbdc5fb1eb40
|
@@ -40,32 +40,38 @@
|
|
40
40
|
.summary-amount {
|
41
41
|
position: relative;
|
42
42
|
width: 100px;
|
43
|
+
margin-right: 2em;
|
43
44
|
|
44
45
|
.net-gl {
|
45
46
|
width: 100%;
|
46
47
|
background: rgba(0,0,0, 0.5);
|
47
48
|
}
|
48
|
-
}
|
49
|
-
.summary-delta {
|
50
|
-
position: relative;
|
51
|
-
margin-right: 1em;
|
52
|
-
width: 1em;
|
53
49
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
width: 1em;
|
50
|
+
.delta {
|
51
|
+
position: absolute;
|
52
|
+
left: 100px;
|
53
|
+
height: 100%;
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
55
|
+
> div {
|
56
|
+
border: 1px dotted yellow;
|
57
|
+
width: 0.5em;
|
58
|
+
}
|
59
|
+
.begin {
|
60
|
+
width: 1em;
|
65
61
|
|
66
|
-
|
62
|
+
background: black;
|
63
|
+
}
|
64
|
+
.end {
|
65
|
+
width: .5em;
|
66
|
+
left: .25em;
|
67
|
+
|
68
|
+
background: rgba(255,0,0, 0.5);
|
69
|
+
}
|
67
70
|
}
|
71
|
+
|
68
72
|
}
|
73
|
+
|
74
|
+
|
69
75
|
.loss {
|
70
76
|
}
|
71
77
|
.gain {
|
@@ -73,12 +79,18 @@
|
|
73
79
|
.max-gl {
|
74
80
|
position: absolute;
|
75
81
|
width: 100%;
|
82
|
+
|
83
|
+
label {
|
84
|
+
position: absolute;
|
85
|
+
}
|
86
|
+
|
87
|
+
|
76
88
|
}
|
77
89
|
.max-gl.long {
|
78
|
-
background: rgba(255,0,0, 0.5);
|
79
90
|
}
|
80
|
-
.max-gl
|
81
|
-
|
91
|
+
.max-gl.short {
|
92
|
+
display: flex;
|
93
|
+
flex-direction: column-reverse;
|
82
94
|
}
|
83
95
|
.long {
|
84
96
|
position: absolute;
|
@@ -1,4 +1,9 @@
|
|
1
1
|
|
2
|
+
Pu ||= Iro::Purse
|
3
|
+
Str ||= Iro::Strategy
|
4
|
+
Po ||= Iro::Position
|
5
|
+
O ||= Iro::Option
|
6
|
+
Sto ||= Iro::Stock
|
2
7
|
|
3
8
|
class Iro::ApplicationController < Wco::ApplicationController
|
4
9
|
layout 'iro/application'
|
@@ -17,6 +22,7 @@ class Iro::ApplicationController < Wco::ApplicationController
|
|
17
22
|
def set_lists
|
18
23
|
@purses = Iro::Purse.all
|
19
24
|
@strategies = Iro::Strategy.all
|
25
|
+
@strategies_list = Iro::Strategy.list
|
20
26
|
end
|
21
27
|
|
22
28
|
|
@@ -2,35 +2,23 @@
|
|
2
2
|
class Iro::PositionsController < Iro::ApplicationController
|
3
3
|
before_action :set_lists
|
4
4
|
|
5
|
-
def new
|
6
|
-
@position = Iro::Position.new
|
7
|
-
authorize! :new, @posision
|
8
|
-
|
9
|
-
if params[:id]
|
10
|
-
old = Iro::Position.find params[:id]
|
11
|
-
old = old.attributes
|
12
|
-
old.delete :_id
|
13
|
-
puts! old, 'old'
|
14
|
-
@position = Iro::Position.new old
|
15
|
-
end
|
16
|
-
if params[:purse_id]
|
17
|
-
@position.purse_id = params[:purse_id]
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
5
|
def create
|
23
|
-
@position = Iro::Position.new
|
6
|
+
pos = @position = Iro::Position.new pos_params
|
7
|
+
o_attrs = {
|
8
|
+
expires_on: pos.expires_on,
|
9
|
+
put_call: pos.put_call,
|
10
|
+
stock_id: pos.stock_id,
|
11
|
+
}
|
12
|
+
pos.inner = Iro::Option.new params[:inner].permit!.merge( o_attrs )
|
13
|
+
pos.outer = Iro::Option.new params[:outer].permit!.merge( o_attrs )
|
24
14
|
authorize! :create, @position
|
25
15
|
|
26
|
-
@position.sync
|
27
|
-
|
28
16
|
if @position.save
|
29
17
|
flash_notice @position
|
30
18
|
redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
|
31
19
|
else
|
32
20
|
flash_alert @position
|
33
|
-
redirect_to request.referrer
|
21
|
+
render action: :new # redirect_to request.referrer
|
34
22
|
end
|
35
23
|
end
|
36
24
|
|
@@ -47,73 +35,72 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
47
35
|
authorize! :edit, @position
|
48
36
|
end
|
49
37
|
|
50
|
-
|
51
|
-
|
52
|
-
@
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
contractType: 'PUT',
|
60
|
-
expirationDate: '2024-03-28',
|
61
|
-
ticker: @strategy.stock.ticker,
|
62
|
-
})
|
63
|
-
outs = outs.select do |out|
|
64
|
-
out[:bidSize]+out[:askSize] > 0
|
65
|
-
end
|
66
|
-
outs = outs.select do |out|
|
67
|
-
out[:strikePrice] > @strategy.buffer_above_water + @strategy.stock.last
|
68
|
-
end
|
69
|
-
outs = outs.select do |out|
|
70
|
-
out[:strikePrice] > @strategy.next_inner_strike
|
71
|
-
end
|
72
|
-
outs = outs.select do |out|
|
73
|
-
out[:delta] < @strategy.next_inner_delta
|
74
|
-
end
|
38
|
+
def new
|
39
|
+
strategy = Iro::Strategy.find params[:position][:strategy_id]
|
40
|
+
@position = Iro::Position.new( params[:position].permit!.merge({
|
41
|
+
status: :active,
|
42
|
+
inner: Iro::Option.new,
|
43
|
+
outer: Iro::Option.new,
|
44
|
+
stock_id: strategy.stock_id,
|
45
|
+
}) )
|
46
|
+
authorize! :new, @posision
|
75
47
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if inner && outer
|
83
|
-
next_position = Iro::Position.new({
|
84
|
-
status: 'proposed',
|
85
|
-
stock: @strategy.stock,
|
86
|
-
inner_strike: inner[:strikePrice],
|
87
|
-
outer_strike: outer[:strikePrice],
|
88
|
-
begin_outer_price: outer[:last],
|
89
|
-
begin_outer_delta: outer[:delta],
|
90
|
-
begin_inner_price: inner[:last],
|
91
|
-
begin_inner_delta: inner[:delta],
|
92
|
-
begin_on: Time.now.to_date,
|
93
|
-
expires_on: '2024-03-28',
|
94
|
-
purse: @purse,
|
95
|
-
strategy: @strategy,
|
96
|
-
quantity: 1,
|
97
|
-
})
|
98
|
-
next_position.sync
|
99
|
-
next_position.save
|
100
|
-
else
|
101
|
-
flash_alert 'cannot propose a new one'
|
48
|
+
if params[:id]
|
49
|
+
old = Iro::Position.find params[:id]
|
50
|
+
old = old.attributes
|
51
|
+
old.delete :_id
|
52
|
+
puts! old, 'old'
|
53
|
+
@position = Iro::Position.new old
|
102
54
|
end
|
103
|
-
redirect_to request.referrer
|
104
55
|
end
|
105
56
|
|
106
|
-
def
|
107
|
-
@position =
|
108
|
-
authorize! :
|
57
|
+
def prepare
|
58
|
+
@position = Iro::Position.find params[:id]
|
59
|
+
authorize! :roll, @position
|
109
60
|
|
110
|
-
@position
|
111
|
-
@position.
|
61
|
+
@prev = @position
|
62
|
+
@purse = @position.purse
|
63
|
+
@stock = @position.stock
|
64
|
+
@n_dollars = 100
|
112
65
|
|
113
|
-
|
66
|
+
## dealing with too many strikes in the chain
|
67
|
+
while true
|
68
|
+
@nn = ( @position.purse.n_next_positions/2 ).ceil
|
69
|
+
upper = Tda::Option.get_quote({
|
70
|
+
contractType: @position.put_call,
|
71
|
+
strike: @prev.inner.strike + @nn*@stock.options_price_increment,
|
72
|
+
expirationDate: @prev.next_expires_on,
|
73
|
+
ticker: @stock.ticker,
|
74
|
+
})
|
75
|
+
if !upper.symbol
|
76
|
+
puts! 'too high'
|
77
|
+
flash_alert 'too high'
|
78
|
+
@purse.n_next_positions = @purse.n_next_positions - 1
|
79
|
+
@purse.n_next_positions = 1 if @purse.n_next_positions < 1
|
80
|
+
@purse.save!
|
81
|
+
next
|
82
|
+
end
|
83
|
+
lower = Tda::Option.get_quote({
|
84
|
+
contractType: @position.put_call,
|
85
|
+
strike: @prev.inner.strike - @nn*@stock.options_price_increment,
|
86
|
+
expirationDate: @prev.next_expires_on,
|
87
|
+
ticker: @stock.ticker,
|
88
|
+
})
|
89
|
+
if !lower.symbol
|
90
|
+
puts! 'too low'
|
91
|
+
flash_alert 'too low'
|
92
|
+
@purse.n_next_positions = @purse.n_next_positions - 1
|
93
|
+
@purse.n_next_positions = 1 if @purse.n_next_positions < 1
|
94
|
+
@purse.save!
|
95
|
+
next
|
96
|
+
end
|
97
|
+
break
|
98
|
+
end
|
99
|
+
|
100
|
+
self.send("_prepare_#{@position.strategy.kind}")
|
114
101
|
end
|
115
102
|
|
116
|
-
|
103
|
+
## long debit call spread
|
117
104
|
def prepare2
|
118
105
|
@position = Iro::Position.find params[:id]
|
119
106
|
authorize! :roll, @position
|
@@ -121,119 +108,83 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
121
108
|
pos = @position
|
122
109
|
stock = @position.stock
|
123
110
|
|
124
|
-
next_outer = @position.outer || Iro::Option.create({
|
125
|
-
stock: stock,
|
126
|
-
strike: pos.outer_strike,
|
127
|
-
expires_on: pos.expires_on,
|
128
|
-
position: pos,
|
129
|
-
last: pos.begin_outer_price,
|
130
|
-
})
|
131
|
-
|
132
|
-
next_inner = @position.inner || Iro::Option.create({
|
133
|
-
stock: stock,
|
134
|
-
strike: pos.inner_strike,
|
135
|
-
expires_on: pos.expires_on,
|
136
|
-
position: pos,
|
137
|
-
last: pos.begin_inner_price,
|
138
|
-
})
|
139
|
-
|
140
|
-
prev_outer = pos.prev.outer
|
141
|
-
prev_inner = pos.prev.inner
|
142
|
-
|
143
|
-
price = pos.prev.outer.last - pos.prev.inner.last + pos.nxt.inner.last - pos.nxt.outer.last
|
144
|
-
|
145
111
|
@query = {
|
146
|
-
orderType: "NET_DEBIT",
|
112
|
+
orderType: price > 0 ? "NET_CREDIT" : "NET_DEBIT",
|
147
113
|
session: "NORMAL",
|
148
114
|
price: price,
|
149
115
|
duration: "DAY",
|
150
116
|
orderStrategyType: "SINGLE",
|
151
117
|
orderLegCollection: [
|
152
|
-
##
|
118
|
+
## close
|
119
|
+
{
|
120
|
+
instruction: "BUY_TO_CLOSE",
|
121
|
+
quantity: pos.q,
|
122
|
+
instrument: {
|
123
|
+
symbol: pos.autoprev.inner.symbol,
|
124
|
+
assetType: "OPTION",
|
125
|
+
},
|
126
|
+
},
|
127
|
+
{
|
128
|
+
instruction: "SELL_TO_CLOSE",
|
129
|
+
quantity: pos.q,
|
130
|
+
instrument: {
|
131
|
+
symbol: pos.autoprev.outer.symbol,
|
132
|
+
assetType: "OPTION",
|
133
|
+
},
|
134
|
+
},
|
135
|
+
|
136
|
+
## open
|
153
137
|
{
|
154
138
|
instruction: "BUY_TO_OPEN",
|
155
|
-
quantity: q,
|
139
|
+
quantity: pos.q,
|
156
140
|
instrument: {
|
157
|
-
symbol: outer.symbol,
|
141
|
+
symbol: pos.outer.symbol,
|
158
142
|
assetType: "OPTION",
|
159
143
|
},
|
160
144
|
},
|
161
145
|
{
|
162
146
|
instruction: "SELL_TO_OPEN",
|
163
|
-
quantity: q,
|
147
|
+
quantity: pos.q,
|
164
148
|
instrument: {
|
165
|
-
symbol: inner.symbol,
|
149
|
+
symbol: pos.inner.symbol,
|
166
150
|
assetType: "OPTION",
|
167
151
|
},
|
168
152
|
},
|
169
153
|
],
|
170
154
|
}
|
155
|
+
puts! @query, '@query'
|
171
156
|
end
|
172
157
|
|
173
|
-
|
158
|
+
## long debit call spread
|
174
159
|
def prepare3
|
175
|
-
|
176
|
-
|
160
|
+
pos = @position = Iro::Position.find params[:id]
|
161
|
+
authorize! :place_order, @position
|
177
162
|
|
178
|
-
|
179
|
-
@position = Iro::Position.find params[:id]
|
180
|
-
authorize! :roll, @position
|
163
|
+
# out = Tda::Option.roll_long_debit_call_spread( position )
|
181
164
|
|
182
|
-
@
|
183
|
-
@purse = @position.purse
|
184
|
-
@stock = @position.stock
|
185
|
-
@n_dollars = 100
|
165
|
+
## @TODO: it's pending here, the order has not been placed.
|
186
166
|
|
187
|
-
|
188
|
-
@next_expires_on = @prev.expires_on.to_datetime.next_occurring(:monday).next_occurring(:friday)
|
189
|
-
if !@next_expires_on.workday?
|
190
|
-
@next_expires_on = Time.previous_business_day( @next_expires_on )
|
191
|
-
end
|
167
|
+
flags = []
|
192
168
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
strike: @prev.inner_strike + @nn*@stock.options_price_increment,
|
199
|
-
expirationDate: @next_expires_on,
|
200
|
-
ticker: @stock.ticker,
|
201
|
-
})
|
202
|
-
if !upper.symbol
|
203
|
-
puts! 'too high'
|
204
|
-
flash_alert 'too high'
|
205
|
-
@purse.n_next_positions = @purse.n_next_positions - 1
|
206
|
-
@purse.n_next_positions = 1 if @purse.n_next_positions < 1
|
207
|
-
@purse.save!
|
208
|
-
next
|
209
|
-
end
|
210
|
-
lower = Tda::Option.get_quote({
|
211
|
-
contractType: 'CALL',
|
212
|
-
strike: @prev.inner_strike - @nn*@stock.options_price_increment,
|
213
|
-
expirationDate: @next_expires_on,
|
214
|
-
ticker: @stock.ticker,
|
215
|
-
})
|
216
|
-
if !lower.symbol
|
217
|
-
puts! 'too low'
|
218
|
-
flash_alert 'too low'
|
219
|
-
@purse.n_next_positions = @purse.n_next_positions - 1
|
220
|
-
@purse.n_next_positions = 1 if @purse.n_next_positions < 1
|
221
|
-
@purse.save!
|
222
|
-
next
|
223
|
-
end
|
224
|
-
break
|
225
|
-
end
|
169
|
+
flags.push pos.prev.update({ status: Iro::Position::STATUS_CLOSED })
|
170
|
+
flags.push pos.update({ status: Iro::Position::STATUS_ACTIVE })
|
171
|
+
flags.push pos.purse.update({
|
172
|
+
available_amount: pos.purse.available_amount + price + pos.q*100,
|
173
|
+
})
|
226
174
|
|
227
|
-
|
175
|
+
flash_notice flags
|
176
|
+
redirect_to controller: :purses, action: :show, template: :gameui, id: pos.purse_id
|
228
177
|
end
|
229
178
|
|
179
|
+
|
180
|
+
|
230
181
|
def _prepare_covered_call
|
231
182
|
@positions = []
|
232
183
|
(-@nn..@nn).each do |idx|
|
233
184
|
next_ = Iro::Position.new({
|
234
185
|
stock: @stock,
|
235
|
-
inner_strike: @prev.
|
236
|
-
expires_on: @next_expires_on,
|
186
|
+
inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
|
187
|
+
expires_on: @prev.next_expires_on,
|
237
188
|
purse: @position.purse,
|
238
189
|
strategy: @position.strategy,
|
239
190
|
quantity: @position.quantity,
|
@@ -242,8 +193,6 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
242
193
|
next_.begin_inner_price = next_.end_inner_price
|
243
194
|
next_.begin_inner_delta = next_.end_inner_delta
|
244
195
|
next_.next_gain_loss_amount = next_.begin_inner_price - @prev.end_inner_price
|
245
|
-
puts! next_, 'next_'
|
246
|
-
puts! next_.next_gain_loss_amount, 'amount'
|
247
196
|
@positions.push next_
|
248
197
|
end
|
249
198
|
end
|
@@ -252,63 +201,82 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
252
201
|
@positions = []
|
253
202
|
(-@nn..@nn).each do |idx|
|
254
203
|
next_ = Iro::Position.find_or_create_by({
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
expires_on: @next_expires_on,
|
204
|
+
expires_on: @prev.next_expires_on,
|
205
|
+
inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
|
206
|
+
outer_strike: @prev.outer.strike - idx*@stock.options_price_increment,
|
207
|
+
prev_id: @prev.id,
|
260
208
|
purse: @position.purse,
|
261
|
-
strategy: @position.strategy,
|
262
209
|
quantity: @position.quantity,
|
263
|
-
|
210
|
+
status: 'prepare',
|
211
|
+
stock: @stock,
|
212
|
+
strategy: @position.strategy,
|
213
|
+
})
|
214
|
+
pos = next_
|
215
|
+
next_.inner ||= Iro::Option.new({
|
216
|
+
# begin_price: pos[:begin_inner_price],
|
217
|
+
# begin_delta: pos[:begin_inner_delta],
|
218
|
+
expires_on: pos[:expires_on],
|
219
|
+
inner: pos,
|
220
|
+
put_call: pos.put_call,
|
221
|
+
stock_id: pos[:stock_id],
|
222
|
+
strike: pos[:inner_strike],
|
264
223
|
})
|
224
|
+
next_.outer ||= Iro::Option.new({
|
225
|
+
# begin_price: pos[:begin_inner_price],
|
226
|
+
# begin_delta: pos[:begin_inner_delta],
|
227
|
+
expires_on: pos[:expires_on],
|
228
|
+
outer: pos,
|
229
|
+
put_call: pos.put_call,
|
230
|
+
stock_id: pos[:stock_id],
|
231
|
+
strike: pos[:outer_strike],
|
232
|
+
})
|
233
|
+
|
265
234
|
next_.sync
|
266
|
-
next_.
|
267
|
-
next_.
|
235
|
+
next_.inner.begin_price = next_.inner.end_price
|
236
|
+
next_.inner.begin_delta = next_.inner.end_delta
|
237
|
+
|
238
|
+
next_.outer.begin_price = next_.outer.end_price
|
239
|
+
next_.outer.begin_delta = next_.outer.end_delta
|
268
240
|
|
269
|
-
next_.
|
270
|
-
next_.
|
271
|
-
next_.next_gain_loss_amount = @prev.end_outer_price - @prev.end_inner_price
|
272
|
-
next_.next_gain_loss_amount += next_.begin_inner_price - next_.begin_outer_price
|
241
|
+
next_.next_gain_loss_amount = @prev.outer.end_price - @prev.inner.end_price
|
242
|
+
next_.next_gain_loss_amount += next_.inner.begin_price - next_.outer.begin_price
|
273
243
|
next_.save
|
274
|
-
puts! next_, 'next_'
|
275
|
-
puts! next_.next_gain_loss_amount, 'next_gain_loss_amount'
|
276
244
|
@positions.push next_
|
277
245
|
end
|
278
246
|
@positions = @positions.reverse
|
279
247
|
end
|
248
|
+
alias_method :_prepare_short_debit_put_spread, :_prepare_long_debit_call_spread
|
280
249
|
|
281
|
-
def _prepare_short_debit_put_spread
|
282
|
-
@positions = []
|
283
|
-
(-@nn..@nn).each do |idx|
|
284
|
-
next_ = Iro::Position.new({
|
285
|
-
stock: @stock,
|
286
|
-
inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
|
287
|
-
outer_strike: @prev.outer_strike - idx*@stock.options_price_increment,
|
288
|
-
expires_on: @next_expires_on,
|
289
|
-
purse: @position.purse,
|
290
|
-
strategy: @position.strategy,
|
291
|
-
quantity: @position.quantity,
|
292
|
-
})
|
293
|
-
next_.sync
|
294
|
-
next_.begin_inner_price = next_.end_inner_price
|
295
|
-
next_.begin_inner_delta = next_.end_inner_delta
|
296
250
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
251
|
+
def sync
|
252
|
+
@position = pos = Iro::Position.find params[:id]
|
253
|
+
authorize! :refresh, @position
|
254
|
+
|
255
|
+
@position.sync
|
256
|
+
@position.calc_rollp
|
257
|
+
if true # @position.rollp > 0.5
|
258
|
+
@position.calc_nxt
|
304
259
|
end
|
260
|
+
|
261
|
+
redirect_to request.referrer || purse_path( @position.purse )
|
305
262
|
end
|
306
263
|
|
264
|
+
##
|
265
|
+
## only updates some attributes
|
266
|
+
##
|
307
267
|
def update
|
308
|
-
@position = Iro::Position.find params[:id]
|
268
|
+
pos = @position = Iro::Position.find params[:id]
|
309
269
|
authorize! :update, @position
|
310
270
|
|
311
|
-
if @position.update
|
271
|
+
if @position.update pos_params
|
272
|
+
o_attrs = {
|
273
|
+
expires_on: pos.expires_on,
|
274
|
+
put_call: pos.put_call,
|
275
|
+
stock_id: pos.stock_id,
|
276
|
+
}
|
277
|
+
pos.inner.update params[:inner].permit!.merge( o_attrs )
|
278
|
+
pos.outer.update params[:outer].permit!.merge( o_attrs )
|
279
|
+
|
312
280
|
flash_notice @position
|
313
281
|
redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
|
314
282
|
else
|
@@ -317,14 +285,29 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
317
285
|
end
|
318
286
|
end
|
319
287
|
|
288
|
+
|
289
|
+
|
320
290
|
##
|
321
291
|
## private
|
322
292
|
##
|
323
293
|
private
|
324
294
|
|
295
|
+
def pos_params
|
296
|
+
params[:position].permit( :purse_id, :status, :stock_id,
|
297
|
+
:strategy_id, :expires_on, :quantity, :begin_on,
|
298
|
+
:long_or_short,
|
299
|
+
)
|
300
|
+
end
|
301
|
+
|
302
|
+
def price
|
303
|
+
pos = @position
|
304
|
+
out = pos.autoprev.outer.end_price - pos.autoprev.inner.end_price + pos.inner.begin_price - pos.outer.begin_price
|
305
|
+
return out
|
306
|
+
end
|
307
|
+
|
308
|
+
|
325
309
|
def set_lists
|
326
310
|
super
|
327
|
-
|
328
311
|
@purses_list = Iro::Purse.list
|
329
312
|
@strategies_list = Iro::Strategy.list(params[:long_or_short])
|
330
313
|
@stocks_list = Iro::Stock.list
|
@@ -35,8 +35,10 @@ class Iro::PursesController < Iro::ApplicationController
|
|
35
35
|
@purse = Iro::Purse.find(params[:id])
|
36
36
|
authorize! :show, @purse
|
37
37
|
|
38
|
+
|
38
39
|
@positions = @purse.positions.where( status: 'active' ).includes( :strategy
|
39
|
-
).order(
|
40
|
+
).order( expires_on: :asc, ticker: :desc, long_or_short: :asc, inner_strike: :asc )
|
41
|
+
|
40
42
|
|
41
43
|
@unit = @purse.unit # 12 ## pixels per dollar
|
42
44
|
@height = @purse.height # 100 ## pixels
|
@@ -32,14 +32,14 @@ class Iro::StocksController < Iro::ApplicationController
|
|
32
32
|
authorize! :new, @stock
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
35
|
+
def sync
|
36
36
|
authorize! :refresh, Iro::Stock
|
37
37
|
tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
|
38
38
|
outs = Tda::Stock.get_quotes tickers
|
39
39
|
outs.map do |out|
|
40
40
|
Iro::Stock.where( ticker: out[:symbol] ).update( last: out[:last] )
|
41
41
|
end
|
42
|
-
flash_notice '
|
42
|
+
flash_notice 'refreshed stocks'
|
43
43
|
redirect_to request.referrer
|
44
44
|
end
|
45
45
|
|