iron_warbler 2.0.7.43 → 2.0.7.45
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/utils.scss +9 -9
- data/app/controllers/iro/positions_controller.rb +1 -0
- data/app/controllers/iro/purses_controller.rb +3 -1
- data/app/controllers/iro/strategies_controller.rb +8 -3
- data/app/views/iro/positions/_form.haml +1 -1
- data/app/views/iro/positions/{_gameui_long_debit_call_spread.haml-trash → _gameui_spread.haml} +9 -8
- data/app/views/iro/positions/_header_spread.haml +12 -0
- data/app/views/iro/positions/_new.haml +4 -0
- data/app/views/iro/positions/done/_gameui_short_debit_put_spread.haml +1 -0
- data/app/views/iro/positions/done/_header_short_debit_put_spread.haml +1 -0
- data/app/views/iro/purses/_form.haml +3 -3
- data/app/views/iro/purses/index.haml +3 -2
- data/app/views/iro/strategies/_form_spread.haml +69 -0
- data/app/views/iro/strategies/{_form.haml → _form_wheel.haml} +12 -12
- data/app/views/iro/strategies/_header.haml +2 -1
- data/app/views/iro/strategies/_table.haml +3 -5
- data/app/views/iro/strategies/edit.haml +1 -1
- data/app/views/iro/strategies/index.haml +2 -1
- data/app/views/iro/strategies/new.haml +1 -1
- data/app/views/layouts/iro/application.haml +1 -1
- data/config/routes.rb +2 -0
- data/lib/iron_warbler.rb +2 -1
- data/lib/tasks/iro_tasks.rake +6 -0
- metadata +20 -30
- data/app/models/iro/alert.rb +0 -63
- data/app/models/iro/datapoint.rb +0 -187
- data/app/models/iro/date.rb +0 -10
- data/app/models/iro/option.rb +0 -151
- data/app/models/iro/option_black_scholes.rb +0 -149
- data/app/models/iro/position.rb +0 -299
- data/app/models/iro/priceitem.rb +0 -93
- data/app/models/iro/purse.rb +0 -72
- data/app/models/iro/stock.rb +0 -134
- data/app/models/iro/strategy.rb +0 -264
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -1
- data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +0 -40
- data/app/views/iro/positions/_header_short_debit_put_spread.haml +0 -1
- data/app/views/iro/positions/roll.haml-trash +0 -42
- /data/app/views/iro/positions/{_gameui_covered_call.haml-bk → done/_gameui_covered_call.haml-bk} +0 -0
- /data/app/views/iro/positions/{_gameui_long_credit_put_spread.haml → done/_gameui_long_credit_put_spread.haml} +0 -0
- /data/app/views/iro/positions/{_gameui_long_debit_call_spread.haml → done/_gameui_long_debit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{_gameui_short_credit_call_spread.haml → done/_gameui_short_credit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{_header_long_credit_put_spread.haml → done/_header_long_credit_put_spread.haml} +0 -0
- /data/app/views/iro/positions/{_header_long_debit_call_spread.haml → done/_header_long_debit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{_header_short_credit_call_spread.haml → done/_header_short_credit_call_spread.haml} +0 -0
- /data/app/views/iro/positions/{roll-cc.haml-bk → done/roll-cc.haml-bk} +0 -0
- /data/app/views/iro/purses/{gameui.haml-bk → done/gameui.haml-bk} +0 -0
- /data/app/views/iro/purses/{gameui.haml-bk2 → done/gameui.haml-bk2} +0 -0
- /data/app/views/iro/stocks/{_grid_is_long.haml → _grid_long.haml} +0 -0
- /data/app/views/iro/stocks/{_grid_is_short.haml → _grid_short.haml} +0 -0
data/app/models/iro/strategy.rb
DELETED
@@ -1,264 +0,0 @@
|
|
1
|
-
|
2
|
-
class Iro::Strategy
|
3
|
-
include Mongoid::Document
|
4
|
-
include Mongoid::Timestamps
|
5
|
-
include Mongoid::Paranoia
|
6
|
-
store_in collection: 'iro_strategies'
|
7
|
-
|
8
|
-
field :slug
|
9
|
-
validates :slug, presence: true, uniqueness: true
|
10
|
-
|
11
|
-
field :description
|
12
|
-
|
13
|
-
LONG = 'is_long'
|
14
|
-
SHORT = 'is_short'
|
15
|
-
field :long_or_short, type: :string
|
16
|
-
validates :long_or_short, presence: true
|
17
|
-
|
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
|
21
|
-
belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
|
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'
|
30
|
-
KINDS = [ nil,
|
31
|
-
KIND_COVERED_CALL,
|
32
|
-
KIND_IRON_CONDOR,
|
33
|
-
KIND_LONG_CREDIT_PUT_SPREAD,
|
34
|
-
KIND_LONG_DEBIT_CALL_SPREAD,
|
35
|
-
KIND_SHORT_CREDIT_CALL_SPREAD,
|
36
|
-
KIND_SHORT_DEBIT_PUT_SPREAD,
|
37
|
-
];
|
38
|
-
field :kind
|
39
|
-
|
40
|
-
def put_call
|
41
|
-
case kind
|
42
|
-
when Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD
|
43
|
-
put_call = 'PUT'
|
44
|
-
when Iro::Strategy::KIND_LONG_DEBIT_CALL_SPREAD
|
45
|
-
put_call = 'CALL'
|
46
|
-
when Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD
|
47
|
-
put_call = 'CALL'
|
48
|
-
when Iro::Strategy::KIND_SHORT_DEBIT_PUT_SPREAD
|
49
|
-
put_call = 'PUT'
|
50
|
-
when Iro::Strategy::KIND_COVERED_CALL
|
51
|
-
put_call = 'CALL'
|
52
|
-
else
|
53
|
-
throw 'zz9 - this should never happen'
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
field :threshold_buffer_above_water, type: :float
|
58
|
-
field :threshold_delta, type: :float
|
59
|
-
field :threshold_netp, type: :float
|
60
|
-
field :threshold_dte, type: :integer, default: 1
|
61
|
-
|
62
|
-
field :next_inner_delta, type: :float
|
63
|
-
field :next_inner_strike, type: :float
|
64
|
-
field :next_outer_delta, type: :float
|
65
|
-
field :next_outer_strike, type: :float
|
66
|
-
field :next_spread_amount, type: :float # e.g. $20 for a $2000 NVDA spread
|
67
|
-
field :next_buffer_above_water, type: :float
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
def begin_delta_covered_call p
|
75
|
-
p.inner.begin_delta
|
76
|
-
end
|
77
|
-
def begin_delta_long_credit_put_spread p
|
78
|
-
p.inner.begin_delta - p.outer.begin_delta
|
79
|
-
end
|
80
|
-
def begin_delta_long_debit_call_spread p
|
81
|
-
p.outer.begin_delta - p.inner.begin_delta
|
82
|
-
end
|
83
|
-
alias_method :begin_delta_short_debit_put_spread, :begin_delta_long_debit_call_spread
|
84
|
-
alias_method :begin_delta_short_credit_call_spread, :begin_delta_long_debit_call_spread
|
85
|
-
|
86
|
-
|
87
|
-
def breakeven_covered_call p
|
88
|
-
p.inner.strike + p.inner.begin_price
|
89
|
-
end
|
90
|
-
def breakeven_long_debit_call_spread p
|
91
|
-
p.inner.strike - p.max_gain
|
92
|
-
end
|
93
|
-
alias_method :breakeven_short_debit_put_spread, :breakeven_long_debit_call_spread
|
94
|
-
|
95
|
-
|
96
|
-
def end_delta_covered_call p
|
97
|
-
p.inner.end_delta
|
98
|
-
end
|
99
|
-
def end_delta_long_credit_put_spread p
|
100
|
-
p.inner.end_delta - p.outer.end_delta
|
101
|
-
end
|
102
|
-
def end_delta_long_debit_call_spread p
|
103
|
-
p.outer.end_delta - p.inner.end_delta
|
104
|
-
end
|
105
|
-
alias_method :end_delta_short_debit_put_spread, :end_delta_long_debit_call_spread
|
106
|
-
alias_method :end_delta_short_credit_call_spread, :end_delta_long_debit_call_spread
|
107
|
-
|
108
|
-
|
109
|
-
def max_gain_covered_call p
|
110
|
-
p.inner.begin_price * 100 - 0.66 # @TODO: is this *100 really?
|
111
|
-
end
|
112
|
-
def max_gain_long_credit_put_spread p
|
113
|
-
## 100 * disallowed for gameui
|
114
|
-
p.inner.begin_price - p.outer.begin_price
|
115
|
-
end
|
116
|
-
def max_gain_long_debit_call_spread p
|
117
|
-
## 100 * disallowed for gameui
|
118
|
-
( p.inner.strike - p.outer.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
|
119
|
-
end
|
120
|
-
def max_gain_short_credit_call_spread p
|
121
|
-
p.inner.begin_price - p.outer.begin_price
|
122
|
-
end
|
123
|
-
def max_gain_short_debit_put_spread p
|
124
|
-
## 100 * disallowed for gameui
|
125
|
-
( p.outer.strike - p.inner.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
def max_loss_covered_call p
|
130
|
-
p.inner.begin_price*10 # just suppose 10,000%
|
131
|
-
end
|
132
|
-
def max_loss_long_credit_put_spread p
|
133
|
-
out = p.inner.strike - p.outer.strike
|
134
|
-
end
|
135
|
-
def max_loss_long_debit_call_spread p
|
136
|
-
out = p.outer.strike - p.inner.strike
|
137
|
-
end
|
138
|
-
def max_loss_short_debit_put_spread p # different
|
139
|
-
out = p.inner.strike - p.outer.strike
|
140
|
-
end
|
141
|
-
def max_loss_short_credit_call_spread p
|
142
|
-
out = p.outer.strike - p.inner.strike
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
def net_amount_covered_call p
|
147
|
-
( p.inner.begin_price - p.inner.end_price )
|
148
|
-
end
|
149
|
-
def net_amount_long_debit_call_spread p
|
150
|
-
outer = p.outer.end_price - p.outer.begin_price
|
151
|
-
inner = p.inner.begin_price - p.inner.end_price
|
152
|
-
out = ( outer + inner )
|
153
|
-
end
|
154
|
-
alias_method :net_amount_long_credit_put_spread , :net_amount_long_debit_call_spread
|
155
|
-
alias_method :net_amount_short_credit_call_spread , :net_amount_long_debit_call_spread
|
156
|
-
alias_method :net_amount_short_debit_put_spread, :net_amount_long_debit_call_spread
|
157
|
-
|
158
|
-
|
159
|
-
## 2024-05-09 @TODO
|
160
|
-
def next_inner_strike_on expires_on
|
161
|
-
outs = Tda::Option.get_quotes({
|
162
|
-
contractType: put_call,
|
163
|
-
expirationDate: expires_on,
|
164
|
-
ticker: stock.ticker,
|
165
|
-
})
|
166
|
-
end
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
##
|
171
|
-
## decisions
|
172
|
-
##
|
173
|
-
|
174
|
-
def calc_rollp_covered_call p
|
175
|
-
|
176
|
-
if ( p.expires_on.to_date - Time.now.to_date ).to_i < 1
|
177
|
-
return [ 0.99, '0 DTE, must exit' ]
|
178
|
-
end
|
179
|
-
|
180
|
-
if ( stock.last - buffer_above_water ) < p.inner.strike
|
181
|
-
return [ 0.98, "Last #{'%.2f' % stock.last} is " +
|
182
|
-
"#{'%.2f' % [p.inner.strike + buffer_above_water - stock.last]} " +
|
183
|
-
"below #{'%.2f' % [p.inner.strike + buffer_above_water]} water" ]
|
184
|
-
end
|
185
|
-
|
186
|
-
if p.inner.end_delta < threshold_delta
|
187
|
-
return [ 0.61, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
|
188
|
-
end
|
189
|
-
|
190
|
-
if 1 - p.inner.end_price/p.inner.begin_price > threshold_netp
|
191
|
-
return [ 0.51, "made enough #{'%.02f' % [(1.0 - p.inner.end_price/p.inner.begin_price )*100]}% profit." ]
|
192
|
-
end
|
193
|
-
|
194
|
-
return [ 0.33, '-' ]
|
195
|
-
end
|
196
|
-
|
197
|
-
## @TODO
|
198
|
-
def calc_rollp_long_debit_call_spread p
|
199
|
-
|
200
|
-
if ( p.expires_on.to_date - Time.now.to_date ).to_i < 1
|
201
|
-
return [ 0.99, '0 DTE, must exit' ]
|
202
|
-
end
|
203
|
-
if ( p.expires_on.to_date - Time.now.to_date ).to_i < 2
|
204
|
-
return [ 0.99, '1 DTE, must exit' ]
|
205
|
-
end
|
206
|
-
|
207
|
-
if ( stock.last - buffer_above_water ) < p.inner.strike
|
208
|
-
return [ 0.95, "Last #{'%.2f' % stock.last} is " +
|
209
|
-
"#{'%.2f' % [stock.last - p.inner.strike - buffer_above_water]} " +
|
210
|
-
"below #{'%.2f' % [p.inner.strike + buffer_above_water]} water" ]
|
211
|
-
end
|
212
|
-
|
213
|
-
if p.inner.end_delta < threshold_delta
|
214
|
-
return [ 0.79, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
|
215
|
-
end
|
216
|
-
|
217
|
-
if 1 - p.inner.end_price/p.inner.begin_price > threshold_netp
|
218
|
-
return [ 0.51, "made enough #{'%.02f' % [(1.0 - p.inner.end_price/p.inner.begin_price )*100]}% profit^" ]
|
219
|
-
end
|
220
|
-
|
221
|
-
return [ 0.33, '-' ]
|
222
|
-
end
|
223
|
-
|
224
|
-
## @TODO
|
225
|
-
def calc_rollp_short_debit_put_spread p
|
226
|
-
|
227
|
-
if ( p.expires_on.to_date - Time.now.to_date ).to_i <= min_dte
|
228
|
-
return [ 0.99, "< #{min_dte}DTE, must exit" ]
|
229
|
-
end
|
230
|
-
|
231
|
-
if stock.last + buffer_above_water > p.inner.strike
|
232
|
-
return [ 0.98, "Last #{'%.2f' % stock.last} is " +
|
233
|
-
"#{'%.2f' % [stock.last + buffer_above_water - p.inner.strike]} " +
|
234
|
-
"above #{'%.2f' % [p.inner.strike - buffer_above_water]} water" ]
|
235
|
-
end
|
236
|
-
|
237
|
-
if p.inner.end_delta.abs < threshold_delta.abs
|
238
|
-
return [ 0.79, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
|
239
|
-
end
|
240
|
-
|
241
|
-
if p.net_percent > threshold_netp
|
242
|
-
return [ 0.51, "made enough #{'%.0f' % [p.net_percent*100]}% > #{"%.2f" % [threshold_netp*100]}% profit," ]
|
243
|
-
end
|
244
|
-
|
245
|
-
return [ 0.33, '-' ]
|
246
|
-
end
|
247
|
-
|
248
|
-
|
249
|
-
## scopes
|
250
|
-
|
251
|
-
def self.for_ticker ticker
|
252
|
-
where( ticker: ticker )
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
def to_s
|
257
|
-
slug
|
258
|
-
end
|
259
|
-
def self.list long_or_short = nil
|
260
|
-
these = long_or_short ? where( long_or_short: long_or_short ) : all
|
261
|
-
[[nil,nil]] + these.map { |ttt| [ ttt, ttt.id ] }
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
@@ -1 +0,0 @@
|
|
1
|
-
app/views/iro/positions/_gameui_long_debit_call_spread.haml
|
@@ -1,40 +0,0 @@
|
|
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
|
-
|
@@ -1 +0,0 @@
|
|
1
|
-
app/views/iro/positions/_header_long_debit_call_spread.haml
|
@@ -1,42 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
-# .StockCoordinatesW
|
4
|
-
-# .StockCoordinates{ style: "height: #{pos.purse.height}px " }
|
5
|
-
|
6
|
-
-# .grid-mark.mark0
|
7
|
-
-# .label= nearest_strike
|
8
|
-
-# - (1...@n_dollars).each_with_index do |idx|
|
9
|
-
-# .grid-mark{ class: "mark#{idx}", style: "left: -#{idx * u}px" }
|
10
|
-
-# .label
|
11
|
-
-# = nearest_strike + idx
|
12
|
-
-# .grid-mark{ class: "mark-#{idx}", style: "left: #{idx * u}px" }
|
13
|
-
-# .label
|
14
|
-
-# = nearest_strike - idx
|
15
|
-
|
16
|
-
-# .Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
17
|
-
-# .label Last: #{pp_amount stock.last}
|
18
|
-
-# .c
|
19
|
-
|
20
|
-
-# - left = "#{ (stock.last - pos.inner_strike) * u}px"
|
21
|
-
-# - width = "0px"
|
22
|
-
-# .PositionW{ style: "left: #{left} ; width: #{width} " }
|
23
|
-
-# .Position
|
24
|
-
-# .PositionC
|
25
|
-
|
26
|
-
-# - if pos.net_amount >= 0
|
27
|
-
-# .Net.NetPositive{ style: "width: #{ (pos.net_amount / 100) * u }px; right: 0" }
|
28
|
-
-# .label
|
29
|
-
-# net
|
30
|
-
-# = pp_amount pos.net_amount
|
31
|
-
-# - else
|
32
|
-
-# .Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount / 100) * u }px; left: 100%" }
|
33
|
-
-# .label
|
34
|
-
-# net
|
35
|
-
-# = pp_amount pos.net_amount
|
36
|
-
|
37
|
-
-# .Breakeven{ style: "width: #{ pos.begin_inner_price * u }px" }
|
38
|
-
-# .label
|
39
|
-
-# Breakeven:
|
40
|
-
-# = pos.begin_inner_price
|
41
|
-
-# .c
|
42
|
-
|
/data/app/views/iro/positions/{_gameui_covered_call.haml-bk → done/_gameui_covered_call.haml-bk}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|