iron_warbler 2.0.7.20 → 2.0.7.21

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0deda82521a6d2995c6cf495e7276550ce2d9f12541b829dbc903c0c1d64050c
4
- data.tar.gz: 8742db15fd84ccd0f344f194380b4074d9b615dc9b95b1f88ddf41504601408c
3
+ metadata.gz: fabfbb9bdc5c7cceac9b4cf0e3fdb5513c89f199502f5731b2f4d423e96a90d0
4
+ data.tar.gz: b182eba8faab8d64b7c75826ab2b5c7328e6fa4123201f334238e9d981293992
5
5
  SHA512:
6
- metadata.gz: ae6c37ed5e85029f73f1fefcb825020e8da3ab4e69e7e85ae16bdfa29ba62673bb3a32f75124026fba0e6155423cbc5fd0cc3695a7c994bf6662d6287b7f4c69
7
- data.tar.gz: 4bbb876537fb451b1734fd3b0a431de13ff03e8cff9eeed75851b19048580091dbb16ef2376dee6ee9ddd9df65d8bee9b2d50a15e8b0afaa9403323f306a8de1
6
+ metadata.gz: c33a21b2c7c4587088b9eccf288075ccb1bcd6ec3bb62e87deeed5b9f28ba1fa1f875e37bda0e875ae8d74af9907c1dd2232bbad7bd45b70cc7ca96106d98f6c
7
+ data.tar.gz: 6e38e2f1815f67c5afa4936c3604cc668b79a15c1f7541f1ff5196344e8fd022acb1457ecf7524935e726186202c7162b9626dded867bfe48b75a2dae038fe9a
@@ -1,4 +1,9 @@
1
1
 
2
+ .positions--header {
3
+ position: relative;
4
+ z-index: 1;
5
+ }
6
+
2
7
  .positions--table {
3
8
 
4
9
  table {
@@ -15,17 +20,12 @@
15
20
  border: 1px solid red;
16
21
 
17
22
  > * {
18
- // border: 1px solid yellow;
19
- // background: #ddd;
20
-
21
23
  transform-origin: 0 0;
22
24
  rotate: -40deg;
23
25
 
24
26
  padding: .4em 0;
25
27
  width: 120px;
26
-
27
28
  }
28
-
29
29
  }
30
30
 
31
31
  th.begin_price {
@@ -51,5 +51,16 @@
51
51
  border-left: 5px solid var(--iro-color-short);
52
52
  }
53
53
 
54
+ tr.covered_call {
55
+ .begin-outer-price,
56
+ .end-outer-price,
57
+ .max-gainp,
58
+ .max-loss,
59
+ .outer-strike,
60
+ ._ {
61
+ display: none;
62
+ }
63
+ }
64
+
54
65
  }
55
66
  }
@@ -53,10 +53,22 @@
53
53
 
54
54
  left: 0;
55
55
  top: 0;
56
+ }
57
+ /* only for covered calls */
58
+ .PositionC {
59
+ background: rgba(255,153,51, 0.5);
60
+ position: absolute;
61
+
62
+ /* HEREHERE: either left, or right 0, this orange strip flips. */
63
+ // left: 0;
64
+ right: 0;
56
65
 
66
+ width: 10000px;
67
+ height: 100%;
57
68
  }
58
69
 
