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.
Files changed (59) 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.scss +31 -0
  5. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
  6. data/app/assets/stylesheets/iron_warbler/utils.scss +28 -3
  7. data/app/controllers/iro/api/stocks_controller.rb +7 -4
  8. data/app/controllers/iro/application_controller.rb +6 -0
  9. data/app/controllers/iro/positions_controller.rb +188 -199
  10. data/app/controllers/iro/purses_controller.rb +3 -1
  11. data/app/controllers/iro/stocks_controller.rb +21 -2
  12. data/app/models/iro/datapoint.rb +1 -1
  13. data/app/models/iro/option.rb +50 -150
  14. data/app/models/iro/option_black_scholes.rb +149 -0
  15. data/app/models/iro/position.rb +155 -212
  16. data/app/models/iro/{price_item.rb → priceitem.rb} +5 -1
  17. data/app/models/iro/purse.rb +41 -4
  18. data/app/models/iro/stock.rb +2 -0
  19. data/app/models/iro/strategy.rb +121 -82
  20. data/app/models/tda/option.rb +1 -1
  21. data/app/models/tda/stock.rb +1 -1
  22. data/app/views/iro/_main_header.haml +8 -5
  23. data/app/views/iro/api/stocks/index.json.jbuilder +5 -0
  24. data/app/views/iro/api/stocks/show.json.jbuilder +11 -0
  25. data/app/views/iro/api/stocks/show.json.jbuilder-bk +12 -0
  26. data/app/views/iro/options/_show_mini.haml +8 -0
  27. data/app/views/iro/positions/_form.haml +11 -4
  28. data/app/views/iro/positions/_formpart_4data.haml +41 -38
  29. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +4 -4
  30. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
  31. data/app/views/iro/positions/_gameui_short_credit_call_spread.haml +38 -0
  32. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
  33. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
  34. data/app/views/iro/positions/_header.haml +2 -0
  35. data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
  36. data/app/views/iro/positions/_header_short_credit_call_spread.haml +50 -0
  37. data/app/views/iro/positions/_new.haml +23 -0
  38. data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +2 -3
  39. data/app/views/iro/positions/_prepare_short_credit_call_spread.haml +1 -0
  40. data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
  41. data/app/views/iro/positions/_table.haml +25 -26
  42. data/app/views/iro/positions/prepare.haml +6 -4
  43. data/app/views/iro/positions/prepare2.haml +15 -4
  44. data/app/views/iro/purses/_form_extra_fields.haml +18 -18
  45. data/app/views/iro/purses/_header.haml +12 -7
  46. data/app/views/iro/purses/_summary.haml +69 -62
  47. data/app/views/iro/purses/show.haml +4 -3
  48. data/app/views/iro/stocks/_form.haml +4 -3
  49. data/app/views/iro/stocks/edit.haml +4 -0
  50. data/app/views/iro/stocks/index.haml +21 -6
  51. data/app/views/iro/strategies/_form.haml +36 -26
  52. data/app/views/iro/strategies/_show.haml +7 -5
  53. data/config/routes.rb +7 -4
  54. data/lib/iro/engine.rb +1 -0
  55. data/lib/iron_warbler.rb +0 -2
  56. data/lib/tasks/iro_tasks.rake +2 -2
  57. metadata +17 -4
  58. data/app/views/iro/api/stocks/show.jbuilder +0 -11
  59. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -40
@@ -8,111 +8,144 @@ class Iro::Strategy
8
8
  field :slug
9
9
  validates :slug, presence: true, uniqueness: true
10
10
 
11
- LONG = 'is_long'
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
- KIND_COVERED_CALL = 'covered_call'
23
- KIND_LONG_DEBIT_CALL_SPREAD = 'long_debit_call_spread'
24
- KIND_SHORT_DEBIT_PUT_SPREAD = 'short_debit_put_spread'
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 kind_short
40
+ def put_call
33
41
  case kind
34
- when KIND_COVERED_CALL
35
- 'cc'
36
- when KIND_LONG_DEBIT_CALL_SPREAD
37
- 'long-spread'
38
- when KIND_SHORT_DEBIT_PUT_SPREAD
39
- 'short-spread'
40
- else
41
- '@TODO-zez'
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 :buffer_above_water, type: :float
46
- field :threshold_delta, type: :float
47
- field :threshold_netp, type: :float
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, type: :float
50
- field :next_outer_delta, type: :float
51
- field :next_inner_strike, type: :float
52
- field :next_outer_strike, type: :float
53
- field :next_spread_amount, type: :float # e.g. $20 for a $2000 NVDA spread
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
- def self.for_ticker ticker
57
- where( ticker: ticker )
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.inner_strike + p.begin_inner_price
81
+ p.inner.strike + p.inner.begin_price
62
82
  end
63
83
  def breakeven_long_debit_call_spread p
64
- p.inner_strike - p.max_gain # p.begin_outer_price + p.begin_inner_price
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
- # return p.begin_inner_price
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 * disalloed for gameui
74
- ( p.inner_strike - p.outer_strike - p.begin_outer_price + p.begin_inner_price ) # - 2*0.66
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 * disalloed for gameui
78
- ( p.outer_strike - p.inner_strike - p.begin_outer_price + p.begin_inner_price ) # - 2*0.66
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.begin_inner_price*10 # just suppose 10,000%
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.outer_strike - p.inner_strike
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.inner_strike - p.outer_strike
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
- def begin_delta_covered_call p
102
- p.begin_inner_delta
128
+
129
+ def net_amount_covered_call p
130
+ ( p.inner.begin_price - p.inner.end_price )
103
131
  end
