iron_warbler 2.0.7.50 → 2.0.7.52

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/iron_warbler/positions.scss +1 -1
  3. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +52 -21
  4. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +8 -1
  5. data/app/controllers/iro/application_controller.rb +9 -0
  6. data/app/controllers/iro/positions_controller.rb +119 -23
  7. data/app/controllers/iro/purses_controller.rb +7 -12
  8. data/app/controllers/iro/stocks_controller.rb +18 -4
  9. data/app/views/iro/_main_header.haml +6 -4
  10. data/app/views/iro/positions/_gameui_covered_call.haml +0 -6
  11. data/app/views/iro/positions/_gameui_long_credit_put_spread.haml +4 -2
  12. data/app/views/iro/positions/_gameui_short_credit_call_spread.haml +4 -2
  13. data/app/views/iro/positions/_header.haml +5 -3
  14. data/app/views/iro/positions/_header_short_credit_call_spread.haml +2 -2
  15. data/app/views/iro/positions/_prepare_header_long_credit_put_spread.haml +8 -8
  16. data/app/views/iro/positions/_prepare_header_short_credit_call_spread.haml +8 -10
  17. data/app/views/iro/positions/_table.haml +4 -0
  18. data/app/views/iro/positions/_table_fast.haml +150 -0
  19. data/app/views/iro/positions/_table_tr_long_credit_put_spread.haml +8 -4
  20. data/app/views/iro/positions/_vcfg_form.haml +28 -0
  21. data/app/views/iro/positions/close_prep2.haml +24 -0
  22. data/app/views/iro/positions/index.haml +7 -1
  23. data/app/views/iro/positions/prepare2.haml +4 -1
  24. data/app/views/iro/purses/_form.haml +4 -0
  25. data/app/views/iro/purses/_gameui_fast.haml +23 -0
  26. data/app/views/iro/purses/_header.haml +6 -11
  27. data/app/views/iro/purses/_summary2.haml +2 -1
  28. data/app/views/iro/purses/gameui.haml +3 -2
  29. data/app/views/iro/purses/table.haml +5 -0
  30. data/app/views/iro/stocks/index.haml +15 -7
  31. data/app/views/iro/stocks/show.haml +30 -12
  32. data/app/views/iro/strategies/_form_spread.haml +9 -1
  33. data/app/views/iro/strategies/_table.haml +11 -4
  34. data/app/views/iro/strategies/index.haml +1 -1
  35. data/config/routes.rb +19 -17
  36. data/lib/iron_warbler.rb +10 -0
  37. data/lib/tasks/coins_tasks.rake-bk +114 -0
  38. data/lib/tasks/iro_tasks.rake +21 -96
  39. data/lib/tasks/old_tasks.rake +32 -0
  40. data/lib/tasks/positions_tasks.rake +172 -0
  41. data/lib/tasks/treasuries_tasks.rake-bk +114 -0
  42. metadata +26 -7
  43. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss-bk +0 -112
  44. data/app/views/iro/positions/_header_spread.haml +0 -30
  45. data/app/views/iro/purses/done/gameui.haml-bk +0 -44
  46. data/app/views/iro/purses/done/gameui.haml-bk2 +0 -89
  47. /data/app/views/iro/purses/{show.haml → _show_fast.haml} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34e2545b7c9088e737b36b2436c475bd820e1e0f00c507f84166eca1c616421e
4
- data.tar.gz: 1e0bb92359a9ebc0c3a0e9cd4dc252e48da5097096f94855a88c2a0dfd41fd10
3
+ metadata.gz: c0703c3e0ebcb7c822c9a20d2b15d0c2793f85c19e15f117eee26e9b31d8550e
4
+ data.tar.gz: 62926b4b746be26e4415d3f9daad710cd24f052c3405c10127d0ca324f41b474
5
5
  SHA512:
