iron_warbler 2.0.7.24 → 2.0.7.26

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/iron_warbler/Card.scss +6 -0
  3. data/app/assets/stylesheets/iron_warbler/positions.scss +1 -1
  4. data/app/assets/stylesheets/iron_warbler/positions_gameui.scss +8 -0
  5. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +2 -4
  6. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
  7. data/app/controllers/iro/application_controller.rb +6 -0
  8. data/app/controllers/iro/positions_controller.rb +186 -137
  9. data/app/controllers/iro/purses_controller.rb +3 -1
  10. data/app/controllers/iro/stocks_controller.rb +2 -2
  11. data/app/models/iro/option.rb +41 -148
  12. data/app/models/iro/option_black_scholes.rb +149 -0
  13. data/app/models/iro/position.rb +156 -205
  14. data/app/models/iro/purse.rb +34 -4
  15. data/app/models/iro/strategy.rb +49 -47
  16. data/app/views/iro/_main_header.haml +4 -2
  17. data/app/views/iro/options/_show_mini.haml +8 -0
  18. data/app/views/iro/positions/_form.haml +8 -3
  19. data/app/views/iro/positions/_formpart_4data.haml +41 -38
  20. data/app/views/iro/positions/_gameui_covered_call.haml +1 -1
  21. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +5 -5
  22. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
  23. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
  24. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
  25. data/app/views/iro/positions/_header.haml +2 -0
  26. data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
  27. data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +6 -5
  28. data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
  29. data/app/views/iro/positions/_table.haml +25 -26
  30. data/app/views/iro/positions/prepare.haml +6 -4
  31. data/app/views/iro/positions/prepare2.haml +22 -0
  32. data/app/views/iro/purses/_form_extra_fields.haml +8 -4
  33. data/app/views/iro/purses/_header.haml +19 -5
  34. data/app/views/iro/purses/_summary.haml +69 -62
  35. data/app/views/iro/purses/show.haml +1 -1
  36. data/app/views/iro/strategies/_form.haml +26 -19
  37. data/app/views/iro/strategies/_show.haml +6 -4
  38. data/config/routes.rb +10 -7
  39. metadata +8 -2
  40. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b73ac7c5b7ca0d29fe20cd0db0dcdca4713a710790bff2cffe8c30c3a18d2d2
4
- data.tar.gz: daef47e2b8841f0253e55d19a8c8703c7aff086c53711b52db3dfdb470a97a78
3
+ metadata.gz: 4afc65383198cc16143683cc82db6ee65604f14a8d13d4d7bc262210ceb14940
4
+ data.tar.gz: 04c7d9a3585dd1036c8f227a1cbbe38fbc6e7d71f68977f3183ac07bdbaba3cf
5
5
  SHA512:
6
- metadata.gz: e59a49397b934c8537abe40eb23eba846aa770956e02168722b2eb5fd6a1e19581388dc43d3ecb6e211e90cffec5cf8b02ef5eaa6efdcb1f40b4599c4125c8e8
7
- data.tar.gz: 8f10a4503e57e02d17ca0dd7a310fc73489dfd22fb23e23f16a79de72f3a589790c09e9facbfb2441daf3fcef2b93456bcac12ce7a767c35ce7e29c2ccffc48f
6
+ metadata.gz: a905e844e0542aa1f7500c1c1bc25a234f2698bc8bfb1e75d83fb7ab2ba24dcc28ed261a876f1add4d9dec80decb32cb84ed1694ac3b8e3657be48f8a36b86bc
7
+ data.tar.gz: d9478f1d454dbcbee3b6fc703233f7d72049ac128f1ad2e550e38286483ccc51a863e8ace598511c2c28a6ce8a26240215d97ff2d524e5a3e03dcbdc5fb1eb40
@@ -0,0 +1,6 @@
1
+
2
+ .Card {
3
+ background: white;
4
+ }
5
+
6
+
@@ -21,7 +21,7 @@
21
21
 
22
22
  > * {
23
23
  transform-origin: 0 0;
24
- rotate: -40deg;
24
+ // rotate: -40deg;
25
25
 
26
26
  padding: .4em 0;
27
27
  width: 120px;
@@ -9,3 +9,11 @@
9
9
  }
10
10
  }
