iron_warbler 2.0.7.22 → 2.0.7.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/iron_warbler/application.css +12 -0
  3. data/app/assets/stylesheets/iron_warbler/positions.scss +2 -0
  4. data/app/assets/stylesheets/iron_warbler/positions_gameui.scss +11 -0
  5. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +6 -2
  6. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +98 -0
  7. data/app/assets/stylesheets/iron_warbler/utils.scss +4 -0
  8. data/app/controllers/iro/alerts_controller.rb +2 -0
  9. data/app/controllers/iro/application_controller.rb +13 -0
  10. data/app/controllers/iro/positions_controller.rb +197 -23
  11. data/app/controllers/iro/purses_controller.rb +60 -6
  12. data/app/controllers/iro/stocks_controller.rb +30 -18
  13. data/app/controllers/iro/strategies_controller.rb +12 -1
  14. data/app/models/iro/alert.rb +1 -0
  15. data/app/models/iro/option.rb +1 -0
  16. data/app/models/iro/position.rb +124 -56
  17. data/app/models/iro/purse.rb +15 -4
  18. data/app/models/iro/stock.rb +3 -0
  19. data/app/models/iro/strategy.rb +122 -27
  20. data/app/models/tda/option.rb +3 -3
  21. data/app/views/iro/_main_header.haml +28 -17
  22. data/app/views/iro/application/home.haml +6 -1
  23. data/app/views/iro/positions/_form.haml +1 -2
  24. data/app/views/iro/positions/_gameui_covered_call.haml +10 -13
  25. data/app/views/iro/positions/_gameui_covered_call.haml-bk +8 -0
  26. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +5 -4
  27. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +5 -4
  28. data/app/views/iro/positions/_header.haml +2 -2
  29. data/app/views/iro/positions/_header_covered_call.haml +7 -1
  30. data/app/views/iro/positions/_header_long_debit_call_spread.haml +19 -1
  31. data/app/views/iro/positions/_prepare_covered_call.haml +25 -0
  32. data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +23 -0
  33. data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +23 -0
  34. data/app/views/iro/positions/_table.haml +33 -24
  35. data/app/views/iro/positions/prepare.haml +24 -0
  36. data/app/views/iro/positions/roll-cc.haml-bk +40 -0
  37. data/app/views/iro/positions/roll.haml-trash +42 -0
  38. data/app/views/iro/purses/_form.haml +9 -0
  39. data/app/views/iro/purses/_form_extra_fields.haml +25 -13
  40. data/app/views/iro/purses/_header.haml +15 -16
  41. data/app/views/iro/purses/_summary.haml +69 -0
  42. data/app/views/iro/purses/gameui.haml +12 -7
  43. data/app/views/iro/purses/index.haml +3 -1
  44. data/app/views/iro/purses/show.haml +5 -1
  45. data/app/views/iro/stocks/_form.haml +5 -0
  46. data/app/views/iro/stocks/_grid_is_long.haml +2 -2
  47. data/app/views/iro/stocks/_grid_is_short.haml +2 -2
  48. data/app/views/iro/stocks/index.haml +3 -2
  49. data/app/views/iro/strategies/_form.haml +12 -6
  50. data/app/views/iro/strategies/_show.haml +3 -3
  51. data/app/views/iro/strategies/_table.haml +15 -6
  52. data/app/views/iro/strategies/show.haml +14 -0
  53. data/app/views/layouts/iro/application.haml +4 -0
  54. data/config/routes.rb +6 -2
  55. metadata +12 -4
  56. data/app/views/iro/positions/roll.haml +0 -83
  57. data/app/views/iro/positions/trash/_header_short_debit_put_spread.haml +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cebb47a68d7145641d296c6dba9d452facc1826e94515f1c372969449297686d
4
- data.tar.gz: 1856079c227ee3f079da067a2ef9b47c8f6c3f617b483527a5616192d0c95754
3
+ metadata.gz: f64245aea1af513cc312b8c87be3ccfb2a81dbdd8d65842800dc88a29b264bab
4
+ data.tar.gz: c0034386ae09bead5e5273e9d344a7fd8c85985d8687d588cb23e7fa251a9087
5
5
  SHA512:
6
- metadata.gz: 854b5350d8f9f7edd2f02bde20cf0a94cfbc6eb39a3662ef8e15c3395b2f5349e0466e8db813a7a338b743a69e6bd8ca3d18a4c090306c3da78a00cfe1e959ef
7
- data.tar.gz: 9586d7277cf4174e4515922849c0e4b7a5a385da8bebaf5ebc87d76c4e1c111ff7a89800d7eaaf6de30b4e708f22cee04afb2b51c9b8c90f53f762553d0023b1
6
+ metadata.gz: 98dcf54902ba16226374f047be14008e280ae241591fa9182ca248d27c55a4328d8a2811de56d569ce7f9b0df24aaf88281a07f5c55edc99e665a1841cfbdc51
7
+ data.tar.gz: ce86ed7930411a2aef0c45b1f0299b329246c9b04058b8a8817ebf7ac0092e58c241901d89f4adaf092f58120c8faf47f580924ef7456b427c4b8152dec8901b
@@ -27,3 +27,15 @@ html {
27
27
  /* body {
28
28
  color: red !important;
29
29
  } */
30
+
31
+ .iro--main-header {
32
+ li {
33
+ margin-bottom: 0.2em;
34
+
35
+ a {
36
+ background: white;
37
+ padding: 0 0.2em;
38
+ }
39
+ }
40
+ }
41
+
@@ -0,0 +1,11 @@
1
+
2
+ .positions--prepare {
3
+ .RollGuide {
4
+ height: 100vh;
5
+ border: 1px dashed gray;
6
+ position: absolute;
7
+ right: 0;
8
+ overflow: hidden;
9
+ }
10
+ }
11
+
@@ -31,6 +31,9 @@
31
31
  z-index: 2;
32
32
  }
33
33
  }
34
+ .PositionW.short_debit_put_spread {
35
+ background: rgba(255,153,0, 0.25);
36
+ }
34
37
  .PositionW {
35
38
  top: 0;
36
39
  border: 2px solid black;
@@ -47,13 +50,14 @@
47
50
 
48
51
  .Position {
49
52
  position: absolute;
50
- background: rgba(0,255,255, 0.25);
51
53
  width: 100%;
52
54
  height: 90%;
53
55
 
54
56
  left: 0;
55
57
  top: 0;
56
58
  }
59
+
60
+
57
61
  /* only for covered calls */
58
62
  .PositionC {
59
63
  background: rgba(255,153,51, 0.5);
@@ -72,7 +76,7 @@
72
76
  position: absolute;
73
77
  right: 0;
74
78
  bottom: -10%;
75
- border: 2px solid green;
79
+ border: 2px dotted green;
76
80
  background: rgba(0,255,0, 0.5);
77
81
  height: 10%;
78
82
  }
@@ -0,0 +1,98 @@
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
+
13
+ display: flex;
14
+
15
+ width: 100%;
16
+ height: 0;
17
+ border-bottom: 1px dotted black;
18
+
19
+ .legendW {
20
+ position: relative;
21
+ // margin-top: 50%;
22
+
23
+ .legend {
24
+ margin-top: -50%;
25
+
26
+ // position: absolute;
27
+ // top: -200px;
28
+ // width: 400px;
29
+ // height: 400px;
30
+
31
+ background: white;
32
+ padding: 0.5em;
33
+ }
34
+ }
35
+
36
+
37
+ /*
38
+ * summary amount and delta
39
+ **/
40
+ .summary-amount {
41
+ position: relative;
42
+ width: 100px;
43
+
44
+ .net-gl {
45
+ width: 100%;
46
+ background: rgba(0,0,0, 0.5);
47
+ }
48
+ }
49
+ .summary-delta {
50
+ position: relative;
51
+ margin-right: 1em;
52
+ width: 1em;
53
+
54
+ > div {
55
+ border: 1px dotted yellow;
56
+ }
57
+ .begin {
58
+ width: 1em;
59
+
60
+ background: black;
61
+ }
62
+ .end {
63
+ width: .5em;
64
+ left: .25em;
65
+
66
+ background: rgba(255,0,0, 0.5);
67
+ }
68
+ }
69
+ .loss {
70
+ }
71
+ .gain {
72
+ }
73
+ .max-gl {
74
+ position: absolute;
75
+ width: 100%;
76
+ }
77
+ .max-gl.long {
78
+ background: rgba(255,0,0, 0.5);
79
+ }
80
+ .max-gl-short {
81
+ background: rgba(255,153,0, 0.5);
82
+ }
83
+ .long {
84
+ position: absolute;
85
+ top: 0;
86
+
87
+ background: rgba(255,0,0, 0.5);
88
+ border: 1px solid red;
89
+ bottom: 0;
90
+ }
91
+ .short {
92
+ background: rgba(255,153,0, 0.5);
93
+ border: 1px solid orange;
94
+
95
+ position: absolute;
96
+ bottom: 0;
97
+ }
98
+ }
@@ -52,6 +52,10 @@
52
52
 