104
- def begin_delta_long_debit_call_spread p
105
- p.begin_outer_delta - p.begin_inner_delta
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 :begin_delta_short_debit_put_spread, :begin_delta_long_debit_call_spread
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
- def end_delta_covered_call p
110
- p.end_inner_delta
111
- end
112
- def end_delta_long_debit_call_spread p
113
- p.end_outer_delta - p.end_inner_delta
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.inner_strike
162
+ if ( stock.last - buffer_above_water ) < p.inner.strike
130
163
  return [ 0.98, "Last #{'%.2f' % stock.last} is " +
131
- "#{'%.2f' % [p.inner_strike + buffer_above_water - stock.last]} " +
132
- "below #{'%.2f' % [p.inner_strike + buffer_above_water]} water" ]
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.end_inner_delta < threshold_delta
136
- return [ 0.61, "Delta #{p.end_inner_delta} is lower than #{threshold_delta} threshold." ]
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.end_inner_price/p.begin_inner_price > threshold_netp
140
- return [ 0.51, "made enough #{'%.0f' % [(1 - p.end_inner_price/p.begin_inner_price )*100]}% profit" ]
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.inner_strike
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.inner_strike - buffer_above_water]} " +
159
- "below #{'%.2f' % [p.inner_strike + buffer_above_water]} water" ]
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.end_inner_delta < threshold_delta
163
- return [ 0.79, "Delta #{p.end_inner_delta} is lower than #{threshold_delta} threshold." ]
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.end_inner_price/p.begin_inner_price > threshold_netp
167
- return [ 0.51, "made enough #{'%.0f' % [(1 - p.end_inner_price/p.begin_inner_price )*100]}% profit" ]
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 < 1
177
- return [ 0.99, '0 DTE, must exit' ]
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 ( stock.last - buffer_above_water ) < p.inner_strike
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.inner_strike - buffer_above_water]} " +
183
- "above #{'%.2f' % [p.inner_strike + buffer_above_water]} water" ]
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.end_inner_delta < threshold_delta
187
- return [ 0.79, "Delta #{p.end_inner_delta} is lower than #{threshold_delta} threshold." ]
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 1 - p.end_inner_price/p.begin_inner_price > threshold_netp
191
- return [ 0.51, "made enough #{'%.0f' % [(1 - p.end_inner_price/p.begin_inner_price )*100]}% profit" ]
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
- "#{stock} #{kind_short} #{slug}"
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
+
@@ -68,7 +68,7 @@ class Tda::Option
68
68
  ## 2023-02-06 _vp_ :: Continue.
69
69
  ##
70
70
  def self.get_quotes params
71
- # puts! params, 'Tda::Option#get_quotes'
71
+ puts! params, 'Tda::Option#get_quotes'
72
72
  opts = {}
73
73
 
74
74
  #
@@ -24,7 +24,7 @@ class Tda::Stock
24
24
  end
25
25
  outs = []
26
26
  inns.each do |symbol, obj|
27
- outs.push ::Iro::PriceItem.create!({
27
+ outs.push ::Iro::Priceitem.create!({
28
28
  putCall: 'STOCK',
29
29
  symbol: symbol,
30
30
  ticker: symbol,
@@ -4,12 +4,12 @@
4
4
 
5
5
  %i.fa.fa-compress.collapse-expand#collapseHeaderTrading
6
6
  Wco Trading
7
- .a
8
- .d-flex
9
- %ul{ style: "margin-top: 2em;" }
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 '[re]', refresh_stocks_path
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= link_to p, purse_path(p)
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,5 @@
1
+
2
+ json.stocks @stocks do |stock|
3
+ json.status stock.status
4
+ json.ticker stock.ticker
5
+ end
@@ -0,0 +1,11 @@
1
+
2
+ json.ticker @stock.ticker
3
+ json.last @stock.last
4
+
5
+ json.datapoints @datapoints do |p|
6
+ json.quote_at Time.at(p.quote_at).strftime('%Y-%m-%d')
7
+ # json.timestamp p.timestamp
8
+ json.value p.value
9
+ end
10
+
11
+
@@ -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
@@ -0,0 +1,8 @@
1
+
2
+ .options--show-mini
3
+ .Card
4
+ = opt.inspect
5
+ %ul
6
+ %li <b>strike:</b>
7
+ %li <b>begin_price:</b>
8
+ %li <b>begin_delta:</b>
@@ -1,5 +1,7 @@
1
1
 
2
- .positions--form{ class: params[:long_or_short] || position.strategy&.long_or_short }
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
- %label Strategy
19
- = f.select :strategy_id, options_for_select( @strategies_list, selected: position.strategy_id )
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.text_field :expires_on
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
- .field
19
- %label Inner Strike
20
- = f.number_field :inner_strike, step: 0.01
21
- .field
22
- %label Begin inner price
23
- = f.text_field :begin_inner_price
24
- .field
25
- %label Begin inner delta
26
- = f.text_field :begin_inner_delta
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
- .field
35
- %label End outer price
36
- = f.text_field :end_outer_price
37
- .field
38
- %label End outer delta
39
- = f.text_field :end_outer_delta
40
- .d-flex
41
- .field
42
- %label End inner price
43
- = f.text_field :end_inner_price
44
- .field
45
- %label End inner delta
46
- = f.text_field :end_inner_delta
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.outer_strike - stock.last ) * u}px"
21
- - width = "#{ ( pos.inner_strike - pos.outer_strike ) * u}px"
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 / 100) * u }px; right: 0" }
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 / 100) * u }px; left: 100%" }
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
+