iron_warbler 2.0.7.25 → 2.0.7.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|