iron_warbler 2.0.7.43 → 2.0.7.46
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/utils.scss +9 -9
- data/app/controllers/iro/api_controller.rb +9 -4
- data/app/controllers/iro/positions_controller.rb +68 -11
- data/app/controllers/iro/purses_controller.rb +7 -2
- data/app/controllers/iro/stocks_controller.rb +5 -1
- data/app/controllers/iro/strategies_controller.rb +9 -3
- data/app/models/tda/option.rb +4 -4
- data/app/views/iro/positions/_form.haml +21 -12
- data/app/views/iro/positions/_gameui_long_credit_put_spread.haml +1 -40
- data/app/views/iro/positions/{_gameui_short_debit_put_spread.haml-trash → _gameui_spread.haml} +9 -6
- data/app/views/iro/positions/_header_spread.haml +12 -0
- data/app/views/iro/positions/_new.haml +5 -0
- data/app/views/iro/positions/_table.haml +4 -5
- data/app/views/iro/positions/{_gameui_long_debit_call_spread.haml-trash → done/_gameui_long_credit_put_spread.haml} +8 -8
- data/app/views/iro/positions/done/_gameui_short_debit_put_spread.haml +1 -0
- data/app/views/iro/positions/done/_header_short_debit_put_spread.haml +1 -0
- data/app/views/iro/purses/_form.haml +3 -3
- data/app/views/iro/purses/_header.haml +10 -2
- data/app/views/iro/purses/index.haml +3 -2
- data/app/views/iro/stocks/_show_card.haml +4 -0
- data/app/views/iro/strategies/_form.haml +25 -13
- data/app/views/iro/strategies/_form_spread.haml +74 -0
- data/app/views/iro/strategies/_form_wheel.haml +60 -0
- data/app/views/iro/strategies/_header.haml +3 -1
- data/app/views/iro/strategies/_show.haml +2 -2
- data/app/views/iro/strategies/_table.haml +7 -7
- data/app/views/iro/strategies/edit.haml +9 -1
- data/app/views/iro/strategies/index.haml +4 -2
- data/app/views/iro/strategies/new.haml +5 -1
- data/app/views/iro/strategies/show.haml +3 -1
- data/app/views/layouts/iro/application.haml +1 -1
- data/config/routes.rb +3 -1
- data/lib/iron_warbler.rb +2 -1
- data/lib/tasks/iro_tasks.rake +6 -0
- metadata +21 -28
- data/app/models/iro/alert.rb +0 -63
- data/app/models/iro/datapoint.rb +0 -187
- data/app/models/iro/date.rb +0 -10
- data/app/models/iro/option.rb +0 -151
- data/app/models/iro/option_black_scholes.rb +0 -149
- data/app/models/iro/position.rb +0 -299
- data/app/models/iro/priceitem.rb +0 -93
- data/app/models/iro/purse.rb +0 -72
- data/app/models/iro/stock.rb +0 -134
- data/app/models/iro/strategy.rb +0 -264
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -1
- data/app/views/iro/positions/_header_short_debit_put_spread.haml +0 -1
- data/app/views/iro/positions/roll.haml-trash +0 -42
- /data/app/views/iro/positions/{_gameui_covered_call.haml-bk → done/_gameui_covered_call.haml-bk} +0 -0
- /data/app/views/iro/positions/{_gameui_long_debit_call_spread.haml → done/_gameui_long_debit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{_gameui_short_credit_call_spread.haml → done/_gameui_short_credit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{_header_long_credit_put_spread.haml → done/_header_long_credit_put_spread.haml} +0 -0
- /data/app/views/iro/positions/{_header_long_debit_call_spread.haml → done/_header_long_debit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{_header_short_credit_call_spread.haml → done/_header_short_credit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{roll-cc.haml-bk → done/roll-cc.haml-bk} +0 -0
- /data/app/views/iro/purses/{gameui.haml-bk → done/gameui.haml-bk} +0 -0
- /data/app/views/iro/purses/{gameui.haml-bk2 → done/gameui.haml-bk2} +0 -0
- /data/app/views/iro/stocks/{_grid_is_long.haml → _grid_long.haml} +0 -0
- /data/app/views/iro/stocks/{_grid_is_short.haml → _grid_short.haml} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d12cbdde8ab8b82ca08c2a009f4e464a9a8f1f2dad5f14f8bab8c68d46f3afb
|
|
4
|
+
data.tar.gz: 2b37b10d1aef00cedd8a25f237c1023fb1862ebddcac074bdce1b6f47142324e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 336486a80b29e5980463900544ecef849964c83aa5598c2fd88e71cf94af89a306d19d5f2c18b40b4d745bf02e51ecb0f754b7d42e1488a36d6d38411254a317
|
|
7
|
+
data.tar.gz: f733705fab7b7cdc24e2a3a387e667d85029a1981f39af70d6ebc4ed8ff764d178ce648be68a922198316449d25b936f57f4336231d7685b6b41a08a3d5789e5
|
|
@@ -5,28 +5,28 @@
|
|
|
5
5
|
// // content: '[LONG]';
|
|
6
6
|
// }
|
|
7
7
|
.long-or-short-item,
|
|
8
|
-
.long-or-short-container .
|
|
9
|
-
.long-or-short-container .
|
|
8
|
+
.long-or-short-container .is-long,
|
|
9
|
+
.long-or-short-container .is-short {
|
|
10
10
|
display: flex;
|
|
11
11
|
flex-direction: column;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
.long-or-short-container .
|
|
15
|
-
.
|
|
14
|
+
.long-or-short-container .is-long,
|
|
15
|
+
.is-long .long-or-short-item {
|
|
16
16
|
border-left: 3px solid var(--iro-color-long);
|
|
17
17
|
padding-left: 5px;
|
|
18
18
|
}
|
|
19
|
-
.long-or-short-container .
|
|
20
|
-
.
|
|
19
|
+
.long-or-short-container .is-short,
|
|
20
|
+
.is-short .long-or-short-item {
|
|
21
21
|
border-left: 3px solid var(--iro-color-short);
|
|
22
22
|
padding-left: 5px;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
.
|
|
25
|
+
.is-short .long-or-short-item::before {
|
|
26
26
|
// content: '[SHORT]';
|
|
27
27
|
}
|
|
28
|
-
.
|
|
29
|
-
.long-or-short-container .
|
|
28
|
+
.is-short .long-or-short-item,
|
|
29
|
+
.long-or-short-container .is-short {
|
|
30
30
|
flex-direction: column-reverse;
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -43,10 +43,15 @@ class Iro::ApiController < ActionController::Base
|
|
|
43
43
|
private
|
|
44
44
|
|
|
45
45
|
def decode_jwt
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
# puts! current_user, '#decode_jwt'
|
|
47
|
+
if current_user
|
|
48
|
+
;
|
|
49
|
+
else
|
|
50
|
+
out = JWT.decode params[:jwt_token], nil, false
|
|
51
|
+
email = out[0]['email']
|
|
52
|
+
user = User.find_by({ email: email })
|
|
53
|
+
sign_in user
|
|
54
|
+
end
|
|
50
55
|
end
|
|
51
56
|
|
|
52
57
|
def set_stock
|
|
@@ -38,6 +38,7 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
|
38
38
|
|
|
39
39
|
def new
|
|
40
40
|
strategy = Iro::Strategy.find params[:position][:strategy_id]
|
|
41
|
+
|
|
41
42
|
@position = strategy.next_position
|
|
42
43
|
@position ||= Iro::Position.new( params[:position].permit!.merge({
|
|
43
44
|
status: Iro::Position::STATUS_PROPOSED,
|
|
@@ -58,23 +59,26 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
|
58
59
|
# end
|
|
59
60
|
end
|
|
60
61
|
|
|
62
|
+
## 2025-10-14
|
|
63
|
+
## long_credit_put_spread
|
|
61
64
|
def prepare
|
|
62
65
|
@position = Iro::Position.find params[:id]
|
|
63
66
|
authorize! :roll, @position
|
|
67
|
+
@n_dollars = 100 ## used in the view, but the name is unclear
|
|
64
68
|
|
|
65
69
|
@prev = @position
|
|
66
70
|
@purse = @position.purse
|
|
67
71
|
@stock = @position.stock
|
|
68
|
-
@n_dollars = 100
|
|
69
72
|
|
|
70
73
|
## dealing with too many strikes in the chain
|
|
74
|
+
=begin
|
|
71
75
|
while true
|
|
72
|
-
@nn = ( @position.purse.n_next_positions/2 ).ceil
|
|
76
|
+
@nn = ( @position.purse.n_next_positions/2 ).ceil ## @nn == @nn_next_positions
|
|
73
77
|
upper = Tda::Option.get_quote({
|
|
74
|
-
contractType:
|
|
75
|
-
strike:
|
|
78
|
+
contractType: @position.inner.put_call,
|
|
79
|
+
strike: @prev.inner.strike + @nn*@stock.options_price_increment,
|
|
76
80
|
expirationDate: @prev.next_expires_on,
|
|
77
|
-
ticker:
|
|
81
|
+
ticker: @stock.ticker,
|
|
78
82
|
})
|
|
79
83
|
if !upper.symbol
|
|
80
84
|
puts! 'too high'
|
|
@@ -100,6 +104,7 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
|
100
104
|
end
|
|
101
105
|
break
|
|
102
106
|
end
|
|
107
|
+
=end
|
|
103
108
|
|
|
104
109
|
self.send("_prepare_#{@position.strategy.kind}")
|
|
105
110
|
end
|
|
@@ -186,12 +191,12 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
|
186
191
|
@positions = []
|
|
187
192
|
(-@nn..@nn).each do |idx|
|
|
188
193
|
next_ = Iro::Position.new({
|
|
189
|
-
stock:
|
|
194
|
+
stock: @stock,
|
|
190
195
|
inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
|
|
191
|
-
expires_on:
|
|
192
|
-
purse:
|
|
193
|
-
strategy:
|
|
194
|
-
quantity:
|
|
196
|
+
expires_on: @prev.next_expires_on,
|
|
197
|
+
purse: @position.purse,
|
|
198
|
+
strategy: @position.strategy,
|
|
199
|
+
quantity: @position.quantity,
|
|
195
200
|
})
|
|
196
201
|
next_.sync
|
|
197
202
|
next_.begin_inner_price = next_.end_inner_price
|
|
@@ -201,6 +206,58 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
|
201
206
|
end
|
|
202
207
|
end
|
|
203
208
|
|
|
209
|
+
## 2025-10-14 _TODO: move to a model?
|
|
210
|
+
## _TODO: what does this do, exactly?
|
|
211
|
+
def _prepare_long_credit_put_spread
|
|
212
|
+
## get quotes for next expires_at
|
|
213
|
+
# quotes = Tda::Option.get_quotes({ contractType: @position.put_call
|
|
214
|
+
@positions = []
|
|
215
|
+
(-@nn..@nn).each do |idx|
|
|
216
|
+
next_ = Iro::Position.find_or_create_by({
|
|
217
|
+
expires_on: @prev.next_expires_on,
|
|
218
|
+
inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
|
|
219
|
+
outer_strike: @prev.outer.strike - idx*@stock.options_price_increment,
|
|
220
|
+
prev_id: @prev.id,
|
|
221
|
+
purse: @position.purse,
|
|
222
|
+
quantity: @position.quantity,
|
|
223
|
+
status: 'prepare',
|
|
224
|
+
stock: @stock,
|
|
225
|
+
strategy: @position.strategy,
|
|
226
|
+
})
|
|
227
|
+
pos = next_
|
|
228
|
+
next_.inner ||= Iro::Option.new({
|
|
229
|
+
# begin_price: pos[:begin_inner_price],
|
|
230
|
+
# begin_delta: pos[:begin_inner_delta],
|
|
231
|
+
expires_on: pos[:expires_on],
|
|
232
|
+
inner: pos,
|
|
233
|
+
put_call: pos.put_call,
|
|
234
|
+
stock_id: pos[:stock_id],
|
|
235
|
+
strike: pos[:inner_strike],
|
|
236
|
+
})
|
|
237
|
+
next_.outer ||= Iro::Option.new({
|
|
238
|
+
# begin_price: pos[:begin_inner_price],
|
|
239
|
+
# begin_delta: pos[:begin_inner_delta],
|
|
240
|
+
expires_on: pos[:expires_on],
|
|
241
|
+
outer: pos,
|
|
242
|
+
put_call: pos.put_call,
|
|
243
|
+
stock_id: pos[:stock_id],
|
|
244
|
+
strike: pos[:outer_strike],
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
next_.sync
|
|
248
|
+
next_.inner.begin_price = next_.inner.end_price
|
|
249
|
+
next_.inner.begin_delta = next_.inner.end_delta
|
|
250
|
+
|
|
251
|
+
next_.outer.begin_price = next_.outer.end_price
|
|
252
|
+
next_.outer.begin_delta = next_.outer.end_delta
|
|
253
|
+
|
|
254
|
+
next_.next_gain_loss_amount = @prev.outer.end_price - @prev.inner.end_price
|
|
255
|
+
next_.next_gain_loss_amount += next_.inner.begin_price - next_.outer.begin_price
|
|
256
|
+
next_.save
|
|
257
|
+
@positions.push next_
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
204
261
|
def _prepare_long_debit_call_spread
|
|
205
262
|
@positions = []
|
|
206
263
|
(-@nn..@nn).each do |idx|
|
|
@@ -299,7 +356,7 @@ class Iro::PositionsController < Iro::ApplicationController
|
|
|
299
356
|
params[:position].permit( :begin_on,
|
|
300
357
|
:expires_on,
|
|
301
358
|
:long_or_short,
|
|
302
|
-
:purse_id,
|
|
359
|
+
:purse_id, :put_call,
|
|
303
360
|
:quantity,
|
|
304
361
|
:status, :stock_id, :strategy_id,
|
|
305
362
|
)
|
|
@@ -31,12 +31,17 @@ class Iro::PursesController < Iro::ApplicationController
|
|
|
31
31
|
authorize! :index, Iro::Purse
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
## table or gameui
|
|
34
35
|
def show
|
|
35
36
|
@purse = Iro::Purse.find(params[:id])
|
|
37
|
+
params[:template] = params[:template].presence || 'show'
|
|
36
38
|
authorize! :show, @purse
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
@positions = @purse.positions
|
|
41
|
+
if params[:view_status] && 'all' != params[:view_status]
|
|
42
|
+
@positions = @positions.where( status: params[:view_status] )
|
|
43
|
+
end
|
|
44
|
+
@positions = @positions.includes( :strategy
|
|
40
45
|
).order( expires_on: :asc, ticker: :desc, long_or_short: :asc, inner_strike: :asc )
|
|
41
46
|
|
|
42
47
|
|
|
@@ -47,8 +47,12 @@ class Iro::StocksController < Iro::ApplicationController
|
|
|
47
47
|
authorize! :refresh, Iro::Stock
|
|
48
48
|
tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
|
|
49
49
|
outs = Tda::Stock.get_quotes tickers
|
|
50
|
+
puts! outs, 'got all tickers'
|
|
51
|
+
|
|
50
52
|
outs.map do |out|
|
|
51
|
-
|
|
53
|
+
puts! out, 'a ticker'
|
|
54
|
+
|
|
55
|
+
Iro::Stock.where( ticker: out[:symbol] ).update_all( last: out[:last] )
|
|
52
56
|
end
|
|
53
57
|
flash_notice 'refreshed stocks'
|
|
54
58
|
redirect_to request.referrer
|
|
@@ -7,13 +7,18 @@ class Iro::StrategiesController < Iro::ApplicationController
|
|
|
7
7
|
@strategy = Iro::Strategy.new params[:strategy].permit!
|
|
8
8
|
authorize! :create, @strategy
|
|
9
9
|
|
|
10
|
+
if @strategy[:kind] == Iro::Strategy::KIND_WHEEL
|
|
11
|
+
@strategy.long_or_short = Iro::Strategy::LONG
|
|
12
|
+
@strategy.credit_or_debit = Iro::Strategy::DEBIT
|
|
13
|
+
end
|
|
14
|
+
|
|
10
15
|
if @strategy.save
|
|
11
16
|
flash_notice @strategy
|
|
17
|
+
redirect_to action: :index
|
|
12
18
|
else
|
|
13
19
|
flash_alert @strategy
|
|
20
|
+
render action: 'new'
|
|
14
21
|
end
|
|
15
|
-
|
|
16
|
-
redirect_to action: :index
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
def destroy
|
|
@@ -37,8 +42,9 @@ class Iro::StrategiesController < Iro::ApplicationController
|
|
|
37
42
|
end
|
|
38
43
|
|
|
39
44
|
def new
|
|
40
|
-
@strategy = Iro::Strategy.new
|
|
45
|
+
@strategy = Iro::Strategy.new({ kind: params[:kind] })
|
|
41
46
|
authorize! :new, @posision
|
|
47
|
+
|
|
42
48
|
end
|
|
43
49
|
|
|
44
50
|
def show
|
data/app/models/tda/option.rb
CHANGED
|
@@ -26,7 +26,7 @@ class Tda::Option
|
|
|
26
26
|
##
|
|
27
27
|
def self.get_chains params
|
|
28
28
|
filename = "./data/schwab/#{Time.now.to_date.to_s}-#{params[:ticker]}-chains.json"
|
|
29
|
-
if !params[:force] && File.exists?(
|
|
29
|
+
if !params[:force] && File.exists?(filename)
|
|
30
30
|
return JSON.parse File.read filename
|
|
31
31
|
|
|
32
32
|
else
|
|
@@ -141,7 +141,7 @@ class Tda::Option
|
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
query = { }.merge opts
|
|
144
|
-
puts! query, '
|
|
144
|
+
puts! query, 'zp1 - query'
|
|
145
145
|
|
|
146
146
|
headers = {
|
|
147
147
|
accept: 'application/json',
|
|
@@ -150,13 +150,13 @@ class Tda::Option
|
|
|
150
150
|
|
|
151
151
|
path = "/chains"
|
|
152
152
|
out = self.get path, {
|
|
153
|
-
# basic_auth: { username: SCHWAB_DATA[:key], password: SCHWAB_DATA[:secret] },
|
|
154
153
|
headers: headers,
|
|
155
154
|
query: query,
|
|
156
155
|
}
|
|
157
|
-
puts! out, '
|
|
156
|
+
puts! out, 'zp1 - got a chain'
|
|
158
157
|
timestamp = DateTime.parse out.headers['date']
|
|
159
158
|
out = out.parsed_response.deep_symbolize_keys
|
|
159
|
+
puts! out, 'zp1 - out'
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
tmp_sym = "#{opts[:contractType].to_s.downcase}ExpDateMap".to_sym
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
- long_or_short = position.long_or_short || position.strategy&.long_or_short || params[:long_or_short]
|
|
3
3
|
|
|
4
|
-
.positions--form{ class:
|
|
4
|
+
.positions--form{ class: "is-#{long_or_short}" }
|
|
5
5
|
= form_for position do |f|
|
|
6
6
|
.actions
|
|
7
7
|
= f.submit
|
|
@@ -10,26 +10,35 @@
|
|
|
10
10
|
.field
|
|
11
11
|
%label Purse
|
|
12
12
|
= f.select :purse_id, options_for_select( @purses_list, selected: position.purse_id )
|
|
13
|
-
|
|
13
|
+
.field
|
|
14
14
|
%label Status
|
|
15
15
|
= f.select :status, options_for_select( Iro::Position::STATUSES, selected: position.status )
|
|
16
16
|
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
.d-flex
|
|
18
|
+
.field
|
|
19
|
+
%label Stock
|
|
20
|
+
= f.select :stock_id, options_for_select( @stocks_list, selected: position.stock_id )
|
|
21
|
+
.field
|
|
22
|
+
%label put_call
|
|
23
|
+
= f.select :put_call, options_for_select([nil, 'PUT', 'CALL'], selected: position.put_call)
|
|
24
|
+
= position.put_call
|
|
20
25
|
|
|
21
26
|
-# .field
|
|
22
27
|
-# %label long or short?
|
|
23
28
|
-# = f.select :long_or_short, options_for_select([nil, Iro::Strategy::LONG, Iro::Strategy::SHORT], selected: long_or_short )
|
|
24
29
|
|
|
25
|
-
%label Strategy
|
|
26
|
-
= f.select :strategy_id, options_for_select( @strategies_list, selected: position.strategy_id )
|
|
27
|
-
|
|
28
30
|
.field
|
|
29
|
-
%label
|
|
30
|
-
= f.select :
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
%label Strategy
|
|
32
|
+
= f.select :strategy_id, options_for_select( @strategies_list, selected: position.strategy_id )
|
|
33
|
+
|
|
34
|
+
.d-flex
|
|
35
|
+
.field
|
|
36
|
+
%label Expires on
|
|
37
|
+
= f.select :expires_on, options_for_select( Iro::Option.expirations_list, selected: position.expires_on.to_date )
|
|
38
|
+
-# = position.expires_on
|
|
39
|
+
.field
|
|
40
|
+
%label Quantity
|
|
41
|
+
= f.text_field :quantity
|
|
33
42
|
|
|
34
43
|
%br
|
|
35
44
|
= render 'formpart_4data', f: f, position: position
|
|
@@ -1,42 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
- stock = pos.stock
|
|
4
|
-
- nearest_strike = stock.last.round
|
|
5
|
-
- u = pos.purse.unit # pixels per dollar
|
|
6
|
-
|
|
7
|
-
-#
|
|
8
|
-
-# 2024-07-30 I have not verified any of this - copied from long_debit_call_spread.
|
|
9
|
-
-#
|
|
10
|
-
|
|
11
|
-
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
|
12
|
-
[<>]
|
|
13
|
-
.maxwidth= render "/iro/positions/header", pos: pos
|
|
14
|
-
.a
|
|
15
|
-
= render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
|
|
16
|
-
.StockCoordinatesW
|
|
17
|
-
.StockCoordinates{ style: "height: #{pos.q() *pos.purse.height}px " }
|
|
18
|
-
.grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
|
|
19
|
-
|
|
20
|
-
.Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
|
21
|
-
.label Last: #{pp_amount stock.last}
|
|
22
|
-
.c
|
|
23
|
-
|
|
24
|
-
- left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
|
|
25
|
-
- width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
|
|
26
|
-
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
|
27
|
-
.Position
|
|
28
|
-
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
|
29
|
-
.RollGuide
|
|
30
|
-
|
|
31
|
-
- if pos.net_amount >= 0
|
|
32
|
-
.Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
|
|
33
|
-
.label
|
|
34
|
-
net
|
|
35
|
-
= pp_amount pos.net_amount
|
|
36
|
-
- else
|
|
37
|
-
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
|
|
38
|
-
.label
|
|
39
|
-
net
|
|
40
|
-
= pp_amount pos.net_amount
|
|
41
|
-
.c
|
|
2
|
+
%h5 _gameui_long_credit_put_spread
|
|
42
3
|
|
data/app/views/iro/positions/{_gameui_short_debit_put_spread.haml-trash → _gameui_spread.haml}
RENAMED
|
@@ -4,35 +4,38 @@
|
|
|
4
4
|
- nearest_strike = stock.last.round
|
|
5
5
|
- u = pos.purse.unit # pixels per dollar
|
|
6
6
|
|
|
7
|
+
-#
|
|
8
|
+
-# 2024-07-30 I have not verified any of this - copied from long_debit_call_spread.
|
|
9
|
+
-#
|
|
7
10
|
|
|
8
11
|
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
|
9
12
|
[<>]
|
|
10
13
|
.maxwidth= render "/iro/positions/header", pos: pos
|
|
11
14
|
.a
|
|
15
|
+
- puts! pos, 'pos'
|
|
12
16
|
= render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
|
|
13
17
|
.StockCoordinatesW
|
|
14
|
-
.StockCoordinates{ style: "height: #{pos.q() *
|
|
18
|
+
.StockCoordinates{ style: "height: #{pos.q() *pos.purse.height}px " }
|
|
15
19
|
.grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
|
|
16
20
|
|
|
17
21
|
.Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
|
18
22
|
.label Last: #{pp_amount stock.last}
|
|
19
23
|
.c
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
- width = "#{ ( pos.outer.strike - pos.inner.strike ) * u}px"
|
|
25
|
+
- left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
|
|
26
|
+
- width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
|
|
24
27
|
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
|
25
28
|
.Position
|
|
26
29
|
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
|
27
30
|
.RollGuide
|
|
28
31
|
|
|
29
32
|
- if pos.net_amount >= 0
|
|
30
|
-
.Net.NetPositive{ style: "width: #{ (pos.net_amount
|
|
33
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
|
|
31
34
|
.label
|
|
32
35
|
net
|
|
33
36
|
= pp_amount pos.net_amount
|
|
34
37
|
- else
|
|
35
|
-
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount
|
|
38
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
|
|
36
39
|
.label
|
|
37
40
|
net
|
|
38
41
|
= pp_amount pos.net_amount
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
- collapse_key ||= pos.id
|
|
3
|
+
%i.fa.fa-expand.collapse-expand.floaty-collapse{ id: "gameui-pos-detail-#{collapse_key}" }
|
|
4
|
+
.maxwidth
|
|
5
|
+
%ul.m-0.p-0
|
|
6
|
+
- if !pos.persisted?
|
|
7
|
+
%li <b>expires_on:</b> #{pos.expires_on}
|
|
8
|
+
%li <b>inner_strike:</b> #{pp_amount pos.inner_strike}
|
|
9
|
+
%li <b>next_gain_loss_amount:</b> #{pp_amount pos.next_gain_loss_amount}
|
|
10
|
+
|
|
11
|
+
%li <b>begin_inner_price:</b> #{pp_amount pos.inner.begin_price}
|
|
12
|
+
%li <b>Net:</b> #{pp_amount pos.net_amount} <i>#{pp_percent pos.net_percent}</i>
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
.d-flex
|
|
3
3
|
.Card
|
|
4
|
+
-# %h5.center.text-center New position
|
|
4
5
|
= form_for Iro::Position.new(strategy: Iro::Strategy.new), url: new_position_path, method: :get do |f|
|
|
5
6
|
= hidden_field_tag 'position[purse_id]', purse.id
|
|
6
7
|
|
|
7
8
|
.formrow-v1
|
|
8
9
|
.label +Position
|
|
9
10
|
|
|
11
|
+
.d-flex.flex-column
|
|
12
|
+
%label Stock
|
|
13
|
+
= f.select :stock_id, options_for_select(@stocks_list)
|
|
14
|
+
|
|
10
15
|
.d-flex.flex-column
|
|
11
16
|
%label Strategy
|
|
12
17
|
= f.select :strategy_id, options_for_select(@strategies_list)
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
|
|
2
|
+
%h5 Positions (#{@purse.positions.length})
|
|
2
3
|
.positions--table
|
|
3
|
-
|
|
4
|
-
%h5 Positions (#{positions.length})
|
|
5
4
|
%table.bordered
|
|
6
5
|
%thead
|
|
7
6
|
%tr
|
|
8
|
-
%th
|
|
7
|
+
%th.actions
|
|
9
8
|
%th.ticker
|
|
10
9
|
.a Stock
|
|
11
10
|
%th
|
|
@@ -19,11 +18,11 @@
|
|
|
19
18
|
%th.strikes
|
|
20
19
|
Strike
|
|
21
20
|
%th.begin_price
|
|
22
|
-
.a Begin
|
|
21
|
+
.a Begin $, D
|
|
23
22
|
%th.max-loss Max Loss
|
|
24
23
|
-# %th.max-gain Max Gain
|
|
25
24
|
%th
|
|
26
|
-
.end_price End
|
|
25
|
+
.end_price End $, D
|
|
27
26
|
%th
|
|
28
27
|
.net Net Amount (%)
|
|
29
28
|
%th
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
|
|
2
|
-
-##
|
|
3
|
-
-## same for long and short debit spreads
|
|
4
|
-
-##
|
|
5
|
-
|
|
6
2
|
- pos = position
|
|
7
3
|
- stock = pos.stock
|
|
8
4
|
- nearest_strike = stock.last.round
|
|
9
5
|
- u = pos.purse.unit # pixels per dollar
|
|
10
6
|
|
|
7
|
+
-#
|
|
8
|
+
-# 2024-07-30 I have not verified any of this - copied from long_debit_call_spread.
|
|
9
|
+
-#
|
|
10
|
+
|
|
11
11
|
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
|
12
12
|
[<>]
|
|
13
13
|
.maxwidth= render "/iro/positions/header", pos: pos
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
.label Last: #{pp_amount stock.last}
|
|
22
22
|
.c
|
|
23
23
|
|
|
24
|
-
- left = "#{ ( pos.outer.strike - stock.last ) *
|
|
25
|
-
- width = "#{ ( pos.inner.strike - pos.outer.strike ) *
|
|
24
|
+
- left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
|
|
25
|
+
- width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
|
|
26
26
|
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
|
27
27
|
.Position
|
|
28
28
|
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
|
29
29
|
.RollGuide
|
|
30
30
|
|
|
31
31
|
- if pos.net_amount >= 0
|
|
32
|
-
.Net.NetPositive{ style: "width: #{ (pos.net_amount
|
|
32
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
|
|
33
33
|
.label
|
|
34
34
|
net
|
|
35
35
|
= pp_amount pos.net_amount
|
|
36
36
|
- else
|
|
37
|
-
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount
|
|
37
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
|
|
38
38
|
.label
|
|
39
39
|
net
|
|
40
40
|
= pp_amount pos.net_amount
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
app/views/iro/positions/done/_gameui_long_debit_call_spread.haml
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
app/views/iro/positions/done/_header_long_debit_call_spread.haml
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
.iro-purses--form
|
|
3
3
|
= form_for purse do |f|
|
|
4
4
|
.flex-row
|
|
5
|
-
.field
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
-# .field
|
|
6
|
+
-# %label stock
|
|
7
|
+
-# = f.select :stock_id, options_for_select( @stocks_list, selected: purse.stock_id )
|
|
8
8
|
|
|
9
9
|
.field
|
|
10
10
|
%label Slug
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
-# (#{purse.positions.length})
|
|
8
8
|
|
|
9
9
|
= link_to '[~]', edit_purse_path(purse)
|
|
10
|
-
= link_to '[table]', purse_path(purse)
|
|
11
|
-
= link_to '[gameUI]',
|
|
10
|
+
= link_to '[table]', purse_path(purse, template: 'show', view_status: params[:view_status] )
|
|
11
|
+
= link_to '[gameUI]', purse_path(purse, template: 'gameui', view_status: params[:view_status] )
|
|
12
12
|
|
|
13
13
|
%ul
|
|
14
14
|
%li <b>Total:</b> #{pp_amount purse.balance}
|
|
@@ -18,9 +18,17 @@
|
|
|
18
18
|
= render '/iro/positions/new', purse: purse
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
- if true # params[:template] == 'gameui'
|
|
22
23
|
.mini-inputs
|
|
23
24
|
= form_for purse, html: { class: 'd-flex' } do |f|
|
|
24
25
|
= render '/iro/purses/form_extra_fields', f: f
|
|
25
26
|
= f.submit '>'
|
|
26
27
|
%br
|
|
28
|
+
|
|
29
|
+
.d-flex
|
|
30
|
+
%h5 view_status
|
|
31
|
+
= form_tag purse_path( @purse ), method: :get do
|
|
32
|
+
= select_tag :view_status, options_for_select([ :all, :active, :proposed, :pending ], selected: params[:view_status] )
|
|
33
|
+
= hidden_field_tag :template, params[:template]
|
|
34
|
+
= submit_tag '>'
|