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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/iron_warbler/Card.scss +6 -0
- data/app/assets/stylesheets/iron_warbler/positions.scss +1 -1
- data/app/assets/stylesheets/iron_warbler/purses.scss +31 -0
- data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
- data/app/assets/stylesheets/iron_warbler/utils.scss +28 -3
- data/app/controllers/iro/api/stocks_controller.rb +7 -4
- data/app/controllers/iro/application_controller.rb +6 -0
- data/app/controllers/iro/positions_controller.rb +188 -199
- data/app/controllers/iro/purses_controller.rb +3 -1
- data/app/controllers/iro/stocks_controller.rb +21 -2
- data/app/models/iro/datapoint.rb +1 -1
- data/app/models/iro/option.rb +50 -150
- data/app/models/iro/option_black_scholes.rb +149 -0
- data/app/models/iro/position.rb +155 -212
- data/app/models/iro/{price_item.rb → priceitem.rb} +5 -1
- data/app/models/iro/purse.rb +41 -4
- data/app/models/iro/stock.rb +2 -0
- data/app/models/iro/strategy.rb +121 -82
- data/app/models/tda/option.rb +1 -1
- data/app/models/tda/stock.rb +1 -1
- data/app/views/iro/_main_header.haml +8 -5
- data/app/views/iro/api/stocks/index.json.jbuilder +5 -0
- data/app/views/iro/api/stocks/show.json.jbuilder +11 -0
- data/app/views/iro/api/stocks/show.json.jbuilder-bk +12 -0
- data/app/views/iro/options/_show_mini.haml +8 -0
- data/app/views/iro/positions/_form.haml +11 -4
- data/app/views/iro/positions/_formpart_4data.haml +41 -38
- data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +4 -4
- data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
- data/app/views/iro/positions/_gameui_short_credit_call_spread.haml +38 -0
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
- data/app/views/iro/positions/_header.haml +2 -0
- data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
- data/app/views/iro/positions/_header_short_credit_call_spread.haml +50 -0
- data/app/views/iro/positions/_new.haml +23 -0
- data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +2 -3
- data/app/views/iro/positions/_prepare_short_credit_call_spread.haml +1 -0
- data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
- data/app/views/iro/positions/_table.haml +25 -26
- data/app/views/iro/positions/prepare.haml +6 -4
- data/app/views/iro/positions/prepare2.haml +15 -4
- data/app/views/iro/purses/_form_extra_fields.haml +18 -18
- data/app/views/iro/purses/_header.haml +12 -7
- data/app/views/iro/purses/_summary.haml +69 -62
- data/app/views/iro/purses/show.haml +4 -3
- data/app/views/iro/stocks/_form.haml +4 -3
- data/app/views/iro/stocks/edit.haml +4 -0
- data/app/views/iro/stocks/index.haml +21 -6
- data/app/views/iro/strategies/_form.haml +36 -26
- data/app/views/iro/strategies/_show.haml +7 -5
- data/config/routes.rb +7 -4
- data/lib/iro/engine.rb +1 -0
- data/lib/iron_warbler.rb +0 -2
- data/lib/tasks/iro_tasks.rake +2 -2
- metadata +17 -4
- data/app/views/iro/api/stocks/show.jbuilder +0 -11
- 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
|
6
|
+
pos = @position = Iro::Position.new pos_params
|
24
7
|
authorize! :create, @position
|
25
8
|
|
26
|
-
|
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
|
-
|
51
|
-
|
52
|
-
@
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
107
|
-
@position =
|
108
|
-
authorize! :
|
61
|
+
def prepare
|
62
|
+
@position = Iro::Position.find params[:id]
|
63
|
+
authorize! :roll, @position
|
109
64
|
|
110
|
-
@position
|
111
|
-
@position.
|
65
|
+
@prev = @position
|
66
|
+
@purse = @position.purse
|
67
|
+
@stock = @position.stock
|
68
|
+
@n_dollars = 100
|
112
69
|
|
113
|
-
|
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
|
-
|
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
|
-
##
|
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
|
-
|
162
|
+
## long debit call spread
|
174
163
|
def prepare3
|
175
|
-
|
176
|
-
|
164
|
+
pos = @position = Iro::Position.find params[:id]
|
165
|
+
authorize! :place_order, @position
|
177
166
|
|
178
|
-
|
179
|
-
@position = Iro::Position.find params[:id]
|
180
|
-
authorize! :roll, @position
|
167
|
+
# out = Tda::Option.roll_long_debit_call_spread( position )
|
181
168
|
|
182
|
-
@
|
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
|
-
|
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
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
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
|
-
|
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.
|
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
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
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
|
-
|
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_.
|
267
|
-
next_.
|
239
|
+
next_.inner.begin_price = next_.inner.end_price
|
240
|
+
next_.inner.begin_delta = next_.inner.end_delta
|
268
241
|
|
269
|
-
next_.
|
270
|
-
next_.
|
271
|
-
|
272
|
-
next_.next_gain_loss_amount
|
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
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
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
|
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(
|
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
|
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 '
|
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
|
data/app/models/iro/datapoint.rb
CHANGED
@@ -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'
|
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 })
|