app/models/iro/position.rb in iron_warbler-2.0.7.26 vs app/models/iro/position.rb in iron_warbler-2.0.7.27

- old
+ new

@@ -10,15 +10,17 @@ def prev_gain_loss_amount out = autoprev.outer.end_price - autoprev.inner.end_price out += inner.begin_price - outer.begin_price end + STATUS_ACTIVE = 'active' - STATUS_PROPOSED = 'proposed' STATUS_CLOSED = 'closed' - STATUS_PENDING = 'pending' - STATUSES = [ nil, STATUS_ACTIVE, STATUS_PROPOSED, STATUS_CLOSED, STATUS_PENDING ] + STATUS_PROPOSED = 'proposed' + ## one more, 'selected' after proposed? + STATUS_PENDING = 'pending' ## 'working' + STATUSES = [ nil, STATUS_CLOSED, STATUS_ACTIVE, STATUS_PROPOSED, STATUS_PENDING ] field :status validates :status, presence: true scope :active, ->{ where( status: 'active' ) } belongs_to :purse, class_name: 'Iro::Purse', inverse_of: :positions @@ -26,33 +28,30 @@ belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :positions delegate :ticker, to: :stock belongs_to :strategy, class_name: 'Iro::Strategy', inverse_of: :positions - field :long_or_short + delegate :put_call, to: :strategy + delegate :long_or_short, to: :strategy - def put_call - case strategy.kind - when Iro::Strategy::KIND_LONG_DEBIT_CALL_SPREAD - put_call = 'CALL' - when Iro::Strategy::KIND_SHORT_DEBIT_PUT_SPREAD - put_call = 'PUT' - when Iro::Strategy::KIND_COVERED_CALL - put_call = 'CALL' - end - end + belongs_to :next_strategy, class_name: 'Iro::Strategy', inverse_of: :next_position, optional: true - belongs_to :prev, class_name: 'Iro::Position', inverse_of: :nxt, optional: true + + belongs_to :prev, class_name: 'Iro::Position', inverse_of: :nxts, optional: true belongs_to :autoprev, class_name: 'Iro::Position', inverse_of: :autonxt, optional: true ## there are many of these, for viewing on the 'roll' view - has_many :nxt, class_name: 'Iro::Position', inverse_of: :prev + has_many :nxts, class_name: 'Iro::Position', inverse_of: :prev has_one :autonxt, class_name: 'Iro::Position', inverse_of: :autoprev ## Options belongs_to :inner, class_name: 'Iro::Option', inverse_of: :inner + validates_associated :inner + belongs_to :outer, class_name: 'Iro::Option', inverse_of: :outer + validates_associated :outer + accepts_nested_attributes_for :inner, :outer field :outer_strike, type: :float # validates :outer_strike, presence: true @@ -137,10 +136,11 @@ self.rollp = out[0] self.next_reasons.push out[1] save end + ## @TODO: herehere 2024-05-09 def calc_nxt pos = self ## 7 days ahead - not configurable so far outs = Tda::Option.get_quotes({ @@ -148,95 +148,93 @@ expirationDate: next_expires_on, ticker: ticker, }) outs_bk = outs.dup - # byebug - - ## strike price outs = outs.select do |out| - out[:bidSize]+out[:askSize] > 0 + 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_buffer_above_water + strategy.stock.last + out[:strikePrice] >= strategy.next_inner_strike elsif Iro::Strategy::LONG == pos.long_or_short - out[:strikePrice] < strategy.stock.last - strategy.next_buffer_above_water + out[:strikePrice] <= strategy.next_inner_strike else - throw 'zz4 - this cannot happen' + raise 'zz3 - this cannot happen' end end - puts! outs[0][:strikePrice], 'after calc next_buffer_above_water' + 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_inner_strike + out[:strikePrice] > strategy.next_buffer_above_water + strategy.stock.last elsif Iro::Strategy::LONG == pos.long_or_short - out[:strikePrice] < strategy.next_inner_strike + out[:strikePrice] < strategy.stock.last - strategy.next_buffer_above_water else - throw 'zz3 - this cannot happen' + raise 'zz4 - this cannot happen' end end - puts! outs[0][:strikePrice], 'after calc next_inner_strike' + puts! outs[0][:strikePrice], 'after calc next_buffer_above_water' - ## delta + ## next_inner_delta outs = outs.select do |out| - out_delta = out[:delta].abs rescue 0 + 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] - # byebug - 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], + 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], + 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_, + 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, + begin_on: Time.now.to_date, + expires_on: next_expires_on, + purse: purse, + strategy: strategy, + quantity: 1, + autoprev: pos, }) - # byebug + pos.autonxt.sync + pos.autonxt.save! + pos.save + return pos - autonxt.sync - autonxt.save! - else throw 'zmq - should not happen' end end @@ -244,11 +242,11 @@ ## ok def next_expires_on out = expires_on.to_datetime.next_occurring(:monday).next_occurring(:friday) if !out.workday? - out = Time.previous_business_day(out ) + out = Time.previous_business_day(out) end return out end ## ok @@ -260,10 +258,10 @@ def self.short where( long_or_short: Iro::Strategy::SHORT ) end def to_s - out = "#{stock} (#{q}) #{expires_on.to_datetime.strftime('%b %d')} #{strategy.kind_short} [" + 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}"