iron_warbler 2.0.7.25 → 2.0.7.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) 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/purses.scss +31 -0
  5. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
  6. data/app/assets/stylesheets/iron_warbler/utils.scss +28 -3
  7. data/app/controllers/iro/api/stocks_controller.rb +7 -4
  8. data/app/controllers/iro/application_controller.rb +6 -0
  9. data/app/controllers/iro/positions_controller.rb +188 -199
  10. data/app/controllers/iro/purses_controller.rb +3 -1
  11. data/app/controllers/iro/stocks_controller.rb +21 -2
  12. data/app/models/iro/datapoint.rb +1 -1
  13. data/app/models/iro/option.rb +50 -150
  14. data/app/models/iro/option_black_scholes.rb +149 -0
  15. data/app/models/iro/position.rb +155 -212
  16. data/app/models/iro/{price_item.rb → priceitem.rb} +5 -1
  17. data/app/models/iro/purse.rb +41 -4
  18. data/app/models/iro/stock.rb +2 -0
  19. data/app/models/iro/strategy.rb +121 -82
  20. data/app/models/tda/option.rb +1 -1
  21. data/app/models/tda/stock.rb +1 -1
  22. data/app/views/iro/_main_header.haml +8 -5
  23. data/app/views/iro/api/stocks/index.json.jbuilder +5 -0
  24. data/app/views/iro/api/stocks/show.json.jbuilder +11 -0
  25. data/app/views/iro/api/stocks/show.json.jbuilder-bk +12 -0
  26. data/app/views/iro/options/_show_mini.haml +8 -0
  27. data/app/views/iro/positions/_form.haml +11 -4
  28. data/app/views/iro/positions/_formpart_4data.haml +41 -38
  29. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +4 -4
  30. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
  31. data/app/views/iro/positions/_gameui_short_credit_call_spread.haml +38 -0
  32. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
  33. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
  34. data/app/views/iro/positions/_header.haml +2 -0
  35. data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
  36. data/app/views/iro/positions/_header_short_credit_call_spread.haml +50 -0
  37. data/app/views/iro/positions/_new.haml +23 -0
  38. data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +2 -3
  39. data/app/views/iro/positions/_prepare_short_credit_call_spread.haml +1 -0
  40. data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
  41. data/app/views/iro/positions/_table.haml +25 -26
  42. data/app/views/iro/positions/prepare.haml +6 -4
  43. data/app/views/iro/positions/prepare2.haml +15 -4
  44. data/app/views/iro/purses/_form_extra_fields.haml +18 -18
  45. data/app/views/iro/purses/_header.haml +12 -7
  46. data/app/views/iro/purses/_summary.haml +69 -62
  47. data/app/views/iro/purses/show.haml +4 -3
  48. data/app/views/iro/stocks/_form.haml +4 -3
  49. data/app/views/iro/stocks/edit.haml +4 -0
  50. data/app/views/iro/stocks/index.haml +21 -6
  51. data/app/views/iro/strategies/_form.haml +36 -26
  52. data/app/views/iro/strategies/_show.haml +7 -5
  53. data/config/routes.rb +7 -4
  54. data/lib/iro/engine.rb +1 -0
  55. data/lib/iron_warbler.rb +0 -2
  56. data/lib/tasks/iro_tasks.rake +2 -2
  57. metadata +17 -4
  58. data/app/views/iro/api/stocks/show.jbuilder +0 -11
  59. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -40
@@ -2,35 +2,24 @@
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
24
7
  authorize! :create, @position
25
8
 
26
- @position.sync
9
+ o_attrs = {
10
+ expires_on: pos.expires_on,
11
+ put_call: pos.put_call, # I need this. _vp_ 2024-04-26
12
+ stock_id: pos.stock_id,
13
+ }
14
+ pos.inner = Iro::Option.new params[:inner].permit!.merge( o_attrs )
15
+ pos.outer = Iro::Option.new params[:outer].permit!.merge( o_attrs )
27
16
 
28
17
  if @position.save
29
18
  flash_notice @position