6
- metadata.gz: 3e0ea3ed8e276d87f870f295c61cf5c2119fe9b375d7f12f8b2090a1f161300883361f530d4855949cb2677f4a26d5a43f419efb52bf517d221d6182be2c2f0a
7
- data.tar.gz: 5236754132aeee57af308c4c86e73fdb4a39de56770a47a0c125444fcc7f437ca544a525fabc0158c064690eb2b4cb478d8167a627f68298015534ae62f96c78
6
+ metadata.gz: 3749f60970e6476f1679d8adf4388c2a7ebdc033b74e63b8baf4aa466dc2a808c04597594286f9e25a9e094909a1ba76194a94225095cebabf4114b179883be6
7
+ data.tar.gz: b2a1469adf02dc2cb227893d088afb6268b03c9b01a7b784eefbea01f1219efa448707b00f2b83fa42c41d012968dd4a0a1ed53eda7dfba5189872f06f2d25b7
@@ -52,7 +52,7 @@
52
52
  width: 160px;
53
53
  }
54
54
  th.next_position {
55
- width: 160px;
55
+ min-width: 200px;
56
56
  }
57
57
  th.next_symbol {
58
58
  width: 120px;
@@ -1,6 +1,6 @@
1
1
 
2
2
  .purses-gameuiW {
3
- border: 1px solid red;
3
+ border: 1px solid #333;
4
4
  width: 100%;
5
5
  // overflow-x: scroll;
6
6
  overflow-y: hidden;
@@ -11,12 +11,12 @@
11
11
  .divider-expiry {
12
12
  height: 5px;
13
13
  width: 100%;
14
- background: red;
14
+ background: #333;
15
15
  }
16
16
  .divider-ticker {
17
17
  height: 2px;
18
18
  width: 100%;
19
- background: red;
19
+ background: #333;
20
20
  margin-bottom: 20px;
21
21
  }
22
22
 
@@ -53,15 +53,55 @@
53
53
  width: 5px;
54
54
  background: yellow;
55
55
  }
56
- .PositionW.short_debit_put_spread {
57
- background: rgba(255,153,0, 0.25);
58
- }
59
56
  .PositionW {
60
57
  top: 0;
61
58
  border: 2px solid black;
62
- background: rgba(0,255,255, 0.25);
59
+
63
60
  position: absolute;
64
61
  height: 100%;
62
+
63
+ .Position {
64
+ position: absolute;
65
+ left: 0;
66
+ top: 0;
67
+
68
+ width: 100%;
69
+ height: 100%;
70
+
71
+ .Quantities {
72
+ // background: rgba(0,0,0, 0.1);
73
+
74
+ width: 33%;
75
+ height: 100%;
76
+ position: absolute;
77
+
78
+ display: flex;
79
+ justify-content: space-evenly;
80
+ flex-direction: column;
81
+
82
+ .item {
83
+ width: 100%;
84
+ border-bottom: 1px solid #333;
85
+ }
86
+
87
+ }
88
+
89
+ }
90
+ }
91
+ .PositionW.long_credit_put_spread {
92
+ background: linear-gradient(to left, rgba(0,255,255, 0.6), transparent);
93
+ // background: linear-gradient(to left, rgba(0,0,0, 0.5), transparent);
94
+ .Quantities {
95
+ left: 0;
96
+ }
97
+ }
98
+ .PositionW.short_credit_call_spread {
99
+ background: linear-gradient(to right, rgba(0,255,255, 0.5), transparent);
100
+ background: linear-gradient(to right, rgba(0,0,0, 0.5), transparent);
101
+ background: linear-gradient(to right, rgba(236,164,60, 0.6), transparent);
102
+ .Quantities {
103
+ right: 0;
104
+ }
65
105
  }
66
106
  .reviewing {
67
107
  .PositionW {
@@ -70,23 +110,14 @@
70
110
  }
71
111
  }
72
112
 
73
- .Position {
74
- position: absolute;
75
- left: 0;
76
- top: 0;
77
-
78
- width: 100%;
79
- height: 100%;
80
- }
81
-
82
-
83
- .MaxGain,
84
- .Breakeven {
113
+ .MaxGain {
85
114
  position: absolute;
86
115
  right: 0;
87
116
  bottom: 0;
88
- border: 2px dotted green;
89
- background: rgba(50,55,55, 0.5);
117
+ border: 2px dotted #eee;
118
+ border: 2px dotted rgb(61,98,66);
119
+ background: rgba(255,255,255, 0.5);
120
+ background: rgba(61,98,66, 0.5);
90
121
  height: 25%;
91
122
  }
92
123
  .PositionW.is-short .MaxGain {
@@ -5,6 +5,13 @@
5
5
  .purses--summary2 {
6
6
  // border: 1px solid yellow;
7
7
 
8
+
9
+ .collapse-expand {
10
+ transform-origin: left bottom;
11
+ transform: rotate(270deg);
12
+ width: 0;
13
+ }
14
+
8
15
  label {
9
16
  position: absolute;
10
17
  }
@@ -22,7 +29,7 @@
22
29
  z-index: 11;
23
30
  height: 400px;
24
31
  position: relative;
25
- background: rgba(255,255,255, 0.75);
32
+ // background: rgba(255,255,255, 0.75);
26
33
 
27
34
  }
28
35
  .PurseSummary {
@@ -9,6 +9,7 @@ class Iro::ApplicationController < Wco::ApplicationController
9
9
  layout 'iro/application'
10
10
 
11
11
  before_action :set_lists, except: %i| schwab_sync |
12
+ before_action :set_vcfg
12
13
 
13
14
  def home
14
15
  authorize! :home, Iro
@@ -33,5 +34,13 @@ class Iro::ApplicationController < Wco::ApplicationController
33
34
  @purses = Iro::Purse.all.order_by( slug: :asc )
34
35
  end
35
36
 
37
+ def set_vcfg
38
+ params[:vcfg] ||= {
39
+ statuses: [ 'active', 'pending' ],
40
+ template: Iro::Purse::TEMPLATE_GAMEUI,
41
+ }
42
+ params[:vcfg].permit!
43
+ end
44
+
36
45
 
37
46
  end
@@ -5,11 +5,48 @@ class Iro::PositionsController < Iro::ApplicationController
5
5
  @position = Iro::Position.find params[:id]
6
6
  authorize! :check, @position
7
7
  outs = Tda::Order.check_status @position.schwab_order_id
8
- @position.update({ schwab_status: outs[:status] })
9
8
  puts! outs, 'outs'
9
+
10
+ if outs[:errors]
11
+ flash[:alert] = 'need to sync?!'
12
+ redirect_to request.referrer
13
+ return
14
+ end
15
+
16
+ attrs = { schwab_status: outs[:status] }
17
+ if 'FILLED' == outs[:status]
18
+ attrs[:status] = Iro::Position::STATUS_CLOSED
19
+ outs[:orderLegCollection].each do |leg|
20
+ hash = Iro::Option.symbol_to_h leg[:instrument][:symbol]
21
+ price = outs[:orderActivityCollection][0][:executionLegs].select do |exec_leg|
22
+ exec_leg[:instrumentId] == leg[:instrument][:instrumentId]
23
+ end[0][:price]
24
+ if @position.inner.matches_h( hash )
25
+ attrs[:inner_attributes] = { end_price: price }
26
+ end
27
+ if @position.outer.matches_h( hash )
28
+ attrs[:outer_attributes] = { end_price: price }
29
+ end
30
+ end
31
+ end
32
+ puts! attrs,' attrs'
33
+ @position.update(attrs)
34
+
10
35
  redirect_to request.referrer
11
36
  end
12
37
 
38
+ def close_prep2
39
+ @position = Iro::Position.find params[:id]
40
+ authorize! :close, @position
41
+ @position.inner.sync
42
+ # @position.inner.update({ begin_price: @position.inner.end_price })
43
+ @position.outer.sync
44
+ # @position.outer.update({ begin_price: @position.outer.end_price })
45
+ @position.update({ pending_price: @position.close_price, intent: Iro::Position::INTENT_CLOSE })
46
+ @query = Tda::Order.close_credit_spread_q @position
47
+ @page_title = "Closing #{@position} ..."
48
+ end
49
+
13
50
  def create
14
51
  @position = Iro::Position.new pos_params
15
52
  authorize! :create, @position
@@ -81,7 +118,20 @@ class Iro::PositionsController < Iro::ApplicationController
81
118
 
82
119
  def index
83
120
  authorize! :index, Iro::Position
84
- @positions = Iro::Position.active
121
+ params[:vcfg] ||= {} # "view config"
122
+ template = params[:vcfg][:template] || Iro::Purse::TEMPLATE_TABLE
123
+
124
+ @purse = Iro::Purse.find_by( slug: 'all' )
125
+ @positions = Iro::Position.all().includes( :strategy, :inner, :outer, :stock, :purse
126
+ ).order_by( expires_on: :asc, ticker: :asc, long_or_short: :asc, inner_strike: :asc )
127
+
128
+ if params[:vcfg][:statuses]
129
+ @positions = @positions.where( :status.in => params[:vcfg][:statuses] )
130
+ end
131
+
132
+ puts! @positions
133
+
134
+ @page_title = 'All Positions'
85
135
  end
86
136
 
87
137
  ## only callable from _new.haml, with position partially pre-filled
@@ -101,14 +151,38 @@ class Iro::PositionsController < Iro::ApplicationController
101
151
  set_position_lists
102
152
  end
103
153
 
104
- ## only credit-spread
154
+ ## only open credit-spread,
155
+ ## roll a credit-spread
105
156
  def reprice
106
157
  @position = Iro::Position.find params[:id]
107
158
  authorize! :roll, @position
108
- @position.update({ pending_price: params[:pending_price] })
159
+ flash_notice @position.update({ pending_price: params[:pending_price] })
160
+
161
+ if @position.schwab_order_id
162
+ Tda::Order.cancel_order!( @position.schwab_order_id )
163
+ outs = Tda::Order.place_order!( @position.schwab_query )
164
+ flag = @position.update({
165
+ schwab_order_id: outs[:schwab_order_id],
166
+ schwab_status: outs[:schwab_status],
167
+ status: Iro::Position::STATUS_PENDING,
168
+ })
169
+ flash_notice "Updated schwab order!"
170
+ end
109
171
 
110
- Tda::Order.cancel_order!( @position.schwab_order_id )
111
- outs = Tda::Order.place_order!( Tda::Order.credit_spread_q @position )
172
+ redirect_to request.referrer
173
+ end
174
+
175
+ def place_order
176
+ @position = Iro::Position.find params[:id]
177
+ authorize! :place_order, @position
178
+
179
+ query = case @position.intent
180
+ when Iro::Position::INTENT_CLOSE
181
+ Tda::Order.close_credit_spread_q @position
182
+ else
183
+ throw '_TODO: hls - placing order, not implemented'
184
+ end
185
+ outs = Tda::Order.place_order!( query )
112
186
 
113
187
  flag = @position.update({
114
188
  schwab_order_id: outs[:schwab_order_id],
@@ -117,24 +191,24 @@ class Iro::PositionsController < Iro::ApplicationController
117
191
  })
118
192
 
119
193
  flash_notice flag
120
- # redirect_to controller: :purses, action: :show, template: 'show', view_status: 'pending', id: @position.purse_id
121
- redirect_to request.referrer
194
+ redirect_to controller: :purses, action: :show, template: 'show', view_status: 'pending', id: @position.purse_id
122
195
  end
123
196
 
124
- ## place2 = credit-spread
125
- def place2
197
+ ## credit-spread
198
+ def open
126
199
  @position = Iro::Position.find params[:id]
127
200
  authorize! :roll, @position
128
201
  @position.inner.sync
129
202
  @position.inner.update({ begin_price: @position.inner.end_price })
130
203
  @position.outer.sync
131
204
  @position.outer.update({ begin_price: @position.outer.end_price })
132
- @position.update({ pending_price: @position.place2_price })
133
- @query = Tda::Order.credit_spread_q @position
205
+ @position.update({ pending_price: @position.open_price })
206
+ @query = @position.schwab_query # Tda::Order.credit_spread_q @position
134
207
  end
135
208
 
136
209
  ## 2025-10-14 long_credit_put_spread
137
210
  ## 2026-02-21 short_credit_call_spread
211
+ ## That's for looking at the ui, with buttons 'select'
138
212
  def prepare
139
213
  @position = Iro::Position.find params[:id]
140
214
  authorize! :roll, @position
@@ -152,23 +226,23 @@ class Iro::PositionsController < Iro::ApplicationController
152
226
  self.send("_prepare_#{@position.strategy.kind}")
153
227
  end
154
228
 
229
+ ## Manually selected one, I suppose
230
+ ## _TODO: pos is autonext position, but should be this position?
231
+ ## rename to: def select ?
155
232
  def prepare2
233
+ if params[:prev_id]
234
+ prev = Iro::Position.find params[:prev_id]
235
+ prev.update({ autonxt_id: params[:id] })
236
+ Iro::Position.where( prev_id: params[:prev_id], status: 'proposed' ).update_all( status: 'prepare' )
237
+ end
238
+
156
239
  @position = Iro::Position.find params[:id]
157
240
  authorize! :roll, @position
158
241
  @position.update({
159
242
  status: Iro::Position::STATUS_PROPOSED,
243
+ intent: @position.strategy.intent,
244
+ pending_price: @position.roll_price,
160
245
  })
161
- if params[:prev_id]
162
- prev = Iro::Position.find params[:prev_id]
163
- prev.update({ autonxt_id: params[:id] })
164
- @position.reload
165
- else
166
- if @position.autoprev
167
- ;
168
- else
169
- throw 'Must pass prev_id here.'
170
- end
171
- end
172
246
 
173
247
  @query = case @position.strategy.kind
174
248
  when Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD,
@@ -181,6 +255,28 @@ class Iro::PositionsController < Iro::ApplicationController
181
255
  end
182
256
  end
183
257
 
258
+ ## 2026-04-08 try-close only so far.
259
+ ## pos is this position, not autonext.
260
+ def prepare2_intent
261
+ @position = Iro::Position.find params[:id]
262
+ authorize! :roll, @position
263
+ case @position.strategy.intent
264
+ when Iro::Strategy::INTENT_CLOSE
265
+
266
+ @position.inner.sync
267
+ @position.inner.update({ begin_price: @position.inner.end_price })
268
+ @position.outer.sync
269
+ @position.outer.update({ begin_price: @position.outer.end_price })
270
+ @position.update({ pending_price: @position.close_price, intent: Iro::Position::INTENT_CLOSE })
271
+ # @query = Tda::Order.close_credit_spread_q @position
272
+
273
+ else
274
+ throw 'unknown intent - trt'
275
+ end
276
+
277
+ end
278
+
279
+
184
280
  ## credit-spread
185
281
  def place3
186
282
  @position = Iro::Position.find params[:id]
@@ -22,7 +22,7 @@ class Iro::PursesController < Iro::ApplicationController
22
22
  end
23
23
 
24
24
  def edit
25
- @purse = Iro::Purse.find(params[:id])
25
+ @purse = Iro::Purse.unscoped.find(params[:id]) rescue Iro::Purse.unscoped.find_by( slug: params[:id] )
26
26
  authorize! :edit, @purse
27
27
  end
28
28
 
@@ -33,25 +33,20 @@ class Iro::PursesController < Iro::ApplicationController
33
33
 
34
34
  ## table or gameui
35
35
  def show
36
- @purse = Iro::Purse.find(params[:id])
36
+ @purse = Iro::Purse.unscoped.find(params[:id]) rescue Iro::Purse.unscoped.find_by( slug: params[:id] )
37
37
  authorize! :show, @purse
38
- params[:template] ||= 'show'
39
- params[:view_status] ||= 'active'
40
38
  @unit = @purse.unit # 12 ## pixels per dollar
41
39
  @height = @purse.height # 100 ## pixels
42
40
  @n_dollars = 50 ## * unit * 2 = length of the grid
43
41
 
44
- @positions = @purse.positions.where( status: params[:view_status]
42
+ @positions = @purse.positions.where( :status.in => params[:vcfg][:statuses]
45
43
  ).includes( :strategy
46
44
  ).order_by( expires_on: :asc, ticker: :asc, long_or_short: :asc, inner_strike: :asc )
47
45
 
48
- if 'all' == params[:view_status]
49
- @positions = @positions.unscope( where: :status )
50
- end
51
-
52
46
  calc_summary
53
47
 
54
- render params[:template]
48
+ @page_title = @purse.to_s
49
+ render params[:vcfg][:template]
55
50
  end
56
51
 
57
52
  def sync
@@ -79,12 +74,12 @@ class Iro::PursesController < Iro::ApplicationController
79
74
  count = count+1
80
75
  end
81
76
 
82
- flash[:notice] = 'Probably synced the purse.'
77
+ flash[:notice] = 'Synced the purse.'
83
78
  redirect_to request.referrer
84
79
  end
85
80
 
86
81
  def update
87
- @purse = Iro::Purse.find(params[:id])
82
+ @purse = Iro::Purse.unscoped.find(params[:id]) rescue Iro::Purse.unscoped.find_by( slug: params[:id] )
88
83
  authorize! :update, @purse
89
84
  if @purse.update params[:purse].permit!
90
85
  flash[:notice] = 'ok'
@@ -12,20 +12,37 @@ class Iro::StocksController < Iro::ApplicationController
12
12
  if @stock.save
13
13
  flash_notice @stock
14
14
  else
15
+ @stock = Iro::Stock.unscoped.find_by ticker: stock_params[:ticker]
16
+ flag = @stock.update( deleted_at: nil, options_price_increment: stock_params[:options_price_increment] )
15
17
  flash_alert @stock
16
18
  end
17
19
  redirect_to action: :index
18
20
  end
19
21
 
20
22
  def destroy
23
+ authorize! :destroy, @stock
21
24
  @stock.destroy
22
- redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
25
+ redirect_to stocks_url, notice: 'Stock was destroyed.'
23
26
  end
24
27
 
25
28
  def edit
26
29
  authorize! :edit, @stock
27
30
  end
28
31
 
32
+ def get_historic_data
33
+ authorize! :show, Iro::Stock
34
+ @stock = Iro::Stock.find params[:id]
35
+ @stock.get_historic_data( params[:date_from].to_date )
36
+ redirect_to action: :show, id: params[:id]
37
+ end
38
+
39
+ def recompute_volatility
40
+ authorize! :show, Iro::Stock
41
+ @stock = Iro::Stock.find params[:id]
42
+ @stock.volatility( recompute: true )
43
+ redirect_to action: :show, id: params[:id]
44
+ end
45
+
29
46
  def index
30
47
  @all_stocks = Iro::Stock.all
31
48
  authorize! :index, Iro::Stock
@@ -47,11 +64,8 @@ class Iro::StocksController < Iro::ApplicationController
47
64
  authorize! :refresh, Iro::Stock
48
65
  tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
49
66
  outs = Tda::Stock.get_quotes tickers
50
- puts! outs, 'got all tickers'
51
67
 
52
68
  outs.map do |out|
53
- puts! out, 'a ticker'
54
-
55
69
  Iro::Stock.where( ticker: out[:symbol] ).update_all( last: out[:last] )
56
70
  end
57
71
  flash_notice 'refreshed stocks'
@@ -22,19 +22,21 @@
22
22
  -# = link_to "Purses (#{Iro::Purse.all.length})", purses_path
23
23
  %li
24
24
  = render '/iro/strategies/header'
25
+ %li
26
+ = link_to 'Positions', iro.positions_path
25
27
 
26
28
 
27
29
  .ml-3
28
30
  = link_to "Purses (#{Iro::Purse.all.length})", purses_path
29
31
  = link_to '[+]', purses_path
30
32
  %ul
31
- - @purses.each do |p|
33
+ - @purses.each do |purse|
32
34
  %li
33
- = p
35
+ = purse
34
36
  &nbsp;
35
- = link_to '[#]', purse_path(p)
37
+ = link_to '[#]', purse_path(purse, vcfg: params[:vcfg].merge({ template: Iro::Purse::TEMPLATE_TABLE }))
36
38
  &nbsp;
37
- = link_to '[ui]', purse_gameui_path(p)
39
+ = link_to '[oo]', purse_path(purse, vcfg: params[:vcfg].merge({ template: Iro::Purse::TEMPLATE_GAMEUI }))
38
40
 
39
41
  -#
40
42
  = link_to 'Strategies', strategies_path
@@ -32,9 +32,3 @@
32
32
  .label
33
33
  net
34
34
  = pp_amount pos.net_amount
35
-
36
- -# .Breakeven{ style: "width: #{ pos.inner.begin_price * u }px" }
37
- -# .label
38
- -# Breakeven:
39
- -# = pos.inner.begin_price
40
-
@@ -8,8 +8,7 @@
8
8
  -# 2026-02-16 I have not verified any of this
9
9
  -#
10
10
 
11
- .collapse-expand.d-flex.--gameui-long-credit-put-spread{ id: "gameui-pos-#{pos.id}" }
12
- [<>]
11
+ .d-flex.--gameui-long-credit-put-spread{ id: "gameui-pos-#{pos.id}" }
13
12
  .maxwidth= render "/iro/positions/header", pos: pos
14
13
  .--gameui-long-credit-put-spread
15
14
  = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
@@ -28,6 +27,9 @@
28
27
  .Position
29
28
  .MaxGain{ style: "width: #{pos.max_gain * u}px" }
30
29
  .RollGuide
30
+ .Quantities
31
+ - (pos.q-1).times do
32
+ .item
31
33
 
32
34
  - if pos.net_amount >= 0
33
35
  .Net.NetPositive{ style: "width: #{ pos.net_amount() *u}px;" }
@@ -10,8 +10,7 @@
10
10
  -## 2026-04-05 move loss inside, gain outside
11
11
  -##
12
12
 
13
- .collapse-expand.d-flex.--gameui-short-credit-call-spread{ id: "gameui-pos-#{pos.id}" }
14
- [<>]
13
+ .d-flex.--gameui-short-credit-call-spread{ id: "gameui-pos-#{pos.id}" }
15
14
  .maxwidth= render "/iro/positions/header", pos: pos
16
15
  .--gameui-short-credit-call-spread
17
16
  = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
@@ -30,6 +29,9 @@
30
29
  .Position
31
30
  .MaxGain{ style: "width: #{pos.max_gain * u}px" }
32
31
  .RollGuide
32
+ .Quantities
33
+ - (pos.q-1).times do
34
+ .item
33
35
 
34
36
  - if pos.net_amount >= 0
35
37
  .Net.NetPositive{ style: "width: #{ pos.net_amount*u }px; left: #{-1* pos.net_amount() *u + border_px}px" }
@@ -1,9 +1,11 @@
1
1
 
2
2
  .positions--header.maxwidth
3
+
3
4
  = pos
4
- = render '/iro/strategies/show', collapse_key: pos.id, strategy: pos.strategy
5
+ -# = render '/iro/strategies/show', collapse_key: pos.id, strategy: pos.strategy
5
6
  = link_to '[prepare]', position_prepare_to_roll_path(pos) if pos.persisted?
6
- -# .d-inline-block= button_to 'close', close_position_path(pos), data: { confirm: 'Are you sure?' }
7
7
  = link_to '[close]', close_position_path(pos)
8
8
  = link_to '[~]', edit_position_path(pos) if pos.persisted?
9
- -# = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
9
+ .d-inline-block= button_to 'x', position_path(pos), method: :delete, data: { confirm: 'Are you sure?' }
10
+ .gray &nbsp;<i>#{pos.status}</i>&nbsp;
11
+
@@ -6,13 +6,13 @@
6
6
  .maxwidth.positions--header.--header-short-credit-call-spread
7
7
  %ul
8
8
  %li
9
- <b>begin $:</b> [#{pp_amount pos.inner.begin_price} -> #{pp_amount pos.outer.begin_price}]
9
+ <b>begin $:</b> [#{pp_amount pos.inner.begin_price} >> #{pp_amount pos.outer.begin_price}]
10
10
  <b>D:</b> [[#{pos.inner.begin_delta} >> #{pos.outer.begin_delta}]]
11
11
  <b>net_ea/max_gain_ea:</b> #{pp_amount pos.net_amount * 100}/#{pp_amount pos.max_gain * 100} :: #{pp_percent pos.net_percent}
12
12
  <b>breakeven:</b> #{pp_amount pos.breakeven}
13
13
  <b>max_loss:</b> #{pp_amount pos.max_loss * 100*q}
14
14
  %li
15
- <b>end $:</b> [#{pp_amount pos.inner.end_price} -> #{pp_amount pos.outer.end_price}]
15
+ <b>end $:</b> [#{pp_amount pos.inner.end_price} >> #{pp_amount pos.outer.end_price}]
16
16
  <b>D:</b> [[#{pos.inner.end_delta} >> #{pos.outer.end_delta}]]
17
17
  <b>net*q</b> #{pp_amount pos.net_amount * 100*q}
18
18
  <b>max_gain*q:</b> #{pp_amount pos.max_gain * 100*q}
@@ -5,12 +5,12 @@
5
5
  .maxwidth.--prepare-header-long-credit-put-spread
6
6
  %ul.m-0.p-0
7
7
  %li
8
- <b>begin_outer_price:</b> #{pp_amount pos.outer.begin_price}
9
- <b>begin_inner_price:</b> #{pp_amount pos.inner.begin_price}
10
- <b>max_gain:</b> #{pp_amount pos.max_gain * 100}
11
- <b>breakeven:</b> #{pp_amount pos.breakeven}
12
- <b>Net:</b> #{pp_amount pos.next_gain_loss_amount}
8
+ #{pos.expires_on} [#{pp_amount pos.outer.strike} << #{pp_amount pos.inner.strike}] &nbsp;
9
+ <b>net_ea:</b> #{pp_amount pos.next_gain_loss_amount} &nbsp;
10
+ <b>max_loss_ea:</b> #{pp_amount pos.max_loss * 100} &nbsp;
13
11
  %li
14
- #{pos.expires_on} <b>#{pos.strategy.kind}</b> [#{pp_amount pos.outer.strike} <- #{pp_amount pos.inner.strike}]
15
- <b>max_loss:</b> #{pp_amount pos.max_loss * 100}
16
- %li
12
+ <b>begin $:</b> [#{pp_amount pos.outer.begin_price} << #{pp_amount pos.inner.begin_price}] &nbsp;
13
+ <b>D:</b> [[#{pos.outer.begin_delta} << #{pos.inner.begin_delta}]] &nbsp;
14
+ <b>max_gain_ea:</b> #{pp_amount pos.max_gain * 100} &nbsp;
15
+ <b>breakeven:</b> #{pp_amount pos.breakeven} &nbsp;
16
+
@@ -5,15 +5,13 @@
5
5
  .maxwidth.--prepare-header-short-credit-call-spread
6
6
  %ul.m-0.p-0
7
7
  %li
8
- -# 2026-02-24 this ordering
9
- <b>begin_inner_price:</b> #{pp_amount pos.inner.begin_price}
10
- <b>begin_outer_price:</b> #{pp_amount pos.outer.begin_price}
11
- <b>max_gain_ea:</b> #{pp_amount pos.max_gain * 100}
12
- <b>breakeven:</b> #{pp_amount pos.breakeven}
13
- <b>Net Ea:</b> #{pp_amount pos.next_gain_loss_amount}
14
- %li
15
- -# 2026-02-24 this ordering
16
- #{pos.expires_on} <b>#{pos.strategy.kind}</b> [#{pp_amount pos.inner.strike} -> #{pp_amount pos.outer.strike}]
17
- <b>max_loss_ea:</b> #{pp_amount pos.max_loss * 100}
8
+ #{pos.expires_on} [#{pp_amount pos.inner.strike} >> #{pp_amount pos.outer.strike}] &nbsp;
9
+ <b>net_ea:</b> #{pp_amount pos.next_gain_loss_amount} &nbsp;
10
+ <b>max_loss_ea:</b> #{pp_amount pos.max_loss * 100} &nbsp;
18
11
  %li
12
+ <b>begin $:</b> [#{pp_amount pos.inner.begin_price} >> #{pp_amount pos.outer.begin_price}] &nbsp;
13
+ <b>D:</b> [[#{pos.inner.begin_delta} >> #{pos.outer.begin_delta}]] &nbsp;
14
+ <b>max_gain_ea:</b> #{pp_amount pos.max_gain * 100} &nbsp;
15
+ <b>breakeven:</b> #{pp_amount pos.breakeven} &nbsp;
16
+
19
17
 
@@ -8,6 +8,9 @@
8
8
  = form_tag positions_path, method: :delete, id: 'positionsXmultiSubmit' do
9
9
  = hidden_field_tag "positions_xmulti", ''
10
10
  = submit_tag 'X-multi', data: { confirm: 'Are you sure?' }
11
+
12
+ %th.intent
13
+ Intent
11
14
  %th.ticker
12
15
  .a Stock
13
16
  %th
@@ -52,6 +55,7 @@
52
55
  %td{ colspan: 18 }
53
56
  .h-50px
54
57
 
58
+ -## Renders the same thing regardless of strategy!
55
59
  = render "iro/positions/table_tr_#{position.strategy.kind}", position: position
56
60
 
57
61