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
data/app/models/iro/strategy.rb
CHANGED
@@ -8,111 +8,144 @@ class Iro::Strategy
|
|
8
8
|
field :slug
|
9
9
|
validates :slug, presence: true, uniqueness: true
|
10
10
|
|
11
|
-
|
11
|
+
field :description
|
12
|
+
|
13
|
+
LONG = 'is_long'
|
12
14
|
SHORT = 'is_short'
|
13
15
|
field :long_or_short, type: :string
|
14
16
|
validates :long_or_short, presence: true
|
15
17
|
|
16
|
-
field :description
|
17
|
-
|
18
|
-
has_many :positions, class_name: 'Iro::Position', inverse_of: :strategy
|
19
18
|
|
19
|
+
has_many :positions, class_name: 'Iro::Position', inverse_of: :strategy
|
20
|
+
has_one :next_position, class_name: 'Iro::Position', inverse_of: :next_strategy
|
20
21
|
belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
has_and_belongs_to_many :purses, class_name: 'Iro::Purse', inverse_of: :strategies
|
23
|
+
|
24
|
+
KIND_COVERED_CALL = 'covered_call'
|
25
|
+
KIND_IRON_CONDOR = 'iron_condor'
|
26
|
+
KIND_LONG_CREDIT_PUT_SPREAD = 'long_credit_put_spread'
|
27
|
+
KIND_LONG_DEBIT_CALL_SPREAD = 'long_debit_call_spread'
|
28
|
+
KIND_SHORT_CREDIT_CALL_SPREAD = 'short_credit_call_spread'
|
29
|
+
KIND_SHORT_DEBIT_PUT_SPREAD = 'short_debit_put_spread'
|
25
30
|
KINDS = [ nil,
|
26
31
|
KIND_COVERED_CALL,
|
32
|
+
KIND_IRON_CONDOR,
|
33
|
+
KIND_LONG_CREDIT_PUT_SPREAD,
|
27
34
|
KIND_LONG_DEBIT_CALL_SPREAD,
|
35
|
+
KIND_SHORT_CREDIT_CALL_SPREAD,
|
28
36
|
KIND_SHORT_DEBIT_PUT_SPREAD,
|
29
37
|
]
|
30
38
|
field :kind
|
31
39
|
|
32
|
-
def
|
40
|
+
def put_call
|
33
41
|
case kind
|
34
|
-
when
|
35
|
-
'
|
36
|
-
when
|
37
|
-
'
|
38
|
-
when KIND_SHORT_DEBIT_PUT_SPREAD
|
39
|
-
'
|
40
|
-
|
41
|
-
'
|
42
|
+
when Iro::Strategy::KIND_LONG_DEBIT_CALL_SPREAD
|
43
|
+
put_call = 'CALL'
|
44
|
+
when Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD
|
45
|
+
put_call = 'CALL'
|
46
|
+
when Iro::Strategy::KIND_SHORT_DEBIT_PUT_SPREAD
|
47
|
+
put_call = 'PUT'
|
48
|
+
when Iro::Strategy::KIND_COVERED_CALL
|
49
|
+
put_call = 'CALL'
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
45
|
-
field :
|
46
|
-
field :threshold_delta,
|
47
|
-
field :threshold_netp,
|
53
|
+
field :threshold_buffer_above_water, type: :float
|
54
|
+
field :threshold_delta, type: :float
|
55
|
+
field :threshold_netp, type: :float
|
56
|
+
field :threshold_dte, type: :integer, default: 1
|
48
57
|
|
49
|
-
field :next_inner_delta,
|
50
|
-
field :
|
51
|
-
field :
|
52
|
-
field :next_outer_strike,
|
53
|
-
field :next_spread_amount,
|
58
|
+
field :next_inner_delta, type: :float
|
59
|
+
field :next_inner_strike, type: :float
|
60
|
+
field :next_outer_delta, type: :float
|
61
|
+
field :next_outer_strike, type: :float
|
62
|
+
field :next_spread_amount, type: :float # e.g. $20 for a $2000 NVDA spread
|
63
|
+
field :next_buffer_above_water, type: :float
|
54
64
|
|
55
65
|
|
56
|
-
|
57
|
-
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
def begin_delta_covered_call p
|
71
|
+
p.inner.begin_delta
|
58
72
|
end
|
73
|
+
def begin_delta_long_debit_call_spread p
|
74
|
+
p.outer.begin_delta - p.inner.begin_delta
|
75
|
+
end
|
76
|
+
alias_method :begin_delta_short_debit_put_spread, :begin_delta_long_debit_call_spread
|
77
|
+
alias_method :begin_delta_short_credit_call_spread, :begin_delta_long_debit_call_spread
|
78
|
+
|
59
79
|
|
60
80
|
def breakeven_covered_call p
|
61
|
-
p.
|
81
|
+
p.inner.strike + p.inner.begin_price
|
62
82
|
end
|
63
83
|
def breakeven_long_debit_call_spread p
|
64
|
-
p.
|
84
|
+
p.inner.strike - p.max_gain
|
65
85
|
end
|
66
86
|
alias_method :breakeven_short_debit_put_spread, :breakeven_long_debit_call_spread
|
67
87
|
|
88
|
+
|
89
|
+
def end_delta_covered_call p
|
90
|
+
p.inner.end_delta
|
91
|
+
end
|
92
|
+
def end_delta_long_debit_call_spread p
|
93
|
+
p.outer.end_delta - p.inner.end_delta
|
94
|
+
end
|
95
|
+
alias_method :end_delta_short_debit_put_spread, :end_delta_long_debit_call_spread
|
96
|
+
alias_method :end_delta_short_credit_call_spread, :end_delta_long_debit_call_spread
|
97
|
+
|
98
|
+
|
68
99
|
def max_gain_covered_call p
|
69
|
-
#
|
70
|
-
p.begin_inner_price * 100 - 0.66 # @TODO: is this *100 really?
|
100
|
+
p.inner.begin_price * 100 - 0.66 # @TODO: is this *100 really?
|
71
101
|
end
|
72
102
|
def max_gain_long_debit_call_spread p
|
73
|
-
## 100 *
|
74
|
-
( p.
|
103
|
+
## 100 * disallowed for gameui
|
104
|
+
( p.inner.strike - p.outer.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
|
105
|
+
end
|
106
|
+
def max_gain_short_credit_call_spread p
|
107
|
+
p.inner.begin_price - p.outer.begin_price
|
75
108
|
end
|
76
109
|
def max_gain_short_debit_put_spread p
|
77
|
-
## 100 *
|
78
|
-
( p.
|
110
|
+
## 100 * disallowed for gameui
|
111
|
+
( p.outer.strike - p.inner.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
|
79
112
|
end
|
80
113
|
|
81
|
-
def net_amount_covered_call p
|
82
|
-
( p.begin_inner_price - p.end_inner_price )
|
83
|
-
end
|
84
|
-
def net_amount_long_debit_call_spread p
|
85
|
-
outer = p.end_outer_price - p.begin_outer_price
|
86
|
-
inner = p.begin_inner_price - p.end_inner_price
|
87
|
-
out = ( outer + inner )
|
88
|
-
end
|
89
|
-
alias_method :net_amount_short_debit_put_spread, :net_amount_long_debit_call_spread
|
90
114
|
|
91
115
|
def max_loss_covered_call p
|
92
|
-
p.
|
116
|
+
p.inner.begin_price*10 # just suppose 10,000%
|
93
117
|
end
|
94
118
|
def max_loss_long_debit_call_spread p
|
95
|
-
out = p.
|
119
|
+
out = p.outer.strike - p.inner.strike
|
96
120
|
end
|
97
121
|
def max_loss_short_debit_put_spread p # different
|
98
|
-
out = p.
|
122
|
+
out = p.inner.strike - p.outer.strike
|
123
|
+
end
|
124
|
+
def max_loss_short_credit_call_spread p
|
125
|
+
out = p.outer.strike - p.inner.strike
|
99
126
|
end
|
100
127
|
|
101
|
-
|
102
|
-
|
128
|
+
|
129
|
+
def net_amount_covered_call p
|
130
|
+
( p.inner.begin_price - p.inner.end_price )
|
103
131
|
end
|
104
|
-
def
|
105
|
-
p.
|
132
|
+
def net_amount_long_debit_call_spread p
|
133
|
+
outer = p.outer.end_price - p.outer.begin_price
|
134
|
+
inner = p.inner.begin_price - p.inner.end_price
|
135
|
+
out = ( outer + inner )
|
106
136
|
end
|
107
|
-
alias_method :
|
137
|
+
alias_method :net_amount_short_credit_call_spread , :net_amount_long_debit_call_spread
|
138
|
+
alias_method :net_amount_short_debit_put_spread, :net_amount_long_debit_call_spread
|
108
139
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
140
|
+
|
141
|
+
## 2024-05-09 @TODO
|
142
|
+
def next_inner_strike_on expires_on
|
143
|
+
outs = Tda::Option.get_quotes({
|
144
|
+
contractType: put_call,
|
145
|
+
expirationDate: expires_on,
|
146
|
+
ticker: stock.ticker,
|
147
|
+
})
|
114
148
|
end
|
115
|
-
alias_method :end_delta_short_debit_put_spread, :end_delta_long_debit_call_spread
|
116
149
|
|
117
150
|
|
118
151
|
|
@@ -126,18 +159,18 @@ class Iro::Strategy
|
|
126
159
|
return [ 0.99, '0 DTE, must exit' ]
|
127
160
|
end
|
128
161
|
|
129
|
-
if ( stock.last - buffer_above_water ) < p.
|
162
|
+
if ( stock.last - buffer_above_water ) < p.inner.strike
|
130
163
|
return [ 0.98, "Last #{'%.2f' % stock.last} is " +
|
131
|
-
"#{'%.2f' % [p.
|
132
|
-
"below #{'%.2f' % [p.
|
164
|
+
"#{'%.2f' % [p.inner.strike + buffer_above_water - stock.last]} " +
|
165
|
+
"below #{'%.2f' % [p.inner.strike + buffer_above_water]} water" ]
|
133
166
|
end
|
134
167
|
|
135
|
-
if p.
|
136
|
-
return [ 0.61, "Delta #{p.
|
168
|
+
if p.inner.end_delta < threshold_delta
|
169
|
+
return [ 0.61, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
|
137
170
|
end
|
138
171
|
|
139
|
-
if 1 - p.
|
140
|
-
return [ 0.51, "made enough #{'%.
|
172
|
+
if 1 - p.inner.end_price/p.inner.begin_price > threshold_netp
|
173
|
+
return [ 0.51, "made enough #{'%.02f' % [(1.0 - p.inner.end_price/p.inner.begin_price )*100]}% profit." ]
|
141
174
|
end
|
142
175
|
|
143
176
|
return [ 0.33, '-' ]
|
@@ -153,18 +186,18 @@ class Iro::Strategy
|
|
153
186
|
return [ 0.99, '1 DTE, must exit' ]
|
154
187
|
end
|
155
188
|
|
156
|
-
if ( stock.last - buffer_above_water ) < p.
|
189
|
+
if ( stock.last - buffer_above_water ) < p.inner.strike
|
157
190
|
return [ 0.95, "Last #{'%.2f' % stock.last} is " +
|
158
|
-
"#{'%.2f' % [stock.last - p.
|
159
|
-
"below #{'%.2f' % [p.
|
191
|
+
"#{'%.2f' % [stock.last - p.inner.strike - buffer_above_water]} " +
|
192
|
+
"below #{'%.2f' % [p.inner.strike + buffer_above_water]} water" ]
|
160
193
|
end
|
161
194
|
|
162
|
-
if p.
|
163
|
-
return [ 0.79, "Delta #{p.
|
195
|
+
if p.inner.end_delta < threshold_delta
|
196
|
+
return [ 0.79, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
|
164
197
|
end
|
165
198
|
|
166
|
-
if 1 - p.
|
167
|
-
return [ 0.51, "made enough #{'%.
|
199
|
+
if 1 - p.inner.end_price/p.inner.begin_price > threshold_netp
|
200
|
+
return [ 0.51, "made enough #{'%.02f' % [(1.0 - p.inner.end_price/p.inner.begin_price )*100]}% profit^" ]
|
168
201
|
end
|
169
202
|
|
170
203
|
return [ 0.33, '-' ]
|
@@ -173,35 +206,41 @@ class Iro::Strategy
|
|
173
206
|
## @TODO
|
174
207
|
def calc_rollp_short_debit_put_spread p
|
175
208
|
|
176
|
-
if ( p.expires_on.to_date - Time.now.to_date ).to_i
|
177
|
-
return [ 0.99,
|
209
|
+
if ( p.expires_on.to_date - Time.now.to_date ).to_i <= min_dte
|
210
|
+
return [ 0.99, "< #{min_dte}DTE, must exit" ]
|
178
211
|
end
|
179
212
|
|
180
|
-
if
|
213
|
+
if stock.last + buffer_above_water > p.inner.strike
|
181
214
|
return [ 0.98, "Last #{'%.2f' % stock.last} is " +
|
182
|
-
"#{'%.2f' % [stock.last - p.
|
183
|
-
"above #{'%.2f' % [p.
|
215
|
+
"#{'%.2f' % [stock.last + buffer_above_water - p.inner.strike]} " +
|
216
|
+
"above #{'%.2f' % [p.inner.strike - buffer_above_water]} water" ]
|
184
217
|
end
|
185
218
|
|
186
|
-
if p.
|
187
|
-
return [ 0.79, "Delta #{p.
|
219
|
+
if p.inner.end_delta.abs < threshold_delta.abs
|
220
|
+
return [ 0.79, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
|
188
221
|
end
|
189
222
|
|
190
|
-
if
|
191
|
-
return [ 0.51, "made enough #{'%.0f' % [
|
223
|
+
if p.net_percent > threshold_netp
|
224
|
+
return [ 0.51, "made enough #{'%.0f' % [p.net_percent*100]}% > #{"%.2f" % [threshold_netp*100]}% profit," ]
|
192
225
|
end
|
193
226
|
|
194
227
|
return [ 0.33, '-' ]
|
195
228
|
end
|
196
229
|
|
197
230
|
|
231
|
+
## scopes
|
232
|
+
|
233
|
+
def self.for_ticker ticker
|
234
|
+
where( ticker: ticker )
|
235
|
+
end
|
198
236
|
|
199
237
|
|
200
238
|
def to_s
|
201
|
-
|
239
|
+
slug
|
202
240
|
end
|
203
241
|
def self.list long_or_short = nil
|
204
242
|
these = long_or_short ? where( long_or_short: long_or_short ) : all
|
205
243
|
[[nil,nil]] + these.map { |ttt| [ ttt, ttt.id ] }
|
206
244
|
end
|
207
245
|
end
|
246
|
+
|
data/app/models/tda/option.rb
CHANGED
data/app/models/tda/stock.rb
CHANGED
@@ -4,12 +4,12 @@
|
|
4
4
|
|
5
5
|
%i.fa.fa-compress.collapse-expand#collapseHeaderTrading
|
6
6
|
Wco Trading
|
7
|
-
.
|
8
|
-
.d-flex
|
9
|
-
%ul
|
7
|
+
.W
|
8
|
+
.d-flex.flex-wrap
|
9
|
+
%ul
|
10
10
|
%li
|
11
11
|
= link_to "Stocks (#{Iro::Stock.all.length})", stocks_path
|
12
|
-
= link_to '[
|
12
|
+
= link_to '[sync]', sync_stocks_path
|
13
13
|
-# %li= link_to 'Options', options_path
|
14
14
|
-# %li Max Pain
|
15
15
|
%li
|
@@ -23,7 +23,10 @@
|
|
23
23
|
= link_to 'Purses', purses_path
|
24
24
|
%ul
|
25
25
|
- @purses.each do |p|
|
26
|
-
%li
|
26
|
+
%li
|
27
|
+
= link_to p, purse_path(p)
|
28
|
+
= link_to '[ui]', purse_gameui_path(p)
|
29
|
+
|
27
30
|
.a
|
28
31
|
= link_to 'Strategies', strategies_path
|
29
32
|
%ul
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
json.priceitems do
|
3
|
+
json.array! @datapoints do |p|
|
4
|
+
json.date p[:quote_at].in_time_zone('UTC').to_date
|
5
|
+
json.quote_at p[:quote_at]
|
6
|
+
json.open p[:open]
|
7
|
+
json.high p[:high]
|
8
|
+
json.low p[:low]
|
9
|
+
json.close p[:value]
|
10
|
+
json.volume p[:volume]
|
11
|
+
end
|
12
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
- long_or_short = position.long_or_short || position.strategy&.long_or_short || params[:long_or_short]
|
3
|
+
|
4
|
+
.positions--form{ class: params[:long_or_short] || long_or_short }
|
3
5
|
= form_for position do |f|
|
4
6
|
.actions
|
5
7
|
= f.submit
|
@@ -15,12 +17,17 @@
|
|
15
17
|
.field
|
16
18
|
%label Stock
|
17
19
|
= f.select :stock_id, options_for_select( @stocks_list, selected: position.stock_id )
|
18
|
-
|
19
|
-
|
20
|
+
|
21
|
+
.field
|
22
|
+
%label long or short?
|
23
|
+
= f.select :long_or_short, options_for_select([nil, Iro::Strategy::LONG, Iro::Strategy::SHORT], selected: long_or_short )
|
24
|
+
|
25
|
+
%label Strategy
|
26
|
+
= f.select :strategy_id, options_for_select( @strategies_list, selected: position.strategy_id )
|
20
27
|
|
21
28
|
.field
|
22
29
|
%label Expires on
|
23
|
-
= f.
|
30
|
+
= f.select :expires_on, options_for_select( Iro::Option.expirations_list, selected: position.expires_on )
|
24
31
|
%label Quantity
|
25
32
|
= f.text_field :quantity
|
26
33
|
|
@@ -1,46 +1,49 @@
|
|
1
1
|
.field
|
2
2
|
%label Begin on
|
3
|
-
= f.text_field :begin_on
|
3
|
+
= f.text_field :begin_on, value: position.begin_on || Time.now.to_date.to_s
|
4
4
|
|
5
5
|
.long-or-short-item
|
6
|
-
.d-flex
|
7
|
-
.field
|
8
|
-
%label Outer Strike
|
9
|
-
= f.number_field :outer_strike, step: 0.01
|
10
|
-
.field
|
11
|
-
%label Begin outer price
|
12
|
-
= f.text_field :begin_outer_price
|
13
|
-
.field
|
14
|
-
%label Begin outer delta
|
15
|
-
= f.text_field :begin_outer_delta
|
16
6
|
|
17
7
|
.d-flex
|
18
|
-
.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
8
|
+
= fields_for :outer, position.outer do |f_outer|
|
9
|
+
.field
|
10
|
+
%label Outer Strike
|
11
|
+
= f_outer.number_field :strike, step: 0.01
|
12
|
+
.field
|
13
|
+
%label Begin outer price
|
14
|
+
= f_outer.text_field :begin_price
|
15
|
+
.field
|
16
|
+
%label Begin outer delta
|
17
|
+
= f_outer.text_field :begin_delta
|
27
18
|
|
28
|
-
%br
|
29
|
-
.flex-row
|
30
|
-
%label End on
|
31
|
-
= f.text_field :end_on
|
32
|
-
.long-or-short-item
|
33
19
|
.d-flex
|
34
|
-
.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
20
|
+
= fields_for :inner, position.inner do |f_inner|
|
21
|
+
.field
|
22
|
+
%label Inner Strike
|
23
|
+
= f_inner.number_field :strike, step: 0.01
|
24
|
+
.field
|
25
|
+
%label Begin inner price
|
26
|
+
= f_inner.text_field :begin_price
|
27
|
+
.field
|
28
|
+
%label Begin inner delta
|
29
|
+
= f_inner.text_field :begin_delta
|
30
|
+
|
31
|
+
-# %br
|
32
|
+
-# .flex-row
|
33
|
+
-# %label End on
|
34
|
+
-# = f.text_field :end_on
|
35
|
+
-# .long-or-short-item
|
36
|
+
-# .d-flex
|
37
|
+
-# .field
|
38
|
+
-# %label End outer price
|
39
|
+
-# = f.text_field :end_outer_price
|
40
|
+
-# .field
|
41
|
+
-# %label End outer delta
|
42
|
+
-# = f.text_field :end_outer_delta
|
43
|
+
-# .d-flex
|
44
|
+
-# .field
|
45
|
+
-# %label End inner price
|
46
|
+
-# = f.text_field :end_inner_price
|
47
|
+
-# .field
|
48
|
+
-# %label End inner delta
|
49
|
+
-# = f.text_field :end_inner_delta
|
@@ -17,20 +17,20 @@
|
|
17
17
|
.label Last: #{pp_amount stock.last}
|
18
18
|
.c
|
19
19
|
|
20
|
-
- left = "#{ ( pos.
|
21
|
-
- width = "#{ ( pos.
|
20
|
+
- left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
|
21
|
+
- width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
|
22
22
|
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
23
23
|
.Position
|
24
24
|
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
25
25
|
.RollGuide
|
26
26
|
|
27
27
|
- if pos.net_amount >= 0
|
28
|
-
.Net.NetPositive{ style: "width: #{ (pos.net_amount
|
28
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
|
29
29
|
.label
|
30
30
|
net
|
31
31
|
= pp_amount pos.net_amount
|
32
32
|
- else
|
33
|
-
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount
|
33
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
|
34
34
|
.label
|
35
35
|
net
|
36
36
|
= pp_amount pos.net_amount
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
-##
|
3
|
+
-## same for long and short debit spreads
|
4
|
+
-##
|
5
|
+
|
6
|
+
- pos = position
|
7
|
+
- stock = pos.stock
|
8
|
+
- nearest_strike = stock.last.round
|
9
|
+
- u = pos.purse.unit # pixels per dollar
|
10
|
+
|
11
|
+
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
12
|
+
[<>]
|
13
|
+
.maxwidth= render "/iro/positions/header", pos: pos
|
14
|
+
.a
|
15
|
+
= render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
|
16
|
+
.StockCoordinatesW
|
17
|
+
.StockCoordinates{ style: "height: #{pos.q() *pos.purse.height}px " }
|
18
|
+
.grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
|
19
|
+
|
20
|
+
.Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
21
|
+
.label Last: #{pp_amount stock.last}
|
22
|
+
.c
|
23
|
+
|
24
|
+
- left = "#{ ( pos.outer.strike - stock.last ) * u}px"
|
25
|
+
- width = "#{ ( pos.inner.strike - pos.outer.strike ) * u}px"
|
26
|
+
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
27
|
+
.Position
|
28
|
+
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
29
|
+
.RollGuide
|
30
|
+
|
31
|
+
- if pos.net_amount >= 0
|
32
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount / 100) * u }px; right: 0" }
|
33
|
+
.label
|
34
|
+
net
|
35
|
+
= pp_amount pos.net_amount
|
36
|
+
- else
|
37
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount / 100) * u }px; left: 100%" }
|
38
|
+
.label
|
39
|
+
net
|
40
|
+
= pp_amount pos.net_amount
|
41
|
+
.c
|
42
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
- pos = position
|
3
|
+
- stock = pos.stock
|
4
|
+
- nearest_strike = stock.last.round
|
5
|
+
- u = pos.purse.unit # pixels per dollar
|
6
|
+
|
7
|
+
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
8
|
+
[<>]
|
9
|
+
.maxwidth= render "/iro/positions/header", pos: pos
|
10
|
+
.a
|
11
|
+
= render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
|
12
|
+
.StockCoordinatesW
|
13
|
+
.StockCoordinates{ style: "height: #{pos.q() *pos.purse.height}px " }
|
14
|
+
.grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
|
15
|
+
|
16
|
+
.Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
17
|
+
.label Last: #{pp_amount stock.last}
|
18
|
+
.c
|
19
|
+
|
20
|
+
- left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
|
21
|
+
- width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
|
22
|
+
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
23
|
+
.Position
|
24
|
+
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
25
|
+
.RollGuide
|
26
|
+
|
27
|
+
- if pos.net_amount >= 0
|
28
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
|
29
|
+
.label
|
30
|
+
net
|
31
|
+
= pp_amount pos.net_amount
|
32
|
+
- else
|
33
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
|
34
|
+
.label
|
35
|
+
net
|
36
|
+
= pp_amount pos.net_amount
|
37
|
+
.c
|
38
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
app/views/iro/positions/_gameui_long_debit_call_spread.haml
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
- pos = position
|
3
|
+
- stock = pos.stock
|
4
|
+
- nearest_strike = stock.last.round
|
5
|
+
- u = pos.purse.unit # pixels per dollar
|
6
|
+
|
7
|
+
|
8
|
+
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
9
|
+
[<>]
|
10
|
+
.maxwidth= render "/iro/positions/header", pos: pos
|
11
|
+
.a
|
12
|
+
= render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
|
13
|
+
.StockCoordinatesW
|
14
|
+
.StockCoordinates{ style: "height: #{pos.q() *u}px " }
|
15
|
+
.grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
|
16
|
+
|
17
|
+
.Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
18
|
+
.label Last: #{pp_amount stock.last}
|
19
|
+
.c
|
20
|
+
|
21
|
+
-## these are different
|
22
|
+
- left = "#{ ( stock.last - pos.outer.strike ) * u}px"
|
23
|
+
- width = "#{ ( pos.outer.strike - pos.inner.strike ) * u}px"
|
24
|
+
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
25
|
+
.Position
|
26
|
+
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
27
|
+
.RollGuide
|
28
|
+
|
29
|
+
- if pos.net_amount >= 0
|
30
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount / 100) * u }px; right: 0" }
|
31
|
+
.label
|
32
|
+
net
|
33
|
+
= pp_amount pos.net_amount
|
34
|
+
- else
|
35
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount / 100) * u }px; left: 100%" }
|
36
|
+
.label
|
37
|
+
net
|
38
|
+
= pp_amount pos.net_amount
|
39
|
+
.c
|
40
|
+
|