iron_warbler 2.0.7.24 → 2.0.7.26
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/positions_gameui.scss +8 -0
- data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +2 -4
- data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
- data/app/controllers/iro/application_controller.rb +6 -0
- data/app/controllers/iro/positions_controller.rb +186 -137
- data/app/controllers/iro/purses_controller.rb +3 -1
- data/app/controllers/iro/stocks_controller.rb +2 -2
- data/app/models/iro/option.rb +41 -148
- data/app/models/iro/option_black_scholes.rb +149 -0
- data/app/models/iro/position.rb +156 -205
- data/app/models/iro/purse.rb +34 -4
- data/app/models/iro/strategy.rb +49 -47
- data/app/views/iro/_main_header.haml +4 -2
- data/app/views/iro/options/_show_mini.haml +8 -0
- data/app/views/iro/positions/_form.haml +8 -3
- data/app/views/iro/positions/_formpart_4data.haml +41 -38
- data/app/views/iro/positions/_gameui_covered_call.haml +1 -1
- data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +5 -5
- data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -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/_prepare_long_debit_call_spread.haml +6 -5
- 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 +22 -0
- data/app/views/iro/purses/_form_extra_fields.haml +8 -4
- data/app/views/iro/purses/_header.haml +19 -5
- data/app/views/iro/purses/_summary.haml +69 -62
- data/app/views/iro/purses/show.haml +1 -1
- data/app/views/iro/strategies/_form.haml +26 -19
- data/app/views/iro/strategies/_show.haml +6 -4
- data/config/routes.rb +10 -7
- metadata +8 -2
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4afc65383198cc16143683cc82db6ee65604f14a8d13d4d7bc262210ceb14940
|
4
|
+
data.tar.gz: 04c7d9a3585dd1036c8f227a1cbbe38fbc6e7d71f68977f3183ac07bdbaba3cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a905e844e0542aa1f7500c1c1bc25a234f2698bc8bfb1e75d83fb7ab2ba24dcc28ed261a876f1add4d9dec80decb32cb84ed1694ac3b8e3657be48f8a36b86bc
|
7
|
+
data.tar.gz: d9478f1d454dbcbee3b6fc703233f7d72049ac128f1ad2e550e38286483ccc51a863e8ace598511c2c28a6ce8a26240215d97ff2d524e5a3e03dcbdc5fb1eb40
|
@@ -52,7 +52,7 @@
|
|
52
52
|
.Position {
|
53
53
|
position: absolute;
|
54
54
|
width: 100%;
|
55
|
-
height:
|
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:
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
width: 1em;
|
50
|
+
.delta {
|
51
|
+
position: absolute;
|
52
|
+
left: 100px;
|
53
|
+
height: 100%;
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
55
|
+
> div {
|
56
|
+
border: 1px dotted yellow;
|
57
|
+
width: 0.5em;
|
58
|
+
}
|
59
|
+
.begin {
|
60
|
+
width: 1em;
|
65
61
|
|
66
|
-
|
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
|
81
|
-
|
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
|
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
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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:
|
135
|
-
strike: @prev.
|
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:
|
149
|
-
strike: @prev.
|
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.
|
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.
|
192
|
-
|
193
|
-
inner_strike: @prev.
|
194
|
-
outer_strike: @prev.
|
195
|
-
|
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_.
|
202
|
-
next_.
|
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_.
|
205
|
-
next_.
|
206
|
-
next_.
|
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
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
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
|
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(
|
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
|
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 '
|
42
|
+
flash_notice 'refreshed stocks'
|
43
43
|
redirect_to request.referrer
|
44
44
|
end
|
45
45
|
|