53
53
  /* M */
54
54
 
55
+ .mini-inputs {
56
+ background: rgba(255,255,255, 0.25);
57
+ }
58
+
55
59
  .modal-absolute {
56
60
  border: 1px solid green;
57
61
  border-radius: 5px;
@@ -42,6 +42,8 @@ class Iro::AlertsController < Iro::ApplicationController
42
42
  private
43
43
 
44
44
  def set_lists
45
+ super
46
+
45
47
  # @profiles_list = Wco::Profile.list
46
48
  @stocks_list = Iro::Stock.list
47
49
  puts! @stocks_list, '@stocks_list'
@@ -3,8 +3,21 @@
3
3
  class Iro::ApplicationController < Wco::ApplicationController
4
4
  layout 'iro/application'
5
5
 
6
+ before_action :set_lists
7
+
6
8
  def home
7
9
  authorize! :home, Iro
8
10
  end
9
11
 
12
+ ##
13
+ ## private
14
+ ##
15
+ private
16
+
17
+ def set_lists
18
+ @purses = Iro::Purse.all
19
+ @strategies = Iro::Strategy.all
20
+ end
21
+
22
+
10
23
  end
@@ -3,14 +3,28 @@ class Iro::PositionsController < Iro::ApplicationController
3
3
  before_action :set_lists
4
4
 
5
5
  def new
6
- @position = Iro::Position.new purse_id: params[:purse_id]
6
+ @position = Iro::Position.new
7
7
  authorize! :new, @posision
8
+
9
+ if params[:id]
10
+ old = Iro::Position.find params[:id]
11
+ old = old.attributes
12
+ old.delete :_id
13
+ puts! old, 'old'
14
+ @position = Iro::Position.new old
15
+ end
16
+ if params[:purse_id]
17
+ @position.purse_id = params[:purse_id]
18
+ end
19
+
8
20
  end
9
21
 
10
22
  def create
11
23
  @position = Iro::Position.new params[:position].permit!
12
24
  authorize! :create, @position
13
25
 
26
+ @position.sync
27
+
14
28
  if @position.save
15
29
  flash_notice @position
16
30
  redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
@@ -33,38 +47,195 @@ class Iro::PositionsController < Iro::ApplicationController
33
47
  authorize! :edit, @position
34
48
  end
35
49
 
50
+ def propose
51
+ @strategy = Iro::Strategy.find params[:strategy_id]
52
+ authorize! :show, @strategy
53
+
54
+ @purse = Iro::Purse.find params[:purse_id]
55
+
56
+ ## short debit put spread
57
+ outs = Tda::Option.get_quotes({
58
+ contractType: 'PUT',
59
+ expirationDate: '2024-03-28',
60
+ ticker: @strategy.stock.ticker,
61
+ })
62
+ outs = outs.select do |out|
63
+ out[:bidSize]+out[:askSize] > 0
64
+ end
65
+ outs = outs.select do |out|
66
+ out[:strikePrice] > @strategy.buffer_above_water + @strategy.stock.last
67
+ end
68
+ outs = outs.select do |out|
69
+ out[:strikePrice] > @strategy.next_inner_strike
70
+ end
71
+ outs = outs.select do |out|
72
+ out[:delta] < @strategy.next_inner_delta
73
+ end
74
+
75
+ inner = outs[0]
76
+ outs = outs.select do |out|
77
+ out[:strikePrice] >= inner[:strikePrice] + @strategy.next_spread_amount
78
+ end
79
+ outer = outs[0]
80
+
81
+ if inner && outer
82
+ next_position = Iro::Position.new({
83
+ status: 'proposed',
84
+ stock: @strategy.stock,
85
+ inner_strike: inner[:strikePrice],
86
+ outer_strike: outer[:strikePrice],
87
+ begin_outer_price: outer[:last],
88
+ begin_outer_delta: outer[:delta],
89
+ begin_inner_price: inner[:last],
90
+ begin_inner_delta: inner[:delta],
91
+ begin_on: Time.now.to_date,
92
+ expires_on: '2024-03-28',
93
+ purse: @purse,
94
+ strategy: @strategy,
95
+ quantity: 1,
96
+ })
97
+ next_position.sync
98
+ next_position.save
99
+ else
100
+ flash_alert 'cannot propose a new one'
101
+ end
102
+ redirect_to request.referrer
103
+ end
104
+
36
105
  def refresh
37
106
  @position = pos = Iro::Position.find params[:id]
38
107
  authorize! :refresh, @position
39
108
 
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
- })
109
+ @position.sync
110
+ @position.calc_rollp
111
+
52
112
  redirect_to request.referrer || purse_path( @position.purse )