30
19
  redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
31
20
  else
32
21
  flash_alert @position
33
- redirect_to request.referrer
22
+ render action: :new # redirect_to request.referrer
34
23
  end
35
24
  end
36
25
 
@@ -47,73 +36,75 @@ class Iro::PositionsController < Iro::ApplicationController
47
36
  authorize! :edit, @position
48
37
  end
49
38
 
50
- ## this is auto-driven
51
- def propose
52
- @strategy = Iro::Strategy.find params[:strategy_id]
53
- authorize! :show, @strategy
54
-
55
- @purse = Iro::Purse.find params[:purse_id]
39
+ def new
40
+ strategy = Iro::Strategy.find params[:position][:strategy_id]
41
+ @position = strategy.next_position
42
+ @position ||= Iro::Position.new( params[:position].permit!.merge({
43
+ status: Iro::Position::STATUS_PROPOSED,
44
+ # inner: Iro::Option.new,
45
+ # outer: Iro::Option.new,
46
+ stock_id: strategy.stock_id,
47
+ }) )
48
+ authorize! :new, @posision
56
49
 
57
- ## short debit put spread
58
- outs = Tda::Option.get_quotes({
59
- contractType: 'PUT',
60
- expirationDate: '2024-03-28',
61
- ticker: @strategy.stock.ticker,
62
- })
63
- outs = outs.select do |out|
64
- out[:bidSize]+out[:askSize] > 0
65
- end
66
- outs = outs.select do |out|
67
- out[:strikePrice] > @strategy.buffer_above_water + @strategy.stock.last
68
- end
69
- outs = outs.select do |out|
70
- out[:strikePrice] > @strategy.next_inner_strike
71
- end
72
- outs = outs.select do |out|
73
- out[:delta] < @strategy.next_inner_delta
74
- end
50
+ @position.calc_nxt
75
51
 
76
- inner = outs[0]
77
- outs = outs.select do |out|
78
- out[:strikePrice] >= inner[:strikePrice] + @strategy.next_spread_amount
79
- end
80
- outer = outs[0]
81
-
82
- if inner && outer
83
- next_position = Iro::Position.new({
84
- status: 'proposed',
85
- stock: @strategy.stock,
86
- inner_strike: inner[:strikePrice],
87
- outer_strike: outer[:strikePrice],
88
- begin_outer_price: outer[:last],
89
- begin_outer_delta: outer[:delta],
90
- begin_inner_price: inner[:last],
91
- begin_inner_delta: inner[:delta],
92
- begin_on: Time.now.to_date,
93
- expires_on: '2024-03-28',
94
- purse: @purse,
95
- strategy: @strategy,
96
- quantity: 1,
97
- })
98
- next_position.sync
99
- next_position.save
100
- else
101
- flash_alert 'cannot propose a new one'
102
- end
103
- redirect_to request.referrer
52
+ # if params[:id]
53
+ # old = Iro::Position.find params[:id]
54
+ # old = old.attributes
55
+ # old.delete :_id
56
+ # puts! old, 'old'
57
+ # @position = Iro::Position.new old
58
+ # end
104
59
  end
105
60
 
106
- def refresh
107
- @position = pos = Iro::Position.find params[:id]
108
- authorize! :refresh, @position
61
+ def prepare
62
+ @position = Iro::Position.find params[:id]
63
+ authorize! :roll, @position
109
64
 
110
- @position.sync
111
- @position.calc_rollp
65
+ @prev = @position
66
+ @purse = @position.purse
67
+ @stock = @position.stock
68
+ @n_dollars = 100
112
69
 