11
11
 
12
+ .select {
13
+ position: absolute;
14
+ z-index: 5;
15
+
16
+ right: -100px;
17
+ text-align: left;
18
+ width: calc(100px - 1em);
19
+ }
@@ -52,7 +52,7 @@
52
52
  .Position {
53
53
  position: absolute;
54
54
  width: 100%;
55
- height: 90%;
55
+ height: 100%;
56
56
 
57
57
  left: 0;
58
58
  top: 0;
@@ -64,8 +64,6 @@
64
64
  background: rgba(255,153,51, 0.5);
65
65
  position: absolute;
66
66
 
67
- /* HEREHERE: either left, or right 0, this orange strip flips. */
68
- // left: 0;
69
67
  right: 0;
70
68
 
71
69
  width: 10000px;
@@ -76,7 +74,7 @@
76
74
  .Breakeven {
77
75
  position: absolute;
78
76
  right: 0;
79
- bottom: -10%;
77
+ bottom: 0;
80
78
  border: 2px dotted green;
81
79
  background: rgba(0,255,0, 0.5);
82
80
  height: 0.5em;
@@ -40,32 +40,38 @@
40
40
  .summary-amount {
41
41
  position: relative;
42
42
  width: 100px;
43
+ margin-right: 2em;
43
44
 
44
45
  .net-gl {
45
46
  width: 100%;
46
47
  background: rgba(0,0,0, 0.5);
47
48
  }
48
- }
49
- .summary-delta {
50
- position: relative;
51
- margin-right: 1em;
52
- width: 1em;
53
49
 
54
- > div {
55
- border: 1px dotted yellow;
56
- }
57
- .begin {
58
- width: 1em;
50
+ .delta {
51
+ position: absolute;
52
+ left: 100px;
53
+ height: 100%;
59
54
 
60
- background: black;
61
- }
62
- .end {
63
- width: .5em;
64
- left: .25em;
55
+ > div {
56
+ border: 1px dotted yellow;
57
+ width: 0.5em;
58
+ }
59
+ .begin {
60
+ width: 1em;
65
61
 
66
- background: rgba(255,0,0, 0.5);
62
+ background: black;
63
+ }
64
+ .end {
65
+ width: .5em;
66
+ left: .25em;
67
+
68
+ background: rgba(255,0,0, 0.5);
69
+ }
67
70
  }
71
+
68
72
  }
73
+
74
+
69
75
  .loss {
70
76
  }
71
77
  .gain {
@@ -73,12 +79,18 @@
73
79
  .max-gl {
74
80
  position: absolute;
75
81
  width: 100%;
82
+
83
+ label {
84
+ position: absolute;
85
+ }
86
+
87
+
76
88
  }
77
89
  .max-gl.long {
78
- background: rgba(255,0,0, 0.5);
79
90
  }
80
- .max-gl-short {
81
- background: rgba(255,153,0, 0.5);
91
+ .max-gl.short {
92
+ display: flex;
93
+ flex-direction: column-reverse;
82
94
  }
83
95
  .long {
84
96
  position: absolute;
@@ -1,4 +1,9 @@
1
1
 
2
+ Pu ||= Iro::Purse
3
+ Str ||= Iro::Strategy
4
+ Po ||= Iro::Position
5
+ O ||= Iro::Option
6
+ Sto ||= Iro::Stock
2
7
 
3
8
  class Iro::ApplicationController < Wco::ApplicationController
4
9
  layout 'iro/application'
@@ -17,6 +22,7 @@ class Iro::ApplicationController < Wco::ApplicationController
17
22
  def set_lists
18
23
  @purses = Iro::Purse.all
19
24
  @strategies = Iro::Strategy.all
25
+ @strategies_list = Iro::Strategy.list
20
26
  end
21
27
 
22
28
 
@@ -2,35 +2,23 @@
2
2
  class Iro::PositionsController < Iro::ApplicationController
3
3
  before_action :set_lists
4
4
 
5
- def new
6
- @position = Iro::Position.new
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
-
20
- end
21
-
22
5
  def create
23
- @position = Iro::Position.new params[:position].permit!
6
+ pos = @position = Iro::Position.new pos_params
7
+ o_attrs = {
8
+ expires_on: pos.expires_on,
9
+ put_call: pos.put_call,
10
+ stock_id: pos.stock_id,
11
+ }
12
+ pos.inner = Iro::Option.new params[:inner].permit!.merge( o_attrs )
13
+ pos.outer = Iro::Option.new params[:outer].permit!.merge( o_attrs )
24
14
  authorize! :create, @position
25
15
 
26
- @position.sync
27
-
28
16
  if @position.save
29
17
  flash_notice @position
30
18
  redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
31
19
  else
32
20
  flash_alert @position
33
- redirect_to request.referrer
21
+ render action: :new # redirect_to request.referrer
34
22
  end
35
23
  end
36
24
 
@@ -47,69 +35,23 @@ class Iro::PositionsController < Iro::ApplicationController
47
35
  authorize! :edit, @position
48
36
  end
49
37
 
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
38
+ def new
39
+ strategy = Iro::Strategy.find params[:position][:strategy_id]
40
+ @position = Iro::Position.new( params[:position].permit!.merge({
41
+ status: :active,
42
+ inner: Iro::Option.new,
43
+ outer: Iro::Option.new,
44
+ stock_id: strategy.stock_id,
45
+ }) )
46
+ authorize! :new, @posision
74
47
 
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'
48
+ if params[:id]
49
+ old = Iro::Position.find params[:id]
50
+ old = old.attributes
51
+ old.delete :_id
52
+ puts! old, 'old'
53
+ @position = Iro::Position.new old
101
54
  end
102
- redirect_to request.referrer
103
- end
104
-
105
- def refresh
106
- @position = pos = Iro::Position.find params[:id]
107
- authorize! :refresh, @position
108
-
109
- @position.sync
110
- @position.calc_rollp
111
-
112
- redirect_to request.referrer || purse_path( @position.purse )
113
55
  end
114
56
 
115
57
  def prepare
@@ -121,19 +63,13 @@ class Iro::PositionsController < Iro::ApplicationController
121
63
  @stock = @position.stock
122
64
  @n_dollars = 100
123
65
 
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
66
  ## dealing with too many strikes in the chain
131
67
  while true
132
68
  @nn = ( @position.purse.n_next_positions/2 ).ceil
133
69
  upper = Tda::Option.get_quote({
134
- contractType: 'CALL',
135
- strike: @prev.inner_strike + @nn*@stock.options_price_increment,
136
- expirationDate: @next_expires_on,
70
+ contractType: @position.put_call,
71
+ strike: @prev.inner.strike + @nn*@stock.options_price_increment,
72
+ expirationDate: @prev.next_expires_on,
137
73
  ticker: @stock.ticker,
138
74
  })
139
75
  if !upper.symbol
@@ -145,9 +81,9 @@ class Iro::PositionsController < Iro::ApplicationController
145
81
  next
146
82
  end
147
83
  lower = Tda::Option.get_quote({
148
- contractType: 'CALL',
149
- strike: @prev.inner_strike - @nn*@stock.options_price_increment,
150
- expirationDate: @next_expires_on,
84
+ contractType: @position.put_call,
85
+ strike: @prev.inner.strike - @nn*@stock.options_price_increment,
86
+ expirationDate: @prev.next_expires_on,
151
87
  ticker: @stock.ticker,
152
88
  })
153
89
  if !lower.symbol
@@ -164,13 +100,91 @@ class Iro::PositionsController < Iro::ApplicationController
164
100
  self.send("_prepare_#{@position.strategy.kind}")
165
101
  end
166
102
 
103
+ ## long debit call spread
104
+ def prepare2
105
+ @position = Iro::Position.find params[:id]
106
+ authorize! :roll, @position
107
+
108
+ pos = @position
109
+ stock = @position.stock
110
+
111
+ @query = {
112
+ orderType: price > 0 ? "NET_CREDIT" : "NET_DEBIT",
113
+ session: "NORMAL",
114
+ price: price,
115
+ duration: "DAY",
116
+ orderStrategyType: "SINGLE",
117
+ orderLegCollection: [
118
+ ## close
119
+ {
120
+ instruction: "BUY_TO_CLOSE",
121
+ quantity: pos.q,
122
+ instrument: {
123
+ symbol: pos.autoprev.inner.symbol,
124
+ assetType: "OPTION",
125
+ },
126
+ },
127
+ {
128
+ instruction: "SELL_TO_CLOSE",
129
+ quantity: pos.q,
130
+ instrument: {
131
+ symbol: pos.autoprev.outer.symbol,
132
+ assetType: "OPTION",
133
+ },
134
+ },
135
+
136
+ ## open
137
+ {
138
+ instruction: "BUY_TO_OPEN",
139
+ quantity: pos.q,
140
+ instrument: {
141
+ symbol: pos.outer.symbol,
142
+ assetType: "OPTION",
143
+ },
144
+ },
145
+ {
146
+ instruction: "SELL_TO_OPEN",
147
+ quantity: pos.q,
148
+ instrument: {
149
+ symbol: pos.inner.symbol,
150
+ assetType: "OPTION",
151
+ },
152
+ },
153
+ ],
154
+ }
155
+ puts! @query, '@query'
156
+ end
157
+
158
+ ## long debit call spread
159
+ def prepare3
160
+ pos = @position = Iro::Position.find params[:id]
161
+ authorize! :place_order, @position
162
+
163
+ # out = Tda::Option.roll_long_debit_call_spread( position )
164
+
165
+ ## @TODO: it's pending here, the order has not been placed.
166
+
167
+ flags = []
168
+
169
+ flags.push pos.prev.update({ status: Iro::Position::STATUS_CLOSED })
170
+ flags.push pos.update({ status: Iro::Position::STATUS_ACTIVE })
171
+ flags.push pos.purse.update({
172
+ available_amount: pos.purse.available_amount + price + pos.q*100,
173
+ })
174
+
175
+ flash_notice flags
176
+ redirect_to controller: :purses, action: :show, template: :gameui, id: pos.purse_id
177
+ end
178
+
179
+
180
+
167
181
  def _prepare_covered_call
168
182
  @positions = []
169
183
  (-@nn..@nn).each do |idx|
170
184
  next_ = Iro::Position.new({
171
185
  stock: @stock,
172
- inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
173
- expires_on: @next_expires_on,
186
+ inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
187
+ expires_on: @prev.next_expires_on,
174
188
  purse: @position.purse,
175
189
  strategy: @position.strategy,
176
190
  quantity: @position.quantity,
@@ -179,8 +193,6 @@ class Iro::PositionsController < Iro::ApplicationController
179
193
  next_.begin_inner_price = next_.end_inner_price
180
194
  next_.begin_inner_delta = next_.end_inner_delta
181
195
  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
196
  @positions.push next_
185
197
  end
186
198
  end
@@ -188,61 +200,83 @@ class Iro::PositionsController < Iro::ApplicationController
188
200
  def _prepare_long_debit_call_spread
189
201
  @positions = []
190
202
  (-@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,
203
+ next_ = Iro::Position.find_or_create_by({
204
+ expires_on: @prev.next_expires_on,
205
+ inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
206
+ outer_strike: @prev.outer.strike - idx*@stock.options_price_increment,
207
+ prev_id: @prev.id,
196
208
  purse: @position.purse,
197
- strategy: @position.strategy,
198
209
  quantity: @position.quantity,
210
+ status: 'prepare',
211
+ stock: @stock,
212
+ strategy: @position.strategy,
213
+ })
214
+ pos = next_
215
+ next_.inner ||= Iro::Option.new({
216
+ # begin_price: pos[:begin_inner_price],
217
+ # begin_delta: pos[:begin_inner_delta],
218
+ expires_on: pos[:expires_on],
219
+ inner: pos,
220
+ put_call: pos.put_call,
221
+ stock_id: pos[:stock_id],
222
+ strike: pos[:inner_strike],
199
223
  })
224
+ next_.outer ||= Iro::Option.new({
225
+ # begin_price: pos[:begin_inner_price],
226
+ # begin_delta: pos[:begin_inner_delta],
227
+ expires_on: pos[:expires_on],
228
+ outer: pos,
229
+ put_call: pos.put_call,
230
+ stock_id: pos[:stock_id],
231
+ strike: pos[:outer_strike],
232
+ })
233
+
200
234
  next_.sync
201
- next_.begin_inner_price = next_.end_inner_price
202
- next_.begin_inner_delta = next_.end_inner_delta
235
+ next_.inner.begin_price = next_.inner.end_price
236
+ next_.inner.begin_delta = next_.inner.end_delta
237
+
238
+ next_.outer.begin_price = next_.outer.end_price
239
+ next_.outer.begin_delta = next_.outer.end_delta
203
240
 
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'
241
+ next_.next_gain_loss_amount = @prev.outer.end_price - @prev.inner.end_price
242
+ next_.next_gain_loss_amount += next_.inner.begin_price - next_.outer.begin_price
243
+ next_.save
210
244
  @positions.push next_
211
245
  end
212
246
  @positions = @positions.reverse
213
247
  end
248
+ alias_method :_prepare_short_debit_put_spread, :_prepare_long_debit_call_spread
214
249
 
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
250
 
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_
251
+ def sync
252
+ @position = pos = Iro::Position.find params[:id]
253
+ authorize! :refresh, @position
254
+
255
+ @position.sync
256
+ @position.calc_rollp
257
+ if true # @position.rollp > 0.5
258
+ @position.calc_nxt
238
259
  end
260
+
261
+ redirect_to request.referrer || purse_path( @position.purse )
239
262
  end
240
263
 
264
+ ##
265
+ ## only updates some attributes
266
+ ##
241
267
  def update
242
- @position = Iro::Position.find params[:id]
268
+ pos = @position = Iro::Position.find params[:id]
243
269
  authorize! :update, @position
244
270
 
245
- if @position.update params[:position].permit!
271
+ if @position.update pos_params
272
+ o_attrs = {
273
+ expires_on: pos.expires_on,
274
+ put_call: pos.put_call,
275
+ stock_id: pos.stock_id,
276
+ }
277
+ pos.inner.update params[:inner].permit!.merge( o_attrs )
278
+ pos.outer.update params[:outer].permit!.merge( o_attrs )
279
+
246
280
  flash_notice @position
247
281
  redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
248
282
  else
@@ -251,14 +285,29 @@ class Iro::PositionsController < Iro::ApplicationController
251
285
  end
252
286
  end
253
287
 
288
+
289
+
254
290
  ##
255
291
  ## private
256
292
  ##
257
293
  private
258
294
 
295
+ def pos_params
296
+ params[:position].permit( :purse_id, :status, :stock_id,
297
+ :strategy_id, :expires_on, :quantity, :begin_on,
298
+ :long_or_short,
299
+ )
300
+ end
301
+
302
+ def price
303
+ pos = @position
304
+ out = pos.autoprev.outer.end_price - pos.autoprev.inner.end_price + pos.inner.begin_price - pos.outer.begin_price
305
+ return out
306
+ end
307
+
308
+
259
309
  def set_lists
260
310
  super
261
-
262
311
  @purses_list = Iro::Purse.list
263
312
  @strategies_list = Iro::Strategy.list(params[:long_or_short])
264
313
  @stocks_list = Iro::Stock.list
@@ -35,8 +35,10 @@ class Iro::PursesController < Iro::ApplicationController
35
35
  @purse = Iro::Purse.find(params[:id])
36
36
  authorize! :show, @purse
37
37
 
38
+
38
39
  @positions = @purse.positions.where( status: 'active' ).includes( :strategy
39
- ).order({ expires_on: :desc, stock: :desc })
40
+ ).order( expires_on: :asc, ticker: :desc, long_or_short: :asc, inner_strike: :asc )
41
+
40
42
 
41
43
  @unit = @purse.unit # 12 ## pixels per dollar
42
44
  @height = @purse.height # 100 ## pixels
@@ -32,14 +32,14 @@ class Iro::StocksController < Iro::ApplicationController
32
32
  authorize! :new, @stock
33
33
  end
34
34
 
35
- def refresh
35
+ def sync
36
36
  authorize! :refresh, Iro::Stock
37
37
  tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
38
38
  outs = Tda::Stock.get_quotes tickers
39
39
  outs.map do |out|
40
40
  Iro::Stock.where( ticker: out[:symbol] ).update( last: out[:last] )
41
41
  end
42
- flash_notice 'ok'
42
+ flash_notice 'refreshed stocks'
43
43
  redirect_to request.referrer
44
44
  end
45
45