iron_warbler 2.0.7.49 → 2.0.7.51

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/iron_warbler/application.css +0 -9
  3. data/app/assets/stylesheets/iron_warbler/positions.scss +4 -0
  4. data/app/assets/stylesheets/iron_warbler/positions_gameui.scss +2 -2
  5. data/app/assets/stylesheets/iron_warbler/purses.scss +2 -1
  6. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +14 -1
  7. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +113 -79
  8. data/app/assets/stylesheets/iron_warbler/utils.scss +5 -4
  9. data/app/controllers/iro/positions_controller.rb +143 -22
  10. data/app/controllers/iro/purses_controller.rb +53 -52
  11. data/app/controllers/iro/stocks_controller.rb +19 -2
  12. data/app/views/iro/_main_header.haml +8 -9
  13. data/app/views/iro/positions/_form_spread.haml +5 -3
  14. data/app/views/iro/positions/_header.haml +1 -0
  15. data/app/views/iro/positions/_header_long_credit_put_spread.haml +11 -7
  16. data/app/views/iro/positions/_header_short_credit_call_spread.haml +10 -8
  17. data/app/views/iro/positions/_new.haml +2 -2
  18. data/app/views/iro/positions/_prepare_header_short_credit_call_spread.haml +4 -3
  19. data/app/views/iro/positions/_table_tr_covered_call.haml +1 -1
  20. data/app/views/iro/positions/_table_tr_long_credit_put_spread.haml +13 -4
  21. data/app/views/iro/positions/close_prep2.haml +24 -0
  22. data/app/views/iro/positions/index.haml +5 -0
  23. data/app/views/iro/positions/place2.haml +27 -0
  24. data/app/views/iro/positions/prepare.haml +1 -1
  25. data/app/views/iro/positions/prepare2.haml +23 -21
  26. data/app/views/iro/purses/_form_extra_fields.haml +21 -16
  27. data/app/views/iro/purses/_header.haml +49 -36
  28. data/app/views/iro/purses/_summary.haml +60 -27
  29. data/app/views/iro/purses/_summary2.haml +77 -0
  30. data/app/views/iro/purses/gameui.haml +4 -7
  31. data/app/views/iro/purses/show.haml +1 -7
  32. data/app/views/iro/stocks/_form.haml +3 -0
  33. data/app/views/iro/stocks/index.haml +16 -8
  34. data/app/views/iro/stocks/show.haml +30 -12
  35. data/app/views/iro/strategies/_form_spread.haml +11 -10
  36. data/app/views/iro/strategies/_list.haml +4 -0
  37. data/app/views/iro/strategies/_show.haml +3 -2
  38. data/app/views/iro/strategies/_table.haml +8 -4
  39. data/app/views/layouts/iro/application.haml +1 -2
  40. data/config/routes.rb +19 -13
  41. data/lib/iron_warbler.rb +10 -0
  42. metadata +20 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 181da017ec4910921e41d9c33dfeb2bb8d0f00c5c8a8f09886a03b06b820de8d
4
- data.tar.gz: 8bad8df4925989d0d47ee9f29bc5f8b965fb485d9b330326c1d3171c95379e6b
3
+ metadata.gz: 27e79457c024254243edfd06b728c5b236da335b03880678f7bffdb72d4fb6b1
4
+ data.tar.gz: ed9263babe2e1bcff873de6924a0160596aa535675a690b3c96319b4e0b53391
5
5
  SHA512:
6
- metadata.gz: 38613099637e30d90aa8d46a49a044b87fe826fc81f3cbc1ae9feb4e2cf858678d1a7685cbeb063d5bcb2427248597a22a1dfd1dd4e3be1c5fe787d645391f21
7
- data.tar.gz: 7132c4dd07498818c3ea0f4b9063c64557bf8c9066badee4549dfaf18fc696a133d7e3d9f2497be01384ce291def53d4b6dd1e1fb1ddfd1207669aaca759032a
6
+ metadata.gz: 7d5a2fbb95f4278e70d0055b591c3f337c257e37112e49f1f34f1ae3ba672ca03abafc5165611a94b20e29d8b0073f70f56db0cad37cca59a3ec66d3e0386ea2
7
+ data.tar.gz: 78d43e5d0142b8481593e5239c997e9756615307d97a0919dc970be22e645fb3ae2847d08992e28bc0b05a017636bd6ba8756a5411c965f5236eeaba75bc57ba
@@ -24,18 +24,9 @@ html {
24
24
  --iro-color-bg2: #fefefe;
25
25
  }
