class Iro::Option

def self.expirations_list full: false, n: 5

def self.expirations_list full: false, n: 5
  out = [[nil,nil]]
  day = Date.today - 5.days
  n.times do
    next_exp = day.next_occurring(:thursday).next_occurring(:friday)
    if !next_exp.workday?
      next_exp = Time.previous_business_day( next_exp )
    end
    out.push([ next_exp.strftime('%b %e'), next_exp.strftime('%Y-%m-%d') ])
    day = next_exp
  end
  return out
  # [
  #   [ nil, nil ],
  #   [ 'Mar 22', '2024-03-22'.to_date ],
  #   [ 'Mar 28', '2024-03-28'.to_date ],
  #   [ 'Apr 5',  '2024-04-05'.to_date ],
  #   [ 'Mar 12', '2024-03-12'.to_date ],
  #   [ 'Mar 19', '2024-03-19'.to_date ],
  # ]
end

def self.max_pain hash

def self.max_pain hash
  outs = {}
  %w| put call |.each do |contractType|
    dates = hash["#{contractType}ExpDateMap"]
    dates.each do |_date, strikes| ## _date="2023-02-10:5"
      date = _date.split(':')[0].to_date.to_s
      outs[date] ||= {
        'all'  => {},
        'call' => {},
        'put'  => {},
        'summary' => {},
      }
      strikes.each do |_strike, _v| ## _strike="18.5"
        strike = _strike.to_f
        ## calls
        mem_c = 0
        strikes.keys.reverse.each do |_key|
          if _key == _strike
            break
          end
          key = _key.to_f
          tmp = hash["callExpDateMap"][_date][_key][0]['openInterest'] * ( key - strike )
          mem_c += tmp
        end
        outs[date]['call'][_strike] = mem_c
        ## puts
        mem_p = 0
        strikes.keys.each do |_key|
          if _key == _strike
            break
          end
          key = _key.to_f
          tmp = hash["putExpDateMap"][_date][_key][0]['openInterest'] * ( strike - key )
          mem_p += tmp
        end
        outs[date]['put'][_strike] = mem_p
        outs[date]['all'][_strike] = mem_c + mem_p
      end
    end
  end
  ## compute summary
  outs.each do |date, types|
    all = types['all']
    outs[date]['summary'] = { 'value' => all.keys[0] }
    all.each do |strike, amount|
      if amount < all[ outs[date]['summary']['value'] ]
        outs[date]['summary']['value'] = strike
      end
    end
  end
  return outs
end

def symbol

# for TDA
def symbol
  if !self[:symbol]
    p_c_ = put_call == 'PUT' ? 'P' : 'C'
    strike_ = strike.to_i == strike ? strike.to_i : strike
    sym = "#{stock.ticker}_#{expires_on.strftime("%m%d%y")}#{p_c_}#{strike_}" # XYZ_011819P45
    self[:symbol] = sym
    save
  end
  self[:symbol]
end

def sync

# do not sync in test
def sync
  out = Tda::Option.get_quote({
    contractType: put_call,
    strike: strike,
    expirationDate: expires_on,
    ticker: ticker,
  })
  puts! out, 'option sync'
  self.end_price = ( out.bid + out.ask ) / 2 rescue 0
  self.end_delta = out.delta if out.delta
  # self.save
end

def ticker; stock.ticker; end

def ticker; stock.ticker; end