59
- .MaxGain {
70
+ .MaxGain,
71
+ .Breakeven {
60
72
  position: absolute;
61
73
  right: 0;
62
74
  bottom: -10%;
@@ -87,34 +99,18 @@
87
99
  border-left: 1px solid var(--iro-color-grid1);
88
100
  border-bottom: 1px solid var(--iro-color-grid1);
89
101
 
90
- height: 50px;
91
-
92
102
  margin-left: 50%;
93
103
  margin-bottom: 0em;
94
104
 
95
105
  position: relative;
96
106
 
97
- .Breakeven {
98
- // background: cyan;
99
- border-right: 2px solid lightblue;
100
-
101
- .half-circle {
102
- width: 100%;
103
- height: 100%; /* as the half of the width */
104
- background-color: lightblue;
105
- border-top-left-radius: 100%; /* 100px of height + 10px of border */
106
- border-top-right-radius: 100%; /* 100px of height + 10px of border */
107
- // border: 10px solid gray;
108
- // border-bottom: 0;
109
- }
110
- }
111
-
112
107
  .Last {
113
108
  border-left: 2px dotted red;
114
109
  }
115
110
  .label {
116
111
  width: 200px;
117
112
  color: gray;
113
+ // border: 1px solid cyan;
118
114
  }
119
115
 
120
116
  .marker {
@@ -142,32 +138,35 @@
142
138
  background: rgba(255,0,0, 0.75);
143
139
  }
144
140
 
145
- .grid-mark:nth-child(4n + 1) {
146
- border: 1px solid red;
147
- display: none;
148
- }
149
- .grid-mark:nth-child(4n) {
150
- border: 1px solid red;
151
- display: none;
152
- }
153
- .grid-mark:nth-child(6n + 1) {
154
- border: 1px solid red;
155
- display: none;
156
- }
157
- .grid-mark:nth-child(6n) {
158
- border: 1px solid red;
159
- display: none;
160
- }
161
- .grid-mark:nth-child(3n + 1) {
162
- border: 1px solid red;
163
- display: none;
164
- }
165
- .grid-mark:nth-child(3n) {
166
- border: 1px solid red;
167
- display: none;
168
- }
141
+
142
+ // .grid-mark:nth-child(4n + 1) {
143
+ // border: 1px solid red;
144
+ // display: none;
145
+ // }
146
+ // .grid-mark:nth-child(4n) {
147
+ // border: 1px solid red;
148
+ // display: none;
149
+ // }
150
+ // .grid-mark:nth-child(6n + 1) {
151
+ // border: 1px solid red;
152
+ // display: none;
153
+ // }
154
+ // .grid-mark:nth-child(6n) {
155
+ // border: 1px solid red;
156
+ // display: none;
157
+ // }
158
+ // .grid-mark:nth-child(3n + 1) {
159
+ // border: 1px solid red;
160
+ // display: none;
161
+ // }
162
+ // .grid-mark:nth-child(3n) {
163
+ // border: 1px solid red;
164
+ // display: none;
165
+ // }
169
166
 
170
167
  .grid-mark {
168
+ // border: 1px solid red;
169
+
171
170
  height: 100%;
172
171
  position: absolute;
173
172
  top: 0;
@@ -175,13 +174,37 @@
175
174
  z-index: -2;
176
175
  border-left: 1px dashed var(--iro-color-grid1);
177
176
 
177
+ .label::before {
178
+ content: "";
179
+ position: absolute;
180
+ left: -1em;
181
+ width: 1em;
182
+ height: 1em;
183
+ border: 1em solid transparent;
184
+ border-left-color: white;
185
+ }
178
186
  .label {
179
- transform: rotate(-30deg);
187
+
188
+ // border: 1px solid red;
189
+
190
+ transform: rotate(-45deg);
191
+ transform-origin: center left;
192
+
180
193
  font-size: 0.8em;
181
194
 
182
195
  position: absolute;
183
- // bottom: -1em;
184
- z-index: 0;
196
+ height: 1em;
197
+ line-height: 1em;
198
+ bottom: -0em;
199
+ z-index: -2;
200
+ width: 0;
201
+
202
+ .labelC {
203
+ background: white;
204
+ position: absolute;
205
+ top: 1.5em;
206
+ left: -1.5em;
207
+ }
185
208
  }
186
209
  }
187
210
 
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
3
 
4
- .long-or-short::before {
5
- // content: '[LONG]';
6
- }
4
+ // .long-or-short::before {
5
+ // // content: '[LONG]';
6
+ // }
7
7
  .long-or-short-item,
8
8
  .long-or-short-container .is_long,
9
9
  .long-or-short-container .is_short {
@@ -48,6 +48,8 @@
48
48
  margin-right: 1em;
49
49
  }
50
50
 
51
+ /* H */
52
+
51
53
  /* M */
52
54
 
53
55
  .modal-absolute {
@@ -76,7 +78,4 @@
76
78
 
77
79
  /* W */
78
80
 
79
- .w-min-50px {
80
- min-width: 50px;
81
- }
82
81
 
@@ -33,6 +33,25 @@ class Iro::PositionsController < Iro::ApplicationController
33
33
  authorize! :edit, @position
34
34
  end
35
35
 
36
+ def refresh
37
+ @position = pos = Iro::Position.find params[:id]
38
+ authorize! :refresh, @position
39
+
40
+ ## covered call
41
+ out = Tda::Option.get_quote({
42
+ contractType: 'CALL',
43
+ strike: pos.inner_strike,
44
+ expirationDate: pos.expires_on,
45
+ ticker: pos.stock.ticker,
46
+ })
47
+ puts! out, 'out'
48
+ @position.update({
49
+ end_inner_price: ( out.bid + out.ask ) / 2,
50
+ end_inner_delta: out.delta,
51
+ })
52
+ redirect_to request.referrer || purse_path( @position.purse )
53
+ end
54
+
36
55
  def roll
37
56
  @position = Iro::Position.find params[:id]
38
57
  authorize! :roll, @position
@@ -37,9 +37,9 @@ class Iro::PursesController < Iro::ApplicationController
37
37
  @positions = @purse.positions.includes( :strategy
38
38
  ).order({ expires_on: :desc })
39
39
 
40
- @unit = 12 ## pixels per dollar
41
- @height = 100 ## pixels
42
- @grid_size = 75 ## dollars to each side of origin
40
+ @unit = @purse.unit # 12 ## pixels per dollar
41
+ @height = @purse.height # 100 ## pixels
42
+ @n_dollars = 100 ## dollars to each side of origin
43
43
 
44
44
  render params[:template]
45
45
  end
@@ -48,8 +48,10 @@ class Iro::PursesController < Iro::ApplicationController
48
48
  @purse = Iro::Purse.find(params[:id])
49
49
  authorize! :update, @purse
50
50
  if @purse.update params[:purse].permit!
51
- redirect_to action: :index, notice: 'Purse was successfully updated.'
51
+ flash[:notice] = 'ok'
52
+ redirect_to purse_path(@purse)
52
53
  else
54
+ flash_alert @purse
53
55
  render :edit
54
56
  end
55
57
  end
@@ -0,0 +1,14 @@
1
+
2
+ # require 'net/scp'
3
+ # require 'open3'
4
+ require 'sidekiq'
5
+
6
+ class Iro::TdaJob
7
+ include Sidekiq::Job
8
+ sidekiq_options queue: 'iro_wor_rb'
9
+
10
+ def perform
11
+
12
+ end
13
+
14
+ end
@@ -54,7 +54,7 @@ class Iro::Position
54
54
  field :end_inner_delta, type: :float
55
55
 
56
56
  def breakeven
57
- inner_strike - begin_outer_price + begin_inner_price
57
+ strategy.breakeven(self)
58
58
  end
59
59
 
60
60
  def current_underlying_strike
@@ -10,6 +10,10 @@ class Iro::Purse
10
10
 
11
11
  has_many :positions, class_name: 'Iro::Position', inverse_of: :purse
12
12
 
13
+ field :unit, type: :integer
14
+ field :height, type: :integer
15
+ field :mark_every_n_usd, type: :float
16
+
13
17
  def to_s
14
18
  slug
15
19
  end
@@ -52,6 +52,14 @@ class Iro::Strategy
52
52
  where( ticker: ticker )
53
53
  end
54
54
 
55
+ def breakeven p
56
+ p.inner_strike - p.begin_outer_price + p.begin_inner_price
57
+ end
58
+
59
+ def breakeven p
60
+ p.inner_strike + p.begin_inner_price
61
+ end
62
+
55
63
  def max_gain_covered_call p
56
64
  # return p.begin_inner_price
57
65
  p.begin_inner_price * 100 - 0.66
@@ -66,7 +74,7 @@ class Iro::Strategy
66
74
  end
67
75
 
68
76
  def max_loss_covered_call p
69
- return 'inf'
77
+ return 'infinity'
70
78
  end
71
79
  def max_loss_long_debit_call_spread p
72
80
  out = 100 * ( p.outer_strike - p.inner_strike )
@@ -13,7 +13,7 @@ class Tda::Option
13
13
  def self.get_chain params
14
14
  opts = { symbol: params[:ticker] } ## use 'GME' as symbol here even though a symbol is eg 'GME_021023P2.5'
15
15
  query = { apikey: ::TD_AMERITRADE[:apiKey] }.merge opts
16
- # puts! query, 'input opts'
16
+ puts! query, 'input opts'
17
17
 
18
18
  path = "/v1/marketdata/chains"
19
19
  out = self.get path, { query: query }
@@ -55,7 +55,7 @@ class Tda::Option
55
55
  ## 2023-03-18 _vp_ This is what I should be using to check if a position should be rolled.
56
56
  ##
57
57
  def self.get_quote params
58
- ::Tda::Option.get_quotes(params)[0]
58
+ OpenStruct.new ::Tda::Option.get_quotes(params)[0]
59
59
  end
60
60
 
61
61
  ##
@@ -79,18 +79,18 @@ class Tda::Option
79
79
  if params[s]
80
80
  opts[s] = params[s]
81
81
  else
82
- raise Iwa::InputError.new("Invalid input, missing '#{s}'.")
82
+ raise Iro::InputError.new("Invalid input, missing '#{s}'.")
83
83
  end
84
84
  end
85
85
  if params[:expirationDate]
86
86
  opts[:fromDate] = opts[:toDate] = params[:expirationDate]
87
87
  else
88
- raise Iwa::InputError.new("Invalid input, missing 'date'.")
88
+ raise Iro::InputError.new("Invalid input, missing 'date'.")
89
89
  end
90
90
  if params[:ticker]
91
91
  opts[:symbol] = params[:ticker].upcase
92
92
  else
93
- raise Iwa::InputError.new("Invalid input, missing 'ticker'.")
93
+ raise Iro::InputError.new("Invalid input, missing 'ticker'.")
94
94
  end
95
95
 
96
96
  if params[:strike]
@@ -98,7 +98,7 @@ class Tda::Option
98
98
  end
99
99
 
100
100
  query = { apikey: ::TD_AMERITRADE[:apiKey] }.merge opts
101
- # puts! query, 'input opts'
101
+ puts! query, 'input opts'
102
102
 
103
103
  path = "/v1/marketdata/chains"
104
104
  out = self.get path, { query: query }
@@ -120,7 +120,7 @@ class Tda::Option
120
120
  end
121
121
  end
122
122
 
123
- # puts! outs, 'outs'
123
+ puts! outs, 'outs'
124
124
  return outs
125
125
  end
126
126
 
@@ -10,19 +10,21 @@
10
10
  .a
11
11
  = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
12
12
  .StockCoordinatesW
13
- .StockCoordinates
13
+ .StockCoordinates{ style: "height: #{pos.purse.height}px " }
14
14
  = render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock
15
15
 
16
16
  .Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
17
17
  .label Last: #{pp_amount stock.last}
18
18
  .c
19
19
 
20
- - left = "#{ (stock.last - position.inner_strike - position.begin_inner_price) * u}px"
21
- - width = "#{ position.begin_inner_price * u}px"
22
- .PositionW{ style: "left: #{left}; width: #{width}; " }
20
+ -## Good, remove trash, leave as implemented.
21
+ -# - left = "#{ (stock.last - position.inner_strike - position.begin_inner_price) * u}px"
22
+ -# - width = "#{ position.begin_inner_price * u}px"
23
+ - left = "#{ (stock.last - pos.inner_strike) * u}px"
24
+ - width = "0px"
25
+ .PositionW{ style: "left: #{left} ; width: #{width} " }
23
26
  .Position
24
- -# .label
25
- -# width: #{ ( position.begin_inner_price - position.begin_outer_price - position.outer_strike + position.inner_strike ) }
27
+ .PositionC
26
28
 
27
29
  - if position.net_amount >= 0
28
30
  .Net.NetPositive{ style: "width: #{ (position.net_amount / 100) * u }px; right: 0" }
@@ -34,3 +36,9 @@
34
36
  .label
35
37
  net
36
38
  = pp_amount position.net_amount
39
+
40
+ .Breakeven{ style: "width: #{ pos.begin_inner_price * u }px" }
41
+ .label
42
+ Breakeven:
43
+ = pos.begin_inner_price
44
+
@@ -2,7 +2,7 @@
2
2
  - pos = position
3
3
  - stock = pos.stock
4
4
  - nearest_strike = stock.last.round
5
- - u = @unit # pixels per dollar
5
+ - u = @purse.unit # pixels per dollar
6
6
 
7
7
  .collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
8
8
  [<>]
@@ -10,7 +10,7 @@
10
10
  .a
11
11
  = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
12
12
  .StockCoordinatesW
13
- .StockCoordinates
13
+ .StockCoordinates{ style: "height: #{pos.purse.height}px " }
14
14
  = render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock
15
15
 
16
16
  .Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
@@ -11,7 +11,7 @@
11
11
  .a
12
12
  = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
13
13
  .StockCoordinatesW
14
- .StockCoordinates
14
+ .StockCoordinates{ style: "height: #{pos.purse.height}px " }
15
15
  = render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock
16
16
 
17
17
  .Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
@@ -1,5 +1,5 @@
1
1
 
2
- .maxwidth
2
+ .positions--header.maxwidth
3
3
  = pos
4
4
  = link_to '[roll]', roll_position_path(pos)
5
5
  = link_to '[~]', edit_position_path(pos)
@@ -19,8 +19,8 @@
19
19
  .a outer_strike, inner_strike
20
20
  %th.begin_price
21
21
  .a Begin outer price, delta
22
- %th.max_loss
23
- .a Max Loss, gain
22
+ %th.max-loss Max Loss
23
+ %th.max-gain Max Gain
24
24
  %th
25
25
  .end_price End Price, delta
26
26
  %th
@@ -52,11 +52,12 @@
52
52
  -# %hr
53
53
  .h-50px
54
54
 
55
- %tr{ class: position.strategy.long_or_short }
55
+ %tr{ class: [ position.strategy.kind, position.strategy.long_or_short ] }
56
56
  %td.actions
57
57
  .flex-row
58
58
  = button_to 'x', position_path(position), method: :delete, data: { confirm: 'Are you sure?' }
59
59
  = link_to '[~]', edit_position_path(position)
60
+ = link_to '[refresh]', refresh_position_path(pos)
60
61
  - if position.next_reasons.present? && position.should_rollp && position.should_rollp > 0.5
61
62
  = button_to 'Roll', roll_position_path(position)
62
63
  - if position.next_reasons.present?
@@ -81,29 +82,30 @@
81
82
  = pp_amount position.stock.last
82
83
  %td.strikes
83
84
  .long-or-short-item
84
- .a= pp_amount position.outer_strike
85
- .a= pp_amount position.inner_strike
85
+ .outer-strike= pp_amount position.outer_strike
86
+ .inner-strike= pp_amount position.inner_strike
86
87
 
87
88
  %td.begin_price
88
89
  .long-or-short-item
89
- .a
90
+ .begin-outer-price
90
91
  = pp_amount position.begin_outer_price
91
92
  <b>D</b> #{pp_delta position.begin_outer_delta}
92
- .a
93
+ .begin-inner-price
93
94
  = pp_amount position.begin_inner_price
94
95
  <b>D</b> #{pp_delta position.begin_inner_delta}
95
- %td.max_loss.max_gain
96
- = pp_amount position.max_loss * pos.q, precision: 0
97
- %br
98
- = pp_amount position.max_gain * pos.q, precision: 0
99
- %br
100
- = pp_percent( -1 * position.max_gain / position.max_loss ) rescue '-' # undef. for covered calls
96
+ %td
97
+ .max-loss= pp_amount position.max_loss * pos.q, precision: 0
98
+ %td
99
+ .max-gain= pp_amount position.max_gain * pos.q, precision: 0
100
+ .max-gainp
101
+ -# = pp_percent( -1 * position.max_gain / position.max_loss ) rescue '-' # undef. for covered calls
102
+
101
103
  %td.end_price
102
104
  .long-or-short-item
103
- .a
105
+ .end-outer-price
104
106
  = pp_amount position.end_outer_price
105
107
  <b>D</b> #{pp_delta position.end_outer_delta}
106
- .a
108
+ .end-inner-price
107
109
  = pp_amount position.end_inner_price
108
110
  <b>D</b> #{pp_delta position.end_inner_delta}
109
111
  %td.net
@@ -1,7 +1,7 @@
1
1
 
2
- - unit = u = 50 # pixels per dollar
3
- - grid_size = 100 # dollars to each side of origin
2
+ - u = @purse.unit # 50 ## pixels per dollar
4
3
  - strategy = @position.strategy
4
+
5
5
  .purses-gameui.padded
6
6
  = render '/iro/purses/header', purse: @position.purse
7
7
 
@@ -23,7 +23,7 @@
23
23
  .StockCoordinates
24
24
  .grid-mark.mark0
25
25
  .label= nearest_strike
26
- - (1...grid_size).each_with_index do |idx|
26
+ - (1...@n_dollars).each_with_index do |idx|
27
27
  .grid-mark{ class: "mark#{idx}", style: "left: -#{idx * u}px" }
28
28
  .label
29
29
  = nearest_strike + idx
@@ -59,7 +59,7 @@
59
59
  .StockCoordinates
60
60
  .grid-mark.mark0
61
61
  .label= nearest_strike
62
- - (1...grid_size).each_with_index do |idx|
62
+ - (1...@n_dollars).each_with_index do |idx|
63
63
  .grid-mark{ class: "mark#{idx}", style: "left: -#{idx * u}px" }
64
64
  .label
65
65
  = nearest_strike + idx
@@ -5,5 +5,6 @@
5
5
  .field
6
6
  %label Slug
7
7
  = f.text_field :slug
8
+ = render '/iro/purses/form_extra_fields', f: f
8
9
  .actions
9
10
  = f.submit
@@ -0,0 +1,14 @@
1
+
2
+ %label unit
3
+ = f.number_field :unit
4
+ px/usd
5
+ &nbsp;&nbsp;
6
+
7
+ %label height
8
+ = f.number_field :height
9
+ px
10
+ &nbsp;&nbsp;
11
+
12
+ %label mark_every_n_usd
13
+ = f.number_field :mark_every_n_usd, step: 0.01
14
+ &nbsp;&nbsp;
@@ -9,10 +9,14 @@
9
9
  = link_to '[view]', purse_path(purse)
10
10
  (#{purse.positions.length})
11
11
 
12
-
13
-
14
12
  = link_to '[+position]', new_position_path({ purse_id: purse.id })
15
13
  = link_to '[+long]', new_position_path({ purse_id: purse.id, long_or_short: Iro::Strategy::LONG })
16
14
  = link_to '[+short]', new_position_path({ purse_id: purse.id, long_or_short: Iro::Strategy::SHORT })
17
- %br
15
+
16
+ - if params[:template] == 'gameui'
17
+ .mini-inputs
18
+ = form_for purse, html: { class: 'd-flex' } do |f|
19
+ = render '/iro/purses/form_extra_fields', f: f
20
+ = f.submit '>'
21
+
18
22
  %br
@@ -1,12 +1,12 @@
1
1
 
2
2
  = render '/iro/purses/header', purse: @purse
3
3
 
4
- - u = @unit
5
- .purses-gameuiW{ data: { margin: { left: u*@grid_size } } }
4
+ - u = @purse.unit
5
+ .purses-gameuiW{ data: { margin: { left: u*@n_dollars } } }
6
6
  .purses-gameui
7
7
  .a
8
8
 
9
- %div{ style: "margin-left: #{u*@grid_size}px; width: 100% " }
9
+ %div{ style: "margin-left: #{u*@n_dollars}px; width: 100% " }
10
10
  - @positions.each_with_index do |pos, idx|
11
11
  - if idx == 0
12
12
  %h4.maxwidth= pos.stock
@@ -15,4 +15,5 @@
15
15
  - if pos.stock != prev_.stock
16
16
  %hr
17
17
  %h4.maxwidth= pos.stock
18
+ -# = pos.strategy.kind
18
19
  = render "/iro/positions/gameui_#{pos.strategy.kind}", position: pos
@@ -1,13 +1,16 @@
1
1
 
2
2
  - nearest_strike = stock.last.round
3
- - u = @unit
3
+ - u = @purse.unit
4
+ - every_n = @purse.mark_every_n_usd
4
5
 
5
6
  .grid-mark.mark0
6
- .label= nearest_strike
7
- - (1...@grid_size).each_with_index do |idx|
7
+ .label
8
+ .labelC= nearest_strike
9
+ - (1...@n_dollars).each_with_index do |idx|
10
+ - idx = idx * every_n
8
11
  .grid-mark{ class: "mark#{idx}", style: "left: #{idx * u}px" }
9
12
  .label
10
- = nearest_strike + idx
13
+ .labelC= nearest_strike + idx
11
14
  .grid-mark{ class: "mark-#{idx}", style: "left: -#{idx * u}px" }
12
15
  .label
13
- = nearest_strike - idx
16
+ .labelC= nearest_strike - idx
@@ -1,13 +1,16 @@
1
1
 
2
2
  - nearest_strike = stock.last.round
3
- - u = @unit
3
+ - u = @purse.unit
4
+ - every_n = @purse.mark_every_n_usd
4
5
 
5
6
  .grid-mark.mark0
6
- .label= nearest_strike
7
- - (1...@grid_size).each_with_index do |idx|
7
+ .label
8
+ .labelC= nearest_strike
9
+ - (1...@n_dollars).each_with_index do |idx|
10
+ - idx = idx * every_n
8
11
  .grid-mark{ class: "mark#{idx}", style: "left: -#{idx * u}px" }
9
12
  .label
10
- = nearest_strike + idx
13
+ .labelC= nearest_strike + idx
11
14
  .grid-mark{ class: "mark-#{idx}", style: "left: #{idx * u}px" }
12
15
  .label
13
- = nearest_strike - idx
16
+ .labelC= nearest_strike - idx
data/config/routes.rb CHANGED
@@ -11,6 +11,7 @@ Iro::Engine.routes.draw do
11
11
 
12
12
  get 'positions/:id/roll', to: 'positions#roll', as: :roll_position
13
13
  post 'positions/:id/roll', to: 'positions#do_roll'
14
+ get 'positions/:id/refresh', to: 'positions#refresh', as: :refresh_position
14
15
  resources :positions
15
16
  resources :profiles
16
17
 
data/lib/iro/engine.rb CHANGED
@@ -5,3 +5,5 @@ class Iro::Engine < ::Rails::Engine
5
5
  isolate_namespace Iro
6
6
  end
7
7
 
8
+ class Iro::InputError < StandardError
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_warbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7.20
4
+ version: 2.0.7.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Pudeyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-15 00:00:00.000000000 Z
11
+ date: 2024-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: business_time
@@ -218,6 +218,7 @@ files:
218
218
  - app/controllers/iro/stocks_controller.rb
219
219
  - app/controllers/iro/strategies_controller.rb
220
220
  - app/helpers/iro/application_helper.rb
221
+ - app/jobs/tda_job.rb
221
222
  - app/mailers/iro/alert_mailer.rb
222
223
  - app/mailers/iro/application_mailer.rb
223
224
  - app/models/iro/alert.rb
@@ -225,12 +226,12 @@ files:
225
226
  - app/models/iro/date.rb
226
227
  - app/models/iro/option.rb
227
228
  - app/models/iro/position.rb
228
- - app/models/iro/position_covered_call.rb
229
- - app/models/iro/position_debit_spread.rb
230
229
  - app/models/iro/price_item.rb
231
230
  - app/models/iro/purse.rb
232
231
  - app/models/iro/stock.rb
233
232
  - app/models/iro/strategy.rb
233
+ - app/models/iro/trash/position_covered_call.rb
234
+ - app/models/iro/trash/position_debit_spread.rb
234
235
  - app/models/tda/option.rb
235
236
  - app/models/tda/stock.rb
236
237
  - app/views/iro/_analytics.erb
@@ -257,6 +258,7 @@ files:
257
258
  - app/views/iro/positions/roll.haml
258
259
  - app/views/iro/positions/trash/_header_short_debit_put_spread.haml
259
260
  - app/views/iro/purses/_form.haml
261
+ - app/views/iro/purses/_form_extra_fields.haml
260
262
  - app/views/iro/purses/_header.haml
261
263
  - app/views/iro/purses/edit.haml
262
264
  - app/views/iro/purses/gameui.haml