iron_warbler 2.0.7.25 → 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 (37) 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_summary.scss +31 -19
  5. data/app/controllers/iro/application_controller.rb +6 -0
  6. data/app/controllers/iro/positions_controller.rb +183 -200
  7. data/app/controllers/iro/purses_controller.rb +3 -1
  8. data/app/controllers/iro/stocks_controller.rb +2 -2
  9. data/app/models/iro/option.rb +38 -150
  10. data/app/models/iro/option_black_scholes.rb +149 -0
  11. data/app/models/iro/position.rb +154 -209
  12. data/app/models/iro/purse.rb +34 -4
  13. data/app/models/iro/strategy.rb +49 -47
  14. data/app/views/iro/_main_header.haml +4 -2
  15. data/app/views/iro/options/_show_mini.haml +8 -0
  16. data/app/views/iro/positions/_form.haml +8 -3
  17. data/app/views/iro/positions/_formpart_4data.haml +41 -38
  18. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +4 -4
  19. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
  20. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
  21. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
  22. data/app/views/iro/positions/_header.haml +2 -0
  23. data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
  24. data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +2 -3
  25. data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
  26. data/app/views/iro/positions/_table.haml +25 -26
  27. data/app/views/iro/positions/prepare.haml +6 -4
  28. data/app/views/iro/positions/prepare2.haml +15 -4
  29. data/app/views/iro/purses/_form_extra_fields.haml +7 -3
  30. data/app/views/iro/purses/_header.haml +19 -5
  31. data/app/views/iro/purses/_summary.haml +69 -62
  32. data/app/views/iro/purses/show.haml +1 -1
  33. data/app/views/iro/strategies/_form.haml +26 -19
  34. data/app/views/iro/strategies/_show.haml +6 -4
  35. data/config/routes.rb +5 -3
  36. metadata +7 -2
  37. 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: 8184e7abf0df5faad6e8d99504be22235e0fa846801be7bd2869e7f81631349b
4
- data.tar.gz: ac0dab40337f109eadccd06b943203e19c507abc9a05cc3e66f0f453b8275d82
3
+ metadata.gz: 4afc65383198cc16143683cc82db6ee65604f14a8d13d4d7bc262210ceb14940
4
+ data.tar.gz: 04c7d9a3585dd1036c8f227a1cbbe38fbc6e7d71f68977f3183ac07bdbaba3cf
5
5
  SHA512:
6
- metadata.gz: e892adf76bb1fecaf319f614bb4249689bd5b761e46b234f5e27b89d3640b0f6fcfb7f9cfba5ecd25873b8c9af40ab7d9e8e706293d09879447c7188ae47303d
7
- data.tar.gz: e037e728a1a2beb3f4f07ec46f5c40c188514960bd961570fb603e5a73842377a01268c9e1ff8538e8c7bc1afc213dc4df5a73fd826be9209838318f2aaee65b
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;
@@ -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,73 +35,72 @@ class Iro::PositionsController < Iro::ApplicationController
47
35
  authorize! :edit, @position
48
36
  end
49
37
 
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]
56
-
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
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
75
47
 
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'
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
102
54
  end
103
- redirect_to request.referrer
104
55
  end
105
56
 
106
- def refresh
107
- @position = pos = Iro::Position.find params[:id]
108
- authorize! :refresh, @position
57
+ def prepare
58
+ @position = Iro::Position.find params[:id]
59
+ authorize! :roll, @position
109
60
 
110
- @position.sync
111
- @position.calc_rollp
61
+ @prev = @position
62
+ @purse = @position.purse
63
+ @stock = @position.stock
64
+ @n_dollars = 100
112
65
 
113
- redirect_to request.referrer || purse_path( @position.purse )
66
+ ## dealing with too many strikes in the chain
67
+ while true
68
+ @nn = ( @position.purse.n_next_positions/2 ).ceil
69
+ upper = Tda::Option.get_quote({
70
+ contractType: @position.put_call,
71
+ strike: @prev.inner.strike + @nn*@stock.options_price_increment,
72
+ expirationDate: @prev.next_expires_on,
73
+ ticker: @stock.ticker,
74
+ })
75
+ if !upper.symbol
76
+ puts! 'too high'
77
+ flash_alert 'too high'
78
+ @purse.n_next_positions = @purse.n_next_positions - 1
79
+ @purse.n_next_positions = 1 if @purse.n_next_positions < 1
80
+ @purse.save!
81
+ next
82
+ end
83
+ lower = Tda::Option.get_quote({
84
+ contractType: @position.put_call,
85
+ strike: @prev.inner.strike - @nn*@stock.options_price_increment,
86
+ expirationDate: @prev.next_expires_on,
87
+ ticker: @stock.ticker,
88
+ })
89
+ if !lower.symbol
90
+ puts! 'too low'
91
+ flash_alert 'too low'
92
+ @purse.n_next_positions = @purse.n_next_positions - 1
93
+ @purse.n_next_positions = 1 if @purse.n_next_positions < 1
94
+ @purse.save!
95
+ next
96
+ end
97
+ break
98
+ end
99
+
100
+ self.send("_prepare_#{@position.strategy.kind}")
114
101
  end
115
102
 
116
- -## long debit call spread
103
+ ## long debit call spread
117
104
  def prepare2