53
113
  end
54
114
 
55
- def roll
115
+ def prepare
56
116
  @position = Iro::Position.find params[:id]
57
117
  authorize! :roll, @position
58
118
 
59
- stock = @position.stock
119
+ @prev = @position
120
+ @purse = @position.purse
121
+ @stock = @position.stock
122
+ @n_dollars = 100
123
+
124
+ ## holiday schedule
125
+ @next_expires_on = @prev.expires_on.to_datetime.next_occurring(:monday).next_occurring(:friday)
126
+ if !@next_expires_on.workday?
127
+ @next_expires_on = Time.previous_business_day( @next_expires_on )
128
+ end
129
+
130
+ ## dealing with too many strikes in the chain
131
+ while true
132
+ @nn = ( @position.purse.n_next_positions/2 ).ceil
133
+ upper = Tda::Option.get_quote({
134
+ contractType: 'CALL',
135
+ strike: @prev.inner_strike + @nn*@stock.options_price_increment,
136
+ expirationDate: @next_expires_on,
137
+ ticker: @stock.ticker,
138
+ })
139
+ if !upper.symbol
140
+ puts! 'too high'
141
+ flash_alert 'too high'
142
+ @purse.n_next_positions = @purse.n_next_positions - 1
143
+ @purse.n_next_positions = 1 if @purse.n_next_positions < 1
144
+ @purse.save!
145
+ next
146
+ end
147
+ lower = Tda::Option.get_quote({
148
+ contractType: 'CALL',
149
+ strike: @prev.inner_strike - @nn*@stock.options_price_increment,
150
+ expirationDate: @next_expires_on,
151
+ ticker: @stock.ticker,
152
+ })
153
+ if !lower.symbol
154
+ puts! 'too low'
155
+ flash_alert 'too low'
156
+ @purse.n_next_positions = @purse.n_next_positions - 1
157
+ @purse.n_next_positions = 1 if @purse.n_next_positions < 1
158
+ @purse.save!
159
+ next
160
+ end
161
+ break
162
+ end
60
163
 