113
- redirect_to request.referrer || purse_path( @position.purse )
70
+ ## dealing with too many strikes in the chain
71
+ while true
72
+ @nn = ( @position.purse.n_next_positions/2 ).ceil
73
+ upper = Tda::Option.get_quote({
74
+ contractType: @position.inner.put_call,
75
+ strike: @prev.inner.strike + @nn*@stock.options_price_increment,
76
+ expirationDate: @prev.next_expires_on,
77
+ ticker: @stock.ticker,
78
+ })
79
+ if !upper.symbol
80
+ puts! 'too high'
81
+ flash_alert 'too high'
82
+ @purse.n_next_positions = @purse.n_next_positions - 1
83
+ @purse.n_next_positions = 1 if @purse.n_next_positions < 1
84
+ @purse.save!
85
+ next
86
+ end
87
+ lower = Tda::Option.get_quote({
88
+ contractType: @position.inner.put_call,
89
+ strike: @prev.inner.strike - @nn*@stock.options_price_increment,
90
+ expirationDate: @prev.next_expires_on,
91
+ ticker: @stock.ticker,
92
+ })
93
+ if !lower.symbol
94
+ puts! 'too low'
95
+ flash_alert 'too low'
96
+ @purse.n_next_positions = @purse.n_next_positions - 1
97
+ @purse.n_next_positions = 1 if @purse.n_next_positions < 1
98
+ @purse.save!
99
+ next
100
+ end
101
+ break
102
+ end
103
+
104
+ self.send("_prepare_#{@position.strategy.kind}")
114
105
  end
115
106
 
116
- -## long debit call spread
107
+ ## long debit call spread
117
108
  def prepare2
118
109
  @position = Iro::Position.find params[:id]
119
110
  authorize! :roll, @position
@@ -121,119 +112,83 @@ class Iro::PositionsController < Iro::ApplicationController
121
112
  pos = @position
122
113
  stock = @position.stock
123
114
 
124
- next_outer = @position.outer || Iro::Option.create({
125
- stock: stock,
126
- strike: pos.outer_strike,
127
- expires_on: pos.expires_on,
128
- position: pos,
129
- last: pos.begin_outer_price,
130
- })
131
-
132
- next_inner = @position.inner || Iro::Option.create({
133
- stock: stock,
134
- strike: pos.inner_strike,
135
- expires_on: pos.expires_on,
136
- position: pos,
137
- last: pos.begin_inner_price,
138
- })
139
-
140
- prev_outer = pos.prev.outer
141
- prev_inner = pos.prev.inner
142
-
143
- price = pos.prev.outer.last - pos.prev.inner.last + pos.nxt.inner.last - pos.nxt.outer.last
144
-
145
115
  @query = {
146
- orderType: "NET_DEBIT",
116
+ orderType: price > 0 ? "NET_CREDIT" : "NET_DEBIT",
147
117
  session: "NORMAL",
148
118
  price: price,
149
119
  duration: "DAY",
150
120
  orderStrategyType: "SINGLE",
151
121
  orderLegCollection: [
152
- ## @TODO: this is only entering the next position, need to also close out the previous.
122
+ ## close
123
+ {
124
+ instruction: "BUY_TO_CLOSE",
125
+ quantity: pos.q,
126
+ instrument: {
127
+ symbol: pos.autoprev.inner.symbol,
128
+ assetType: "OPTION",
129
+ },
130
+ },
131
+ {
132
+ instruction: "SELL_TO_CLOSE",
133
+ quantity: pos.q,
134
+ instrument: {
135
+ symbol: pos.autoprev.outer.symbol,
136
+ assetType: "OPTION",
137
+ },
138
+ },
139
+
140
+ ## open
153
141
  {
154
142
  instruction: "BUY_TO_OPEN",
155
- quantity: q,
143
+ quantity: pos.q,
156
144
  instrument: {
157
- symbol: outer.symbol,
145
+ symbol: pos.outer.symbol,
158
146
  assetType: "OPTION",
159
147
  },
160
148
  },
161
149
  {
162
150
  instruction: "SELL_TO_OPEN",
163
- quantity: q,
151
+ quantity: pos.q,
164
152
  instrument: {
165
- symbol: inner.symbol,
153
+ symbol: pos.inner.symbol,
166
154
  assetType: "OPTION",
167
155
  },
168
156
  },
169
157
  ],
170
158
  }
159
+ puts! @query, '@query'
171
160
  end
172
161
 
173
- -## long debit call spread
162
+ ## long debit call spread
174
163
  def prepare3
