class Iro::Strategy

def self.for_ticker ticker

def self.for_ticker ticker
  where( ticker: ticker )
end

def self.list long_or_short = nil

def self.list long_or_short = nil
  these = long_or_short ? where( long_or_short: long_or_short ) : all
  [[nil,nil]] + these.map { |ttt| [ ttt, ttt.id ] }
end

def begin_delta_spread p

def begin_delta_spread p
  p.inner.begin_delta - p.outer.begin_delta
end

def begin_delta_wheel p

def begin_delta_wheel p
  p.inner.begin_delta
end

def breakeven_covered_call p

def breakeven_covered_call p
  p.inner.strike + p.inner.begin_price
end

def breakeven_long_debit_call_spread p

def breakeven_long_debit_call_spread p
  p.inner.strike - p.max_gain
end

def calc_rollp_covered_call p

def calc_rollp_covered_call p
  if ( p.expires_on.to_date - Time.now.to_date ).to_i < 1
    return [ 0.99, '0 DTE, must exit' ]
  end
  if ( stock.last - buffer_above_water ) < p.inner.strike
    return [ 0.98, "Last #{'%.2f' % stock.last} is " +
        "#{'%.2f' % [p.inner.strike + buffer_above_water - stock.last]} " +
        "below #{'%.2f' % [p.inner.strike + buffer_above_water]} water" ]
  end
  if p.inner.end_delta < threshold_delta
    return [ 0.61, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
  end
  if 1 - p.inner.end_price/p.inner.begin_price > threshold_netp
    return [ 0.51, "made enough #{'%.02f' % [(1.0 - p.inner.end_price/p.inner.begin_price )*100]}% profit." ]
  end
  return [ 0.33, '-' ]
end

def calc_rollp_long_debit_call_spread p

# @TODO
def calc_rollp_long_debit_call_spread p
  if ( p.expires_on.to_date - Time.now.to_date ).to_i < 1
    return [ 0.99, '0 DTE, must exit' ]
  end
  if ( p.expires_on.to_date - Time.now.to_date ).to_i < 2
    return [ 0.99, '1 DTE, must exit' ]
  end
  if ( stock.last - buffer_above_water ) < p.inner.strike
    return [ 0.95, "Last #{'%.2f' % stock.last} is " +
        "#{'%.2f' % [stock.last - p.inner.strike - buffer_above_water]} " +
        "below #{'%.2f' % [p.inner.strike + buffer_above_water]} water" ]
  end
  if p.inner.end_delta < threshold_delta
    return [ 0.79, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
  end
  if 1 - p.inner.end_price/p.inner.begin_price > threshold_netp
    return [ 0.51, "made enough #{'%.02f' % [(1.0 - p.inner.end_price/p.inner.begin_price )*100]}% profit^" ]
  end
  return [ 0.33, '-' ]
end

def calc_rollp_short_debit_put_spread p

# @TODO
def calc_rollp_short_debit_put_spread p
  if ( p.expires_on.to_date - Time.now.to_date ).to_i <= min_dte
    return [ 0.99, "< #{min_dte}DTE, must exit" ]
  end
  if stock.last + buffer_above_water > p.inner.strike
    return [ 0.98, "Last #{'%.2f' % stock.last} is " +
        "#{'%.2f' % [stock.last + buffer_above_water - p.inner.strike]} " +
        "above #{'%.2f' % [p.inner.strike - buffer_above_water]} water" ]
  end
  if p.inner.end_delta.abs < threshold_delta.abs
    return [ 0.79, "Delta #{p.inner.end_delta} is lower than #{threshold_delta} threshold." ]
  end
  if p.net_percent > threshold_netp
    return [ 0.51, "made enough #{'%.0f' % [p.net_percent*100]}% > #{"%.2f" % [threshold_netp*100]}% profit," ]
  end
  return [ 0.33, '-' ]
end

def end_delta_spread p

def end_delta_spread p
  p.inner.end_delta - p.outer.end_delta
end

def end_delta_wheel p

def end_delta_wheel p
  p.inner.end_delta
end

def max_gain_spread p

end
( p.outer.strike - p.inner.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
## 100 * disallowed for gameui
def max_gain_short_debit_put_spread p
end
p.inner.begin_price - p.outer.begin_price
def max_gain_short_credit_call_spread p
end
( p.inner.strike - p.outer.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
## 100 * disallowed for gameui
def max_gain_long_debit_call_spread p
end
p.inner.begin_price - p.outer.begin_price
## 100 * disallowed for gameui
# def max_gain_long_credit_put_spread p
end
p.inner.begin_price * 100 - 0.66 # @TODO: is this *100 really?
def max_gain_covered_call p
def max_gain_spread p
  ## 100 * disallowed for gameui
  ( p.outer.strike - p.inner.strike ).abs - p.outer.begin_price + p.inner.begin_price # - 2*0.66
end

def max_gain_wheel p

def max_gain_wheel p
  p.inner.begin_price * 100 - 0.66 # @TODO: is this *100 really?
end

def max_loss_spread p

end
out = p.outer.strike - p.inner.strike
def max_loss_short_credit_call_spread p
end
out = p.inner.strike - p.outer.strike
def max_loss_short_debit_put_spread p # different
end
out = p.outer.strike - p.inner.strike
def max_loss_long_debit_call_spread p
end
out = p.inner.strike - p.outer.strike
def max_loss_long_credit_put_spread p
end
p.inner.begin_price*10 # just suppose 10,000%
def max_loss_covered_call p
def max_loss_spread p
  ( p.outer.strike - p.inner.strike ).abs
end

def max_loss_wheel p

def max_loss_wheel p
  p.inner.begin_price*10 # just suppose 10,000%
end

def net_amount_spread p

def net_amount_spread p
  p.inner.begin_price - p.inner.end_price
end

def next_inner_strike_on expires_on

# 2024-05-09 @TODO
def next_inner_strike_on expires_on
  outs = Tda::Option.get_quotes({
    contractType: put_call,
    expirationDate: expires_on,
    ticker: stock.ticker,
  })
end

def put_call

def put_call
  case kind
  # when Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD
  #   put_call = 'PUT'
  # when Iro::Strategy::KIND_LONG_DEBIT_CALL_SPREAD
  #   put_call = 'CALL'
  # when Iro::Strategy::KIND_SHORT_CREDIT_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'
  when Iro::Strategy::KIND_SPREAD
    if credit_or_debit == CREDIT
      if long_or_short == LONG
        'PUT'
      elsif long_or_short == SHORT
        'CALL'
      else
        throw 'zz5 - should never happen'
      end
    else
      throw 'zz6 - debit spreads are not implemented'
    end
  when Iro::Strategy::KIND_WHEEL
    'CALL'
  else
    throw 'zz9 - this should never happen'
  end
end

def slug

def slug
  "#{long_or_short} #{credit_or_debit} #{kind} #{stock}"
end

def to_s

def to_s
  slug
end