61
- @positions = [
62
- Iro::Position.new({ stock: stock, begin_inner_price: 5.21, inner_strike: 91, expires_on: '2024-04-05', gain_loss_amount: -1.25 }),
63
- Iro::Position.new({ stock: stock, begin_inner_price: 5.77, inner_strike: 90, expires_on: '2024-04-05', gain_loss_amount: -0.7 }),
64
- Iro::Position.new({ stock: stock, begin_inner_price: 6.4, inner_strike: 89, expires_on: '2024-04-05', gain_loss_amount: -0.03 }),
65
- Iro::Position.new({ stock: stock, begin_inner_price: 6.85, inner_strike: 88, expires_on: '2024-04-05', gain_loss_amount: 0.6 }),
66
- Iro::Position.new({ stock: stock, begin_inner_price: 7.07, inner_strike: 87, expires_on: '2024-04-05', gain_loss_amount: 1.22 }),
67
- ]
164
+ self.send("_prepare_#{@position.strategy.kind}")
165
+ end
166
+
167
+ def _prepare_covered_call
168
+ @positions = []
169
+ (-@nn..@nn).each do |idx|
170
+ next_ = Iro::Position.new({
171
+ stock: @stock,
172
+ inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
173
+ expires_on: @next_expires_on,
174
+ purse: @position.purse,
175
+ strategy: @position.strategy,
176
+ quantity: @position.quantity,
177
+ })
178
+ next_.sync
179
+ next_.begin_inner_price = next_.end_inner_price
180
+ next_.begin_inner_delta = next_.end_inner_delta
181
+ next_.next_gain_loss_amount = next_.begin_inner_price - @prev.end_inner_price
182
+ puts! next_, 'next_'
183
+ puts! next_.next_gain_loss_amount, 'amount'
184
+ @positions.push next_
185
+ end
186
+ end
187
+
188
+ def _prepare_long_debit_call_spread
189
+ @positions = []
190
+ (-@nn..@nn).each do |idx|
191
+ next_ = Iro::Position.new({
192
+ stock: @stock,
193
+ inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
194
+ outer_strike: @prev.outer_strike - idx*@stock.options_price_increment,
195
+ expires_on: @next_expires_on,
196
+ purse: @position.purse,
197
+ strategy: @position.strategy,
198
+ quantity: @position.quantity,
199
+ })
200
+ next_.sync
201
+ next_.begin_inner_price = next_.end_inner_price
202
+ next_.begin_inner_delta = next_.end_inner_delta
203
+
204
+ next_.begin_outer_price = next_.end_outer_price
205
+ next_.begin_outer_delta = next_.end_outer_delta
206
+ next_.next_gain_loss_amount = @prev.end_outer_price - @prev.end_inner_price
207
+ next_.next_gain_loss_amount += next_.begin_inner_price - next_.begin_outer_price
208
+ puts! next_, 'next_'
209
+ puts! next_.next_gain_loss_amount, 'next_gain_loss_amount'
210
+ @positions.push next_
211
+ end
212
+ @positions = @positions.reverse
213
+ end
214
+
215
+ def _prepare_short_debit_put_spread
216
+ @positions = []
217
+ (-@nn..@nn).each do |idx|
218
+ next_ = Iro::Position.new({
219
+ stock: @stock,
220
+ inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
221
+ outer_strike: @prev.outer_strike - idx*@stock.options_price_increment,
222
+ expires_on: @next_expires_on,
223
+ purse: @position.purse,
224
+ strategy: @position.strategy,
225
+ quantity: @position.quantity,
226
+ })
227
+ next_.sync
228
+ next_.begin_inner_price = next_.end_inner_price
229
+ next_.begin_inner_delta = next_.end_inner_delta
230
+
231
+ next_.begin_outer_price = next_.end_outer_price
232
+ next_.begin_outer_delta = next_.end_outer_delta
233
+ next_.next_gain_loss_amount = @prev.end_outer_price - @prev.end_inner_price
234
+ next_.next_gain_loss_amount += next_.begin_inner_price - next_.begin_outer_price
235
+ puts! next_, 'next_'
236
+ puts! next_.next_gain_loss_amount, 'next_gain_loss_amount'
237
+ @positions.push next_
238
+ end
68
239
  end
69
240
 
70
241
  def update
