Class: Iro::Position
- Inherits:
-
Object
- Object
- Iro::Position
- Includes:
- Mongoid::Document, Mongoid::Paranoia, Mongoid::Timestamps
- Defined in:
- app/models/iro/position.rb
Constant Summary collapse
- STATUS_ACTIVE =
'active'- STATUS_CLOSED =
'closed'- STATUS_PROPOSED =
'proposed'- STATUS_PENDING =
one more, ‘selected’ after proposed?
'pending'- STATUSES =
‘working’
[ nil, STATUS_CLOSED, STATUS_ACTIVE, STATUS_PROPOSED, STATUS_PENDING ]
Instance Attribute Summary collapse
-
#next_gain_loss_amount ⇒ Object
Returns the value of attribute next_gain_loss_amount.
Class Method Summary collapse
-
.long ⇒ Object
ok.
-
.short ⇒ Object
ok.
Instance Method Summary collapse
- #begin_delta ⇒ Object
- #breakeven ⇒ Object
-
#calc_nxt ⇒ Object
@TODO: herehere 2024-05-09.
-
#calc_rollp ⇒ Object
should_roll?.
- #current_underlying_strike ⇒ Object
- #end_delta ⇒ Object
-
#inner ⇒ Object
Options.
-
#max_gain ⇒ Object
each.
-
#max_loss ⇒ Object
each.
-
#net_amount ⇒ Object
each.
- #net_percent ⇒ Object
-
#next_expires_on ⇒ Object
ok.
-
#next_reasons ⇒ Object
decisions.
-
#nxts ⇒ Object
there are many of these, for viewing on the ‘roll’ view.
- #prev_gain_loss_amount ⇒ Object
- #q ⇒ Object
- #refresh ⇒ Object
- #sync ⇒ Object
- #to_s ⇒ Object
Instance Attribute Details
#next_gain_loss_amount ⇒ Object
Returns the value of attribute next_gain_loss_amount.
9 10 11 |
# File 'app/models/iro/position.rb', line 9 def next_gain_loss_amount @next_gain_loss_amount end |
Class Method Details
Instance Method Details
#begin_delta ⇒ Object
72 73 74 |
# File 'app/models/iro/position.rb', line 72 def begin_delta strategy.send("begin_delta_#{strategy.kind}", self) end |
#breakeven ⇒ Object
79 80 81 |
# File 'app/models/iro/position.rb', line 79 def breakeven strategy.send("breakeven_#{strategy.kind}", self) end |
#calc_nxt ⇒ Object
@TODO: herehere 2024-05-09
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'app/models/iro/position.rb', line 142 def calc_nxt pos = self ## 7 days ahead - not configurable so far outs = Tda::Option.get_quotes({ contractType: pos.put_call, expirationDate: next_expires_on, ticker: ticker, }) outs_bk = outs.dup outs = outs.select do |out| out[:bidSize] + out[:askSize] > 0 end ## next_inner_strike outs = outs.select do |out| if Iro::Strategy::SHORT == pos.long_or_short out[:strikePrice] >= strategy.next_inner_strike elsif Iro::Strategy::LONG == pos.long_or_short out[:strikePrice] <= strategy.next_inner_strike else raise 'zz3 - this cannot happen' end end puts! outs[0][:strikePrice], 'after calc next_inner_strike' ## next_buffer_above_water outs = outs.select do |out| if Iro::Strategy::SHORT == pos.long_or_short out[:strikePrice] > strategy.next_buffer_above_water + strategy.stock.last elsif Iro::Strategy::LONG == pos.long_or_short out[:strikePrice] < strategy.stock.last - strategy.next_buffer_above_water else raise 'zz4 - this cannot happen' end end puts! outs[0][:strikePrice], 'after calc next_buffer_above_water' ## next_inner_delta outs = outs.select do |out| out_delta = out[:delta].abs rescue 0 out_delta >= strategy.next_inner_delta.abs end puts! outs[0][:strikePrice], 'after calc next_inner_delta' inner = outs[0] outs = outs.select do |out| out[:strikePrice] >= inner[:strikePrice].to_f + strategy.next_spread_amount end outer = outs[0] if inner && outer o_attrs = { expires_on: next_expires_on, put_call: pos.put_call, stock_id: pos.stock_id, } inner_ = Iro::Option.new(o_attrs.merge({ strike: inner[:strikePrice], begin_price: ( inner[:bid] + inner[:ask] )/2, begin_delta: inner[:delta], end_price: ( inner[:bid] + inner[:ask] )/2, end_delta: inner[:delta], })) outer_ = Iro::Option.new(o_attrs.merge({ strike: outer[:strikePrice], begin_price: ( outer[:bid] + outer[:ask] )/2, begin_delta: outer[:delta], end_price: ( outer[:bid] + outer[:ask] )/2, end_delta: outer[:delta], })) pos.autonxt ||= Iro::Position.new pos.autonxt.update({ prev_gain_loss_amount: 'a', status: 'proposed', stock: strategy.stock, inner: inner_, outer: outer_, inner_strike: inner_.strike, outer_strike: outer_.strike, begin_on: Time.now.to_date, expires_on: next_expires_on, purse: purse, strategy: strategy, quantity: 1, autoprev: pos, }) pos.autonxt.sync pos.autonxt.save! pos.save return pos else throw 'zmq - should not happen' end end |
#calc_rollp ⇒ Object
should_roll?
129 130 131 132 133 134 135 136 137 138 139 |
# File 'app/models/iro/position.rb', line 129 def calc_rollp self.next_reasons = [] # self.next_symbol = nil # self.next_delta = nil out = strategy.send( "calc_rollp_#{strategy.kind}", self ) self.rollp = out[0] self.next_reasons.push out[1] save end |
#current_underlying_strike ⇒ Object
83 84 85 |
# File 'app/models/iro/position.rb', line 83 def Iro::Stock.find_by( ticker: ticker ).last end |
#end_delta ⇒ Object
75 76 77 |
# File 'app/models/iro/position.rb', line 75 def end_delta strategy.send("end_delta_#{strategy.kind}", self) end |
#inner ⇒ Object
Options
47 |
# File 'app/models/iro/position.rb', line 47 belongs_to :inner, class_name: 'Iro::Option', inverse_of: :inner |
#max_gain ⇒ Object
each
107 108 109 |
# File 'app/models/iro/position.rb', line 107 def max_gain # each strategy.send("max_gain_#{strategy.kind}", self) end |
#max_loss ⇒ Object
each
110 111 112 |
# File 'app/models/iro/position.rb', line 110 def max_loss # each strategy.send("max_loss_#{strategy.kind}", self) end |
#net_amount ⇒ Object
each
104 105 106 |
# File 'app/models/iro/position.rb', line 104 def net_amount # each strategy.send("net_amount_#{strategy.kind}", self) end |
#net_percent ⇒ Object
101 102 103 |
# File 'app/models/iro/position.rb', line 101 def net_percent net_amount / max_gain end |
#next_expires_on ⇒ Object
ok
244 245 246 247 248 249 250 |
# File 'app/models/iro/position.rb', line 244 def next_expires_on out = expires_on.to_datetime.next_occurring(:monday).next_occurring(:friday) if !out.workday? out = Time.previous_business_day(out) end return out end |
#next_reasons ⇒ Object
decisions
125 |
# File 'app/models/iro/position.rb', line 125 field :next_reasons, type: :array, default: [] |
#nxts ⇒ Object
there are many of these, for viewing on the ‘roll’ view
42 |
# File 'app/models/iro/position.rb', line 42 has_many :nxts, class_name: 'Iro::Position', inverse_of: :prev |
#prev_gain_loss_amount ⇒ Object
10 11 12 13 |
# File 'app/models/iro/position.rb', line 10 def prev_gain_loss_amount out = autoprev.outer.end_price - autoprev.inner.end_price out += inner.begin_price - outer.begin_price end |
#q ⇒ Object
66 |
# File 'app/models/iro/position.rb', line 66 def q; quantity; end |
#refresh ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'app/models/iro/position.rb', line 87 def refresh out = Tda::Option.get_quote({ contractType: 'CALL', strike: strike, expirationDate: expires_on, ticker: ticker, }) update({ end_delta: out[:delta], end_price: out[:last], }) print '^' end |
#sync ⇒ Object
115 116 117 118 |
# File 'app/models/iro/position.rb', line 115 def sync inner.sync outer.sync end |
#to_s ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'app/models/iro/position.rb', line 262 def to_s out = "#{stock} (#{q}) #{expires_on.to_datetime.strftime('%b %d')} #{strategy.long_or_short} [" if Iro::Strategy::LONG == long_or_short if outer.strike out = out + "$#{outer.strike}->" end out = out + "$#{inner.strike}" else out = out + "$#{inner.strike}" if outer.strike out = out + "<-$#{outer.strike}" end end out += "] " return out end |