175
- out = Tda::Option.roll_long_debit_call_spread( position )
176
- end
164
+ pos = @position = Iro::Position.find params[:id]
165
+ authorize! :place_order, @position
177
166
 
178
- def prepare
179
- @position = Iro::Position.find params[:id]
180
- authorize! :roll, @position
167
+ # out = Tda::Option.roll_long_debit_call_spread( position )
181
168
 
182
- @prev = @position
183
- @purse = @position.purse
184
- @stock = @position.stock
185
- @n_dollars = 100
169
+ ## @TODO: it's pending here, the order has not been placed.
186
170
 
187
- ## holiday schedule
188
- @next_expires_on = @prev.expires_on.to_datetime.next_occurring(:monday).next_occurring(:friday)
189
- if !@next_expires_on.workday?
190
- @next_expires_on = Time.previous_business_day( @next_expires_on )
191
- end
171
+ flags = []
192
172
 
193
- ## dealing with too many strikes in the chain
194
- while true
195
- @nn = ( @position.purse.n_next_positions/2 ).ceil
196
- upper = Tda::Option.get_quote({
197
- contractType: 'CALL',
198
- strike: @prev.inner_strike + @nn*@stock.options_price_increment,
199
- expirationDate: @next_expires_on,
200
- ticker: @stock.ticker,
201
- })
202
- if !upper.symbol
203
- puts! 'too high'
204
- flash_alert 'too high'
205
- @purse.n_next_positions = @purse.n_next_positions - 1
206
- @purse.n_next_positions = 1 if @purse.n_next_positions < 1
207
- @purse.save!
208
- next
209
- end
210
- lower = Tda::Option.get_quote({
211
- contractType: 'CALL',
212
- strike: @prev.inner_strike - @nn*@stock.options_price_increment,
213
- expirationDate: @next_expires_on,
214
- ticker: @stock.ticker,
215
- })
216
- if !lower.symbol
217
- puts! 'too low'
218
- flash_alert 'too low'
219
- @purse.n_next_positions = @purse.n_next_positions - 1
220
- @purse.n_next_positions = 1 if @purse.n_next_positions < 1
221
- @purse.save!
222
- next
223
- end
224
- break
225
- end
173
+ flags.push pos.prev.update({ status: Iro::Position::STATUS_CLOSED })
174
+ flags.push pos.update({ status: Iro::Position::STATUS_ACTIVE })
175
+ flags.push pos.purse.update({
176
+ available_amount: pos.purse.available_amount + price + pos.q*100,
177
+ })
226
178
 
227
- self.send("_prepare_#{@position.strategy.kind}")
179
+ flash_notice flags
180
+ redirect_to controller: :purses, action: :show, template: :gameui, id: pos.purse_id
228
181
  end
229
182
 
183
+
184
+
230
185
  def _prepare_covered_call
231
186
  @positions = []
232
187
  (-@nn..@nn).each do |idx|