26
26
 
27
- /* body {
28
- color: red !important;
29
- } */
30
-
31
27
  .iro--main-header {
32
28
  li {
33
29
  margin-bottom: 0.2em;
34
-
35
- a {
36
- background: white;
37
- padding: 0 0.2em;
38
- }
39
30
  }
40
31
  }
41
32
 
@@ -2,6 +2,10 @@
2
2
  .positions--header {
3
3
  position: relative;
4
4
  z-index: 1;
5
+ ul {
6
+ margin: 0;
7
+ padding: 0;
8
+ }
5
9
  }
6
10
 
7
11
  .begin-inner-price,
@@ -1,7 +1,7 @@
1
1
 
2
- .positions--prepare {
2
+ .positions-prepare {
3
3
  .RollGuide {
4
- height: 100vh;
4
+ height: 200vh;
5
5
  border: 1px dashed gray;
6
6
  position: absolute;
7
7
  right: 0;
@@ -2,11 +2,12 @@
2
2
  .purses--form-extra-fields {
3
3
  background: rgba(255,255,255, 0.5);
4
4
  padding: 0.3em 0;
5
- margin-bottom: 0.5em;
5
+ // margin-bottom: 0.5em;
6
6
 
7
7
  line-height: 1.5em;
8
8
  input {
9
9
  height: 1.5em;
10
+ min-width: 90px;
10
11
  }
11
12
 
12
13
  > div {
@@ -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;
@@ -8,6 +8,18 @@
8
8
 
9
9
  .purses-gameui {
10
10
 
11
+ .divider-expiry {
12
+ height: 5px;
13
+ width: 100%;
14
+ background: #333;
15
+ }
16
+ .divider-ticker {
17
+ height: 2px;
18
+ width: 100%;
19
+ background: #333;
20
+ margin-bottom: 20px;
21
+ }
22
+
11
23
  .Origin::before {
12
24
  position: absolute;
13
25
  top: -1em;
@@ -95,6 +107,7 @@
95
107
 
96
108
  // background: var(--iro-color-bg2);
97
109
  // border: 1px solid red;
110
+ margin-top: 1em;
98
111
  margin-bottom: 2em;
99
112
 
100
113
  position: relative;
@@ -1,110 +1,144 @@
1
1
 
2
- .PurseSummaryW {
3
- position: relative;
4
- background: rgba(255,255,255, 0.75);
5
- height: 400px;
6
- width: 100%;
7
- z-index: 5;
8
- }
9
- .PurseSummary {
10
- position: absolute;
11
- top: 200px;
12
-
2
+ .summaries {
13
3
  display: flex;
4
+ }
5
+ .purses--summary2 {
6
+ // border: 1px solid yellow;
14
7
 
15
- width: 100%;
16
- height: 0;
17
- border-bottom: 1px dotted black;
8
+ label {
9
+ position: absolute;
10
+ }
18
11
 
19
12
  .legendW {
20
- position: relative;
21
- // margin-top: 50%;
13
+ height: 100px;
14
+ margin-left: 60px;
22
15
 
23
- .legend {
24
- margin-top: -50%;
16
+ display: flex;
17
+ }
25
18
 
26
- // position: absolute;
27
- // top: -200px;
28
- // width: 400px;
29
- // height: 400px;
19
+ .PurseSummaryW {
20
+ margin-left: 1em;
21
+ width: 500px;
22
+ z-index: 11;
23
+ height: 400px;
24
+ position: relative;
25
+ background: rgba(255,255,255, 0.75);
30
26
 
31
- background: white;
32
- padding: 0.5em;
33
- }
27
+ }
28
+ .PurseSummary {
29
+ position: absolute;
30
+ top: 50%;
31
+ width: 100%;
32
+ height: 0;
33
+ border-bottom: 1px solid black;
34
34
  }
35
35
 
36
+ /* shared */
37
+ .summary-long, .summary-short {
38
+ // border: 1px solid blue;
39
+ position: absolute;
36
40
 
37
- /*
38
- * summary amount and delta
39
- **/
40
- .summary-amount {
41
- position: relative;
42
- width: 100px;
43
- margin-right: 2em;
41
+ display: flex;
44
42
 
45
- .net-gl {
46
- width: 100%;
47
- background: rgba(0,0,0, 0.5);
48
- }
43
+ width: 100%;
44
+ // height: 300px;
49
45
 
50
- .delta {
46
+ .deltaW {
47
+ border: 2px solid black;
48
+ height: 0;
49
+ display: flex;
50
+ align-items: center;
51
51
  position: absolute;
52
- left: 100px;
53
- height: 100%;
52
+ top: 50%;
53
+ left: 110px;
54
54
 
55
- > div {
56
- border: 1px dotted yellow;
57
- width: 0.5em;
58
- }
59
- .begin {
60
- width: 1em;
55
+ .delta {
56
+ // border: 2px dashed green;
57
+ width: 20px;
61
58
 
62
- background: black;
63
- }
64
- .end {
65
- width: .5em;
66
- left: .25em;
59
+ display: flex;
60
+ align-items: center;
61
+
62
+ .begin {
63
+ width: 100%;
64
+ background: rgba(0,0,0, 0.25);
65
+ }
66
+ .end {
67
+ width: 50%;
68
+ // background: rgba(0,0,0, 0.75);
69
+ }
67
70
 
68
- background: rgba(255,0,0, 0.5);
69
71
  }
70
72
  }
71
73
 
72
- }
74
+ /* shared */
75
+ .plot {
76
+ background: rgba(255,153,0, 0.5);
73
77
 
78
+ position: relative;
74
79
 
75
- .loss {
76
- }
77
- .gain {
78
- }
79
- .max-gl {
80
- position: absolute;
81
- width: 100%;
80
+ width: 100px;
82
81
 
83
- label {
84
- position: absolute;
82
+ .max-gl {
83
+ width: 100%;
84
+ position: absolute;
85
+ background: rgba(255,255,0, 0.5);
86
+ }
87
+ .net-gl {
88
+ position: absolute;
89
+ width: 90%;
90
+ }
91
+ .gain {
92
+ background: rgba(0,0,0, 0.70);
93
+ }
94
+ .loss {
95
+ background: rgba(255,0,0, 0.5);
96
+ }
85
97
  }
86
-
87
-
88
98
  }
89
- .max-gl.long {
90
- }
91
- .max-gl.short {
92
- display: flex;
93
- flex-direction: column-reverse;
94
- }
95
- .long {
96
- position: absolute;
99
+
100
+ .summary-long {
97
101
  top: 0;
98
102
 
99
- background: rgba(255,0,0, 0.5);
100
- border: 1px solid red;
101
- bottom: 0;
103
+ .legendW {
104
+ flex-direction: column;
105
+ }
106
+ .plot {
107
+ bottom: 0;
108
+ .gain {
109
+ bottom: 0;
110
+ }
111
+ .max-gl {
112
+ bottom: 0;
113
+ }
114
+ }
102
115
  }
103
- .short {
104
- background: rgba(255,153,0, 0.5);
105
- border: 1px solid orange;
106
116
 
107
- position: absolute;
117
+ .summary-short {
108
118
  bottom: 0;
119
+
120
+ display: flex;
121
+ align-items: flex-end;
122
+
123
+ .deltaW {
124
+ left: 140px;
125
+ }
126
+ label {
127
+ bottom: 0;
128
+ }
129
+ .legendW {
130
+ flex-direction: column-reverse;
131
+ }
132
+ .plot {
133
+ background: rgba(255,153,0, 0.5);
134
+ width: 100px;
135
+
136
+ .gain {
137
+ top: 0;
138
+ }
139
+ .loss {
140
+ bottom: 0;
141
+ }
142
+ }
109
143
  }
110
- }
144
+ }
@@ -70,7 +70,7 @@
70
70
  /* M */
71
71
 
72
72
  .mini-inputs {
73
- background: rgba(255,255,255, 0.25);
73
+ // background: rgba(255,255,255, 0.25);
74
74
  }
75
75
 
76
76
  .modal-absolute {
@@ -83,15 +83,16 @@
83
83
  position: absolute;
84
84
 
85
85
  min-width: 200px;
86
- width: 400px;
86
+ // width: 400px;
87
87
 
88
88
  min-height: 200px;
89
- height: 300px;
89
+ // height: 300px;
90
+
90
91
  /* overflow: auto; */
91
92
 
92
93
  background: white;
93
94
 
94
- z-index: 2;
95
+ z-index: 200;
95
96
 
96
97
  }
97
98
 
@@ -1,26 +1,73 @@
1
1
 
2
2
  class Iro::PositionsController < Iro::ApplicationController
3
- before_action :set_lists
3
+
4
+ def check
5
+ @position = Iro::Position.find params[:id]
6
+ authorize! :check, @position
7
+ outs = Tda::Order.check_status @position.schwab_order_id
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
+
35
+ redirect_to request.referrer
36
+ end
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
4
49
 
5
50
  def create
6
51
  @position = Iro::Position.new pos_params
7
52
  authorize! :create, @position
8
53
 
9
- @position.inner_strike = params[:inner][:strike]
10
- @position.outer_strike = params[:outer][:strike]
54
+ # @position.inner_strike = params[:inner][:strike]
55
+ # @position.outer_strike = params[:outer][:strike]
11
56
 
12
57
  o_attrs = {
13
58
  expires_on: @position.expires_on,
14
- put_call: @position.put_call, # I need this. _vp_ 2024-04-26
15
- stock_id: @position.stock_id,
59
+ put_call: @position.put_call, # I need this. _vp_ 2024-04-26
60
+ stock_id: @position.stock_id,
16
61
  }
17
- @position.inner = Iro::Option.new params[:inner].permit!.merge( o_attrs )
18
- @position.inner.end_price = @position.inner.begin_price
19
- @position.inner.end_delta = @position.inner.begin_delta
62
+ @position.inner = Iro::Option.create!({ strike: params[:position][:inner_strike] }.merge( o_attrs ))
63
+ @position.inner.sync
64
+ @position.inner.begin_price = @position.inner.end_price
65
+ @position.inner.begin_delta = @position.inner.end_delta
20
66
  if [ Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD, Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD ].include?( @position.strategy.kind )
21
- @position.outer = Iro::Option.new params[:outer].permit!.merge( o_attrs )
22
- @position.outer.end_price = @position.outer.begin_price
23
- @position.outer.end_delta = @position.outer.begin_delta
67
+ @position.outer = Iro::Option.create!({ strike: params[:position][:outer_strike] }.merge( o_attrs ))
68
+ @position.outer.sync
69
+ @position.outer.begin_price = @position.outer.end_price
70
+ @position.outer.begin_delta = @position.outer.end_delta
24
71
  end
25
72
 
26
73
  if @position.save
@@ -53,6 +100,7 @@ class Iro::PositionsController < Iro::ApplicationController
53
100
  def edit
54
101
  @position = Iro::Position.find params[:id]
55
102
  authorize! :edit, @position
103
+ set_position_lists
56
104
  end
57
105
 
58
106
  def eval
@@ -68,6 +116,11 @@ class Iro::PositionsController < Iro::ApplicationController
68
116
  redirect_to request.referrer
69
117
  end
70
118
 
119
+ def index
120
+ authorize! :index, Iro::Position
121
+ @positions = Iro::Position.active
122
+ end
123
+
71
124
  ## only callable from _new.haml, with position partially pre-filled
72
125
  def new
73
126
  authorize! :new, Iro::Position
@@ -81,6 +134,63 @@ class Iro::PositionsController < Iro::ApplicationController
81
134
  # outer: Iro::Option.new,
82
135
  stock_id: strategy.stock_id,
83
136
  }) )
137
+
138
+ set_position_lists
139
+ end
140
+
141
+ ## only credit-spread
142
+ def reprice
143
+ @position = Iro::Position.find params[:id]
144
+ authorize! :roll, @position
145
+ @position.update({ pending_price: params[:pending_price] })
146
+
147
+ Tda::Order.cancel_order!( @position.schwab_order_id )
148
+ outs = Tda::Order.place_order!( Tda::Order.credit_spread_q @position )
149
+
150
+ flag = @position.update({
151
+ schwab_order_id: outs[:schwab_order_id],
152
+ schwab_status: outs[:schwab_status],
153
+ status: Iro::Position::STATUS_PENDING,
154
+ })
155
+
156
+ flash_notice flag
157
+ # redirect_to controller: :purses, action: :show, template: 'show', view_status: 'pending', id: @position.purse_id
158
+ redirect_to request.referrer
159
+ end
160
+
161
+ def place_order
162
+ @position = Iro::Position.find params[:id]
163
+ authorize! :place_order, @position
164
+
165
+ query = case @position.intent
166
+ when Iro::Position::INTENT_CLOSE
167
+ Tda::Order.close_credit_spread_q @position
168
+ else
169
+ throw '_TODO: hls - placing order, not implemented'
170
+ end
171
+ outs = Tda::Order.place_order!( query )
172
+
173
+ flag = @position.update({
174
+ schwab_order_id: outs[:schwab_order_id],
175
+ schwab_status: outs[:schwab_status],
176
+ status: Iro::Position::STATUS_PENDING,
177
+ })
178
+
179
+ flash_notice flag
180
+ redirect_to controller: :purses, action: :show, template: 'show', view_status: 'pending', id: @position.purse_id
181
+ end
182
+
183
+ ## place2 = credit-spread
184
+ ## should be renamped to open_prep2
185
+ def place2
186
+ @position = Iro::Position.find params[:id]
187
+ authorize! :roll, @position
188
+ @position.inner.sync
189
+ @position.inner.update({ begin_price: @position.inner.end_price })
190
+ @position.outer.sync
191
+ @position.outer.update({ begin_price: @position.outer.end_price })
192
+ @position.update({ pending_price: @position.place2_price })
193
+ @query = Tda::Order.credit_spread_q @position
84
194
  end
85
195
 
86
196
  ## 2025-10-14 long_credit_put_spread
@@ -102,11 +212,6 @@ class Iro::PositionsController < Iro::ApplicationController
102
212
  self.send("_prepare_#{@position.strategy.kind}")
103
213
  end
104
214
 
105
- ## 2026-02-26 continue...
106
- ## short credit call spread
107
- ## covered call ???
108
- ## short credit call spread
109
- ## long credit put spread
110
215
  def prepare2
111
216
  @position = Iro::Position.find params[:id]
112
217
  authorize! :roll, @position
@@ -136,15 +241,33 @@ class Iro::PositionsController < Iro::ApplicationController
136
241
  end
137
242
  end
138
243
 
244
+ ## credit-spread
245
+ def place3
246
+ @position = Iro::Position.find params[:id]
247
+ @position.update({ pending_price: params[:pending_price] })
248
+ authorize! :place_order, @position
249
+ outs = Tda::Order.place_order!( Tda::Order.credit_spread_q @position )
250
+
251
+ flag = @position.update({
252
+ schwab_order_id: outs[:schwab_order_id],
253
+ schwab_status: outs[:schwab_status],
254
+ status: Iro::Position::STATUS_PENDING,
255
+ })
256
+
257
+ flash_notice flag
258
+ redirect_to controller: :purses, action: :show, template: 'show', view_status: 'pending', id: @position.purse_id
259
+ end
260
+
139
261
  ## 2026-02-26 continue...
140
262
  ## short credit call spread
141
263
  def prepare3
142
264
  @position = Iro::Position.find params[:id]
143
265
  authorize! :place_order, @position
144
- order_id = Tda::Order.place_order( Tda::Order.roll_credit_call_spread_q @position )
266
+ outs = Tda::Order.place_order!( Tda::Order.roll_credit_call_spread_q @position )
145
267
 
146
268
  flag = @position.update({
147
- schwab_order_id: order_id,
269
+ schwab_order_id: outs[:schwab_order_id],
270
+ schwab_status: outs[:schwab_status],
148
271
  status: Iro::Position::STATUS_PENDING,
149
272
  })
150
273
 
@@ -414,11 +537,9 @@ class Iro::PositionsController < Iro::ApplicationController
414
537
  )
415
538
  end
416
539
 
417
- def set_lists
418
- super
419
- @purses_list = Iro::Purse.list
420
- @strategies_list = Iro::Strategy.list(params[:long_or_short])
540
+ def set_position_lists
421
541
  @stocks_list = Iro::Stock.list
542
+ @strategies_list = ( @position.purse.strategies.list + [[ @position.strategy.to_s, @position.strategy.id.to_s ]] ).uniq
422
543
  end
423
544
 
424
545
  end