@@ -86,8 +257,11 @@ class Iro::PositionsController < Iro::ApplicationController
86
257
  private
87
258
 
88
259
  def set_lists
260
+ super
261
+
262
+ @purses_list = Iro::Purse.list
89
263
  @strategies_list = Iro::Strategy.list(params[:long_or_short])
90
- @stocks_list = Iro::Stock.list
264
+ @stocks_list = Iro::Stock.list
91
265
  end
92
266
 
93
267
  end
@@ -7,10 +7,11 @@ class Iro::PursesController < Iro::ApplicationController
7
7
  @purse = Iro::Purse.new params[:purse].permit!
8
8
  authorize! :create, @purse
9
9
  if @purse.save
10
- redirect_to action: :index, notice: 'Purse was successfully created.'
10
+ ;
11
11
  else
12
- render :new
12
+ flash_alert @purse
13
13
  end
14
+ redirect_to action: :index
14
15
  end
15
16
 
16
17
  def destroy
@@ -34,13 +35,15 @@ class Iro::PursesController < Iro::ApplicationController
34
35
  @purse = Iro::Purse.find(params[:id])
35
36
  authorize! :show, @purse
36
37
 
37
- @positions = @purse.positions.includes( :strategy
38
- ).order({ expires_on: :desc })
38
+ @positions = @purse.positions.where( status: 'active' ).includes( :strategy
39
+ ).order({ expires_on: :desc, stock: :desc })
39
40
 
40
41
  @unit = @purse.unit # 12 ## pixels per dollar
41
42
  @height = @purse.height # 100 ## pixels
42
43
  @n_dollars = 100 ## dollars to each side of origin
43
44
 
45
+ calc_summary
46
+
44
47
  render params[:template]
45
48
  end
46
49
 
@@ -49,7 +52,7 @@ class Iro::PursesController < Iro::ApplicationController
49
52
  authorize! :update, @purse
50
53
  if @purse.update params[:purse].permit!
51
54
  flash[:notice] = 'ok'
52
- redirect_to purse_path(@purse)
55
+ redirect_to request.referrer # purse_path(@purse)
53
56
  else
54
57
  flash_alert @purse
55
58
  render :edit
@@ -61,9 +64,60 @@ class Iro::PursesController < Iro::ApplicationController
61
64
  ##
62
65
  private
63
66
 
67
+ ## for one stock only!
68
+ def calc_summary
69
+ @max_loss_long = 0
70
+ @max_loss_short = 0
71
+
72
+ @max_gain_long = 0
73
+ @max_gain_short = 0
74
+
75
+ @gain_long = 0
76
+ @gain_short = 0
77
+
78
+ @begin_delta_long = 0
79
+ @begin_delta_short = 0
80
+ @end_delta_long = 0
81
+ @end_delta_short = 0
82
+
83
+ @positions.each do |pos|
84
+ if Iro::Strategy::LONG == pos.strategy.long_or_short
85
+ @max_loss_long += pos.max_loss * pos.q * 100
86
+ @max_gain_long += pos.max_gain * pos.q * 100
87
+ @gain_long += pos.net_amount * pos.q * 100
88
+
89
+ @begin_delta_long += pos.begin_delta * pos.q
90
+ @end_delta_long += pos.end_delta * pos.q
91
+ end
92
+ if Iro::Strategy::SHORT == pos.strategy.long_or_short
93
+ @max_loss_short += pos.max_loss * pos.q * 100
94
+ @max_gain_short += pos.max_gain * pos.q * 100
95
+ @gain_short += pos.net_amount * pos.q * 100
96
+
97
+ @begin_delta_short += pos.begin_delta * pos.q
98
+ @end_delta_short += pos.end_delta * pos.q
99
+ end
100
+ end
101
+ # @max_loss_long *= -1
102
+ # @max_loss_short *= -1
103
+ @begin_delta_short *= -1
104
+ @end_delta_short *= -1
105
+ if @gain_long < 0
106
+ @loss_long = @gain_long
107
+ @gain_long = nil
108
+ end
109
+ if @gain_short < 0
110
+ @loss_short = @gain_short
111
+ @gain_short = nil
112
+ end
113
+ end
114
+
64
115
  def set_lists
