class Iro::Position
def calc_nxt
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 if 'CALL' == pos.put_call ; elsif 'PUT' == pos.put_call outs = outs.reverse end ## next_inner_strike outs = outs.select do |out| if Iro::Strategy::CREDIT == pos.credit_or_debit if Iro::Strategy::SHORT == pos.long_or_short ## short credit call out[:strikePrice] >= strategy.next_inner_strike elsif Iro::Strategy::LONG == pos.long_or_short ## long credit put out[:strikePrice] <= strategy.next_inner_strike end else raise 'zz3 - @TODO: implement, debit spreads' end end puts! outs[0][:strikePrice], 'after calc next_inner_strike' puts! outs, 'outs' ## 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' puts! outs, 'outs' ## next_inner_delta outs = outs.select do |out| if 'CALL' == pos.put_call out_delta = out[:delta] rescue 1 out_delta <= strategy.next_inner_delta elsif 'PUT' == pos.put_call out_delta = out[:delta] rescue 0 out_delta <= strategy.next_inner_delta else raise 'zz5 - this cannot happen' end end puts! outs[0][:strikePrice], 'after calc next_inner_delta' puts! outs, 'outs' inner = outs[0] outs = outs.select do |out| if 'CALL' == pos.put_call out[:strikePrice] >= inner[:strikePrice].to_f + strategy.next_spread_amount elsif 'PUT' == pos.put_call out[:strikePrice] <= inner[:strikePrice].to_f - strategy.next_spread_amount end 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