118
105
  @position = Iro::Position.find params[:id]
119
106
  authorize! :roll, @position
@@ -121,119 +108,83 @@ class Iro::PositionsController < Iro::ApplicationController
121
108
  pos = @position
122
109
  stock = @position.stock
123
110
 
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
111
  @query = {
146
- orderType: "NET_DEBIT",
112
+ orderType: price > 0 ? "NET_CREDIT" : "NET_DEBIT",
147
113
  session: "NORMAL",
148
114
  price: price,
149
115
  duration: "DAY",
150
116
  orderStrategyType: "SINGLE",
151
117
  orderLegCollection: [
152
- ## @TODO: this is only entering the next position, need to also close out the previous.
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
153
137
  {
154
138
  instruction: "BUY_TO_OPEN",
155
- quantity: q,
139
+ quantity: pos.q,
156
140
  instrument: {
157
- symbol: outer.symbol,
141
+ symbol: pos.outer.symbol,
158
142
  assetType: "OPTION",
159
143
  },
160
144
  },
161
145
  {
162
146
  instruction: "SELL_TO_OPEN",
163
- quantity: q,
147
+ quantity: pos.q,
164
148
  instrument: {
165
- symbol: inner.symbol,
149
+ symbol: pos.inner.symbol,
166
150
  assetType: "OPTION",
167
151
  },
168
152
  },
169
153
  ],
170
154
  }
155
+ puts! @query, '@query'
171
156
  end
172
157
 
173
- -## long debit call spread
158
+ ## long debit call spread
174
159
  def prepare3
175
- out = Tda::Option.roll_long_debit_call_spread( position )
176
- end
160
+ pos = @position = Iro::Position.find params[:id]
161
+ authorize! :place_order, @position
177
162
 
178
- def prepare
179
- @position = Iro::Position.find params[:id]
180
- authorize! :roll, @position
163
+ # out = Tda::Option.roll_long_debit_call_spread( position )
181
164
 
182
- @prev = @position
183
- @purse = @position.purse
184
- @stock = @position.stock
185
- @n_dollars = 100
165
+ ## @TODO: it's pending here, the order has not been placed.
186
166
 
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
167
+ flags = []
192
168
 
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
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
+ })
226
174
 
227
- self.send("_prepare_#{@position.strategy.kind}")
175
+ flash_notice flags
176
+ redirect_to controller: :purses, action: :show, template: :gameui, id: pos.purse_id
228
177
  end
229
178
 
179
+
180
+
230
181
  def _prepare_covered_call
231
182
  @positions = []
232
183
  (-@nn..@nn).each do |idx|
233
184
  next_ = Iro::Position.new({
234
185
  stock: @stock,
235
- inner_strike: @prev.inner_strike - idx*@stock.options_price_increment,
236
- expires_on: @next_expires_on,
186
+ inner_strike: @prev.inner.strike - idx*@stock.options_price_increment,
187
+ expires_on: @prev.next_expires_on,
237
188
  purse: @position.purse,
238
189
  strategy: @position.strategy,
239
190
  quantity: @position.quantity,
@@ -242,8 +193,6 @@ class Iro::PositionsController < Iro::ApplicationController
242
193
  next_.begin_inner_price = next_.end_inner_price
243
194
  next_.begin_inner_delta = next_.end_inner_delta
244
195
  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
196
  @positions.push next_
248
197
  end
249
198
  end
@@ -252,63 +201,82 @@ class Iro::PositionsController < Iro::ApplicationController
252
201
  @positions = []
253
202
  (-@nn..@nn).each do |idx|
254
203
  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,
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,
260
208
  purse: @position.purse,
261
- strategy: @position.strategy,
262
209
  quantity: @position.quantity,
263
- prev_id: @prev.id,
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],
264
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
+
265
234
  next_.sync
266
- next_.begin_inner_price = next_.end_inner_price
267
- 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
268
240
 
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
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
273
243
  next_.save
274
- puts! next_, 'next_'
275
- puts! next_.next_gain_loss_amount, 'next_gain_loss_amount'
276
244
  @positions.push next_
277
245
  end
278
246
  @positions = @positions.reverse
279
247
  end
248
+ alias_method :_prepare_short_debit_put_spread, :_prepare_long_debit_call_spread
280
249
 
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
250
 
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_
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
304
259
  end
260
+
261
+ redirect_to request.referrer || purse_path( @position.purse )
305
262
  end
306
263
 
264
+ ##
265
+ ## only updates some attributes
266
+ ##
307
267
  def update
308
- @position = Iro::Position.find params[:id]
268
+ pos = @position = Iro::Position.find params[:id]
309
269
  authorize! :update, @position
310
270
 
311
- 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
+
312
280
  flash_notice @position
313
281
  redirect_to controller: :purses, action: :show, id: @position.purse_id.to_s
314
282
  else
@@ -317,14 +285,29 @@ class Iro::PositionsController < Iro::ApplicationController
317
285
  end
318
286
  end
319
287
 
288
+
289
+
320
290
  ##
321
291
  ## private
322
292
  ##
323
293
  private
324
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
+
325
309
  def set_lists
326
310
  super
327
-
328
311
  @purses_list = Iro::Purse.list
329
312
  @strategies_list = Iro::Strategy.list(params[:long_or_short])
330
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