116
+ super
117
+
65
118
  # @profiles_list = Wco::Profile.list
66
- @stocks_list = [[nil,nil]] + Iro::Stock.active.map { |s| [ s.ticker, s.ticker ] }
119
+ # @tickers_list = [[nil,nil]] + Iro::Stock.active.map { |s| [ s.ticker, s.ticker ] }
120
+ @stocks_list = Iro::Stock.list
67
121
 
68
122
  end
69
123
 
@@ -2,32 +2,48 @@
2
2
  class Iro::StocksController < Iro::ApplicationController
3
3
  before_action :set_stock, only: [:show, :edit, :update, :destroy]
4
4
 
5
+ def create
6
+ @stock = Iro::Stock.new(stock_params)
7
+ authorize! :create, @stock
8
+
9
+ if @stock.save
10
+ flash_notice @stock
11
+ else
12
+ flash_alert @stock
13
+ end
14
+ redirect_to action: :index
15
+ end
16
+
17
+ def destroy
18
+ @stock.destroy
19
+ redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
20
+ end
21
+
22
+ def edit
23
+ end
24
+
5
25
  def index
6
26
  @stocks = Iro::Stock.all
7
27
  authorize! :index, Iro::Stock
8
28
  end
9
29
 
10
- def show
11
- end
12
-
13
30
  def new
14
31
  @stock = Iro::Stock.new
15
32
  authorize! :new, @stock
16
33
  end
17
34
 
18
- def edit
35
+ def refresh
36
+ authorize! :refresh, Iro::Stock
37
+ tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
38
+ outs = Tda::Stock.get_quotes tickers
39
+ outs.map do |out|
40
+ Iro::Stock.where( ticker: out[:symbol] ).update( last: out[:last] )
41
+ end
42
+ flash_notice 'ok'
43
+ redirect_to request.referrer
19
44
  end
20
45
 
21
- def create
22
- @stock = Iro::Stock.new(stock_params)
23
- authorize! :create, @stock
24
-
25
- if @stock.save
26
- flash_notice @stock
27
- else
28
- flash_alert @stock
29
- end
30
- redirect_to action: :index
46
+ def show
31
47
  end
32
48
 
33
49
  def update
@@ -41,10 +57,6 @@ class Iro::StocksController < Iro::ApplicationController
41
57
  redirect_to request.referrer
42
58
  end
43
59
 
44
- def destroy
45
- @stock.destroy
46
- redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
47
- end
48
60
 
49
61
  ##
50
62
  ## private
@@ -32,6 +32,7 @@ class Iro::StrategiesController < Iro::ApplicationController
32
32
  def index
33
33
  authorize! :index, Iro::Strategy
34
34
  @strategies = Iro::Strategy.all
35
+
35
36
  # render '_table'
36
37
  end
37
38
 
@@ -40,6 +41,13 @@ class Iro::StrategiesController < Iro::ApplicationController
40
41
  authorize! :new, @posision
41
42
  end
42
43
 
44
+ def show
45
+ @strategy = Iro::Strategy.find params[:id]
46
+ authorize! :show, @strategy
47
+ end
48
+
49
+
50
+
43
51
  def update
44
52
  @strategy = Iro::Strategy.find params[:id]
45
53
  authorize! :update, @strategy
@@ -59,8 +67,11 @@ class Iro::StrategiesController < Iro::ApplicationController
59
67
  private
60
68
 
61
69
  def set_lists
70
+ super
71
+
72
+ @purses_list = Iro::Purse.list
62
73
  @strategies_list = Iro::Strategy.list
63
- @tickers_list = Iro::Stock.list
74
+ @stocks_list = Iro::Stock.list
64
75
  end
65
76
 
66
77
  end
@@ -2,6 +2,7 @@
2
2
  class Iro::Alert
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'iro_alerts'
6
7
 
7
8
  # SLEEP_TIME_SECONDS = Rails.env.production? ? 60 : 15