233
188
  next_ = Iro::Position.new({
234
189
  stock: @stock,
235
- inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
236
- expires_on: @next_expires_on,
190
+ inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
191
+ expires_on: @prev.next_expires_on,
237
192
  purse: @position.purse,
238
193
  strategy: @position.strategy,
239
194
  quantity: @position.quantity,
@@ -242,8 +197,6 @@ class Iro::PositionsController < Iro::ApplicationController
242
197
  next_.begin_inner_price = next_.end_inner_price
243
198
  next_.begin_inner_delta = next_.end_inner_delta
244
199
  next_.next_gain_loss_amount = next_.begin_inner_price - @prev.end_inner_price
245
- puts! next_, 'next_'
246
- puts! next_.next_gain_loss_amount, 'amount'
247
200
  @positions.push next_
248
201
  end
249
202
  end
@@ -252,63 +205,81 @@ class Iro::PositionsController < Iro::ApplicationController
252
205
  @positions = []
253
206
  (-@nn..@nn).each do |idx|
254
207
  next_ = Iro::Position.find_or_create_by({
255
- status: 'prepare',
256
- stock: @stock,
257
- inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
258
- outer_strike: @prev.outer_strike - idx*@stock.options_price_increment,
259
- expires_on: @next_expires_on,
208
+ expires_on: @prev.next_expires_on,
209
+ inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
210
+ outer_strike: @prev.outer.strike - idx*@stock.options_price_increment,
211
+ prev_id: @prev.id,
260
212
  purse: @position.purse,
261
- strategy: @position.strategy,
262
213
  quantity: @position.quantity,
263
- prev_id: @prev.id,
214
+ status: 'prepare',
215
+ stock: @stock,
216
+ strategy: @position.strategy,
217
+ })
218
+ pos = next_
219
+ next_.inner ||= Iro::Option.new({
220
+ # begin_price: pos[:begin_inner_price],
221
+ # begin_delta: pos[:begin_inner_delta],
222
+ expires_on: pos[:expires_on],
223
+ inner: pos,
224
+ put_call: pos.put_call,
225
+ stock_id: pos[:stock_id],
226
+ strike: pos[:inner_strike],
227
+ })
228
+ next_.outer ||= Iro::Option.new({
229
+ # begin_price: pos[:begin_inner_price],
230
+ # begin_delta: pos[:begin_inner_delta],
231
+ expires_on: pos[:expires_on],
232
+ outer: pos,
233
+ put_call: pos.put_call,
234
+ stock_id: pos[:stock_id],
235
+ strike: pos[:outer_strike],
264
236
  })
237
+
265
238
  next_.sync
266
- next_.begin_inner_price = next_.end_inner_price
267
- next_.begin_inner_delta = next_.end_inner_delta
239
+ next_.inner.begin_price = next_.inner.end_price
240
+ next_.inner.begin_delta = next_.inner.end_delta
268
241
 
269
- next_.begin_outer_price = next_.end_outer_price
270
- next_.begin_outer_delta = next_.end_outer_delta
271
- next_.next_gain_loss_amount = @prev.end_outer_price - @prev.end_inner_price
272
- next_.next_gain_loss_amount += next_.begin_inner_price - next_.begin_outer_price
242
+ next_.outer.begin_price = next_.outer.end_price
243
+ next_.outer.begin_delta = next_.outer.end_delta
244
+
245
+ next_.next_gain_loss_amount = @prev.outer.end_price - @prev.inner.end_price
246
+ next_.next_gain_loss_amount += next_.inner.begin_price - next_.outer.begin_price
273
247
  next_.save
274
- puts! next_, 'next_'
275
- puts! next_.next_gain_loss_amount, 'next_gain_loss_amount'
276
248
  @positions.push next_
277
249
  end
278
250
  @positions = @positions.reverse
279
251
  end
252
+ alias_method :_prepare_short_debit_put_spread, :_prepare_long_debit_call_spread
253
+ alias_method :_prepare_short_credit_call_spread, :_prepare_long_debit_call_spread
280
254
 
281
- def _prepare_short_debit_put_spread
282
- @positions = []
283
- (-@nn..@nn).each do |idx|
284
- next_ = Iro::Position.new({
285
- stock: @stock,
286
- inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
287
- outer_strike: @prev.outer_strike - idx*@stock.options_price_increment,
288
- expires_on: @next_expires_on,
289
- purse: @position.purse,
290
- strategy: @position.strategy,
291
- quantity: @position.quantity,
292
- })
293
- next_.sync
294
- next_.begin_inner_price = next_.end_inner_price
295
- next_.begin_inner_delta = next_.end_inner_delta
296
255
 
297
- next_.begin_outer_price = next_.end_outer_price
298
- next_.begin_outer_delta = next_.end_outer_delta
299
- next_.next_gain_loss_amount = @prev.end_outer_price - @prev.end_inner_price
300
- next_.next_gain_loss_amount += next_.begin_inner_price - next_.begin_outer_price
301
- puts! next_, 'next_'
302
- puts! next_.next_gain_loss_amount, 'next_gain_loss_amount'
303
- @positions.push next_
256
+ def sync
257
+ @position = pos = Iro::Position.find params[:id]
258
+ authorize! :refresh, @position
259
+
260
+ @position.sync
261
+ @position.calc_rollp
262
+ if true # @position.rollp > 0.5
263
+ @position.calc_nxt
304
264
  end
265
+
266
+ redirect_to request.referrer || purse_path( @position.purse )
305
267
  end
306
268
 
269
+ ##
270
+ ## only updates some attributes
271
+ ##
307
272
  def update
308
- @position = Iro::Position.find params[:id]
273
+ pos = @position = Iro::Position.find params[:id]
309
274
  authorize! :update, @position
310
275
 
311
- if @position.update params[:position].permit!
276
+ if @position.update pos_params
277
+ o_attrs = {
278
+ expires_on: pos.expires_on,
279
+ }
280
+ pos.inner.update params[:inner].permit!.merge( o_attrs )
281
+ pos.outer.update params[:outer].permit!.merge( o_attrs )
282
+
312
283
  flash_notice @position
313
284
  redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
314
285
  else
@@ -317,14 +288,32 @@ class Iro::PositionsController < Iro::ApplicationController
317
288
  end
318
289
  end
319
290
 
291
+
292
+
320
293
  ##
321
294
  ## private
322
295
  ##
323
296
  private
324
297
 
298
+ def pos_params
299
+ params[:position].permit( :begin_on,
300
+ :expires_on,
301
+ :long_or_short,
302
+ :purse_id,
303
+ :quantity,
304
+ :status, :stock_id, :strategy_id,
305
+ )
306
+ end
307
+
308
+ def price
309
+ pos = @position
310
+ out = pos.autoprev.outer.end_price - pos.autoprev.inner.end_price + pos.inner.begin_price - pos.outer.begin_price
311
+ return out
312
+ end
313
+
314
+
325
315
  def set_lists
326
316
  super
327
-
328
317
  @purses_list = Iro::Purse.list
329
318
  @strategies_list = Iro::Strategy.list(params[:long_or_short])
330
319
  @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
@@ -20,11 +20,19 @@ class Iro::StocksController < Iro::ApplicationController
20
20
  end
21
21
 
22
22
  def edit
23
+ authorize! :edit, @stock
23
24
  end
24
25
 
25
26
  def index
26
27
  @stocks = Iro::Stock.all
27
28
  authorize! :index, Iro::Stock
29
+
30
+ respond_to do |format|
31
+ format.html
32
+ format.json do
33
+ render layout: false
34
+ end
35
+ end
28
36
  end
29
37
 
30
38
  def new
@@ -32,18 +40,29 @@ class Iro::StocksController < Iro::ApplicationController
32
40
  authorize! :new, @stock
33
41
  end
34
42
 
35
- def refresh
43
+ def sync
36
44
  authorize! :refresh, Iro::Stock
37
45
  tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
38
46
  outs = Tda::Stock.get_quotes tickers
39
47
  outs.map do |out|
40
48
  Iro::Stock.where( ticker: out[:symbol] ).update( last: out[:last] )
41
49
  end
42
- flash_notice 'ok'
50
+ flash_notice 'refreshed stocks'
43
51
  redirect_to request.referrer
44
52
  end
45
53
 
46
54
  def show
55
+ authorize! :show, @stock
56
+
57
+ @priceitems = Iro::PriceItem.where({
58
+ ticker: @stock.ticker,
59
+ })
60
+
61
+ respond_to do |format|
62
+ format.json do
63
+ render layout: false
64
+ end
65
+ end
47
66
  end
48
67
 
49
68
  def update
@@ -9,7 +9,7 @@ class Iro::Datapoint
9
9
  validates :kind, presence: true
10
10
  index({ kind: -1 })
11
11
 
12
- field :symbol ## ticker, but use 'symbol' ONLY
12
+ field :symbol ## ticker, but use 'symbol' here
13
13
 
14
14
  field :date, type: Date ## @obsolete, use quote_at
15
15
  index({ kind: -1, date: -1 })