app/models/iro/position.rb in iron_warbler-2.0.7.22 vs app/models/iro/position.rb in iron_warbler-2.0.7.23

- old
+ new

@@ -1,12 +1,13 @@ class Iro::Position include Mongoid::Document include Mongoid::Timestamps + include Mongoid::Paranoia store_in collection: 'iro_positions' - attr_accessor :gain_loss_amount + attr_accessor :next_gain_loss_amount STATUS_ACTIVE = 'active' STATUS_PROPOSED = 'proposed' STATUSES = [ nil, 'active', 'inactive', 'proposed' ] field :status @@ -51,12 +52,19 @@ field :end_outer_delta, type: :float field :end_inner_price, type: :float field :end_inner_delta, type: :float + def begin_delta + strategy.send("begin_delta_#{strategy.kind}", self) + end + def end_delta + strategy.send("end_delta_#{strategy.kind}", self) + end + def breakeven - strategy.breakeven(self) + strategy.send("breakeven_#{strategy.kind}", self) end def current_underlying_strike Iro::Stock.find_by( ticker: ticker ).last end @@ -85,82 +93,142 @@ strategy.send("max_gain_#{strategy.kind}", self) end def max_loss # each strategy.send("max_loss_#{strategy.kind}", self) end + # def gain_loss_amount + # strategy.send("gain_loss_amount_#{strategy.kind}", self) + # end field :next_delta, type: :float field :next_outcome, type: :float field :next_symbol field :next_mark field :next_reasons, type: :array, default: [] - field :should_rollp, type: :float + field :rollp, type: :float - ## - ## decisions - ## - def should_roll? - puts! 'shold_roll?' + ## covered call + # def sync + # puts! [ inner_strike, expires_on, stock.ticker ], 'init sync' + # out = Tda::Option.get_quote({ + # contractType: 'CALL', + # strike: inner_strike, + # expirationDate: expires_on, + # ticker: stock.ticker, + # }) + # puts! out, 'sync' + # self.end_inner_price = ( out.bid + out.ask ) / 2 + # self.end_inner_delta = out.delta + # end - update({ - next_reasons: [], - next_symbol: nil, - next_delta: nil, + ## long call spread + # def sync + # # puts! [ + # # [ inner_strike, expires_on, stock.ticker ], + # # [ outer_strike, expires_on, stock.ticker ], + # # ], 'init sync inner, outer' + # inner = Tda::Option.get_quote({ + # contractType: 'CALL', + # strike: inner_strike, + # expirationDate: expires_on, + # ticker: stock.ticker, + # }) + # outer = Tda::Option.get_quote({ + # contractType: 'CALL', + # strike: outer_strike, + # expirationDate: expires_on, + # ticker: stock.ticker, + # }) + # puts! [inner, outer], 'sync inner, outer' + # self.end_outer_price = ( outer.bid + outer.ask ) / 2 + # self.end_outer_delta = outer.delta + + # self.end_inner_price = ( inner.bid + inner.ask ) / 2 + # self.end_inner_delta = inner.delta + # end + + def sync + put_call = Iro::Strategy::LONG == strategy.long_or_short ? 'CALL' : 'PUT' + puts! [ + [ inner_strike, expires_on, stock.ticker ], + [ outer_strike, expires_on, stock.ticker ], + ], 'init sync inner, outer' + inner = Tda::Option.get_quote({ + contractType: put_call, + strike: inner_strike, + expirationDate: expires_on, + ticker: stock.ticker, }) + outer = Tda::Option.get_quote({ + contractType: put_call, + strike: outer_strike, + expirationDate: expires_on, + ticker: stock.ticker, + }) + puts! [inner, outer], 'sync inner, outer' + self.end_outer_price = ( outer.bid + outer.ask ) / 2 + self.end_outer_delta = outer.delta - if must_roll? - out = 1.0 - elsif can_roll? + self.end_inner_price = ( inner.bid + inner.ask ) / 2 + self.end_inner_delta = inner.delta + end + def sync_short_debit_put_spread + puts! [ + [ inner_strike, expires_on, stock.ticker ], + [ outer_strike, expires_on, stock.ticker ], + ], 'init sync inner, outer' + inner = Tda::Option.get_quote({ + contractType: 'PUT', + strike: inner_strike, + expirationDate: expires_on, + ticker: stock.ticker, + }) + outer = Tda::Option.get_quote({ + contractType: 'PUT', + strike: outer_strike, + expirationDate: expires_on, + ticker: stock.ticker, + }) + puts! [inner, outer], 'sync inner, outer' + self.end_outer_price = ( outer.bid + outer.ask ) / 2 + self.end_outer_delta = outer.delta - if end_delta < strategy.threshold_delta - next_reasons.push "delta is lower than threshold" - out = 0.91 - elsif 1 - end_outer_price/begin_outer_price > strategy.threshold_netp - next_reasons.push "made enough percent profit (dubious)" - out = 0.61 - else - next_reasons.push "neutral" - out = 0.33 - end + self.end_inner_price = ( inner.bid + inner.ask ) / 2 + self.end_inner_delta = inner.delta + end - else - out = 0.0 - end + ## + ## decisions + ## - update({ - next_delta: next_position[:delta], - next_outcome: next_position[:mark] - end_price, - next_symbol: next_position[:symbol], - next_mark: next_position[:mark], - should_rollp: out, - # status: Iro::Position::STATE_PROPOSED, - }) + def calc_rollp + self.next_reasons = [] + self.next_symbol = nil + self.next_delta = nil - puts! next_reasons, 'next_reasons' - puts! out, 'out' - return out > 0.5 + out = strategy.send( "calc_rollp_#{strategy.kind}", self ) + + self.rollp = out[0] + self.next_reasons.push out[1] + save + + # update({ + # next_delta: next_position[:delta], + # next_outcome: next_position[:mark] - end_price, + # next_symbol: next_position[:symbol], + # next_mark: next_position[:mark], + # should_rollp: out, + # # status: Iro::Position::STATE_PROPOSED, + # }) end ## expires_on = cc.expires_on ; nil def can_roll? ## only if less than 7 days left ( expires_on.to_date - Time.now.to_date ).to_i < 7 - end - - ## If I'm near below water - ## - ## expires_on = cc.expires_on ; strategy = cc.strategy ; strike = cc.strike ; nil - def must_roll? - if ( current_underlying_strike + strategy.buffer_above_water ) > strike - return true - end - ## @TODO: This one should not happen, I should log appropriately. _vp_ 2023-03-19 - if ( expires_on.to_date - Time.now.to_date ).to_i < 1 - return true - end end ## strike = cc.strike ; strategy = cc.strategy ; nil def near_below_water? strike < current_underlying_strike + strategy.buffer_above_water