"""Replay today's real maker session against the new rules.

Three rules were added after the live session lost money:
  ENTRY GATE  -- refuse a book whose three touches do not clear 1.00 + fees
  RATCHET     -- never re-quote a leg below where it was first offered
  BUDGET      -- once a leg fills, price the rest to clear the target

The question this answers is not "would we have made money" -- at n=3 that is
unanswerable -- but the more useful one: WHICH of today's fills would each rule
have prevented, and what would the completed books have collected instead.
"""
import csv, collections, sys
sys.path.insert(0, r'E:\soccer\main')
import mm_maker_live as ML

ORDERS = r'E:\soccer\research\mm_live_orders.csv'


def load_quotes():
    """{event: {leg: [prices in cents, in time order]}}"""
    books = collections.defaultdict(lambda: collections.defaultdict(list))
    with open(ORDERS, encoding='utf-8', errors='replace') as fh:
        for r in csv.DictReader(fh):
            t = r.get('ticker') or ''
            if '-' not in t:
                continue
            try:
                p = int(r.get('price_cents'))
            except (TypeError, ValueError):
                continue
            ev, leg = t.rsplit('-', 1)
            seq = books[ev][leg]
            if not seq or seq[-1] != p:
                seq.append(p)
    return books


# what actually filled today, from the exchange
FILLS = {
    'KXLALIGAGAME-26AUG15ALAGET': {'ALA': 40, 'TIE': 34, 'GET': 25},
    'KXARGPREMDIVGAME-26AUG15SLAUNI': {'UNI': 33, 'TIE': 32, 'SLA': 33},
    'KXEREDIVISIEGAME-26AUG15EXCPSV': {'EXC': 14, 'PSV': 68, 'TIE': 18},
}

books = load_quotes()
print('=== every book we quoted today ===')
print(f'{"book":34} {"entry sum":>9} {"gate":>6} {"chased":>7}')
gated = chased = 0
for ev, legs in sorted(books.items()):
    if len(legs) != 3:
        continue
    entry = {l: seq[0] for l, seq in legs.items()}
    esum = sum(entry.values())
    asks = {l: v / 100.0 for l, v in entry.items()}
    b = ML.book_budget(asks, {})
    g = 'REFUSE' if b['decision'] == 'gate' else 'take'
    dropped = {l: (seq[0], min(seq)) for l, seq in legs.items() if min(seq) < seq[0]}
    if b['decision'] == 'gate':
        gated += 1
    if dropped:
        chased += 1
    name = ev.replace('KXARGPREMDIVGAME', 'ARG').replace('KX', '')[:34]
    print(f'{name:34} {esum:>8}c {g:>6} '
          f'{("yes " + ",".join(f"{l} {a}->{b_}" for l, (a, b_) in dropped.items())) if dropped else "no":>7}')

print(f'\n  {gated} of {len([b for b in books.values() if len(b)==3])} books '
      f'refused by the entry gate')
print(f'  {chased} books had at least one leg walked DOWN from its first quote')

print('\n=== the three books that completed ===')
print(f'{"book":30} {"collected":>10} {"vs 1.00":>9} {"with ratchet":>13} {"vs 1.00":>9}')
for ev, fills in FILLS.items():
    legs = books.get(ev) or {}
    entry = {l: seq[0] for l, seq in legs.items()} if legs else {}
    actual = sum(fills.values())
    # the ratchet floors every leg at its first quote, so a completed book
    # collects at least the entry sum
    ratch = sum(max(fills.get(l, 0), entry.get(l, 0)) for l in fills) if entry else actual
    name = ev.replace('KXARGPREMDIVGAME', 'ARG').replace('KX', '')[:30]
    print(f'{name:30} {actual:>9}c {actual-100:>+8}c {ratch:>12}c {ratch-100:>+8}c')

print('\n  The ratchet alone recovers only what the chase gave away. Two of')
print('  these books never had an edge to protect -- which is what the entry')
print('  gate is for, and it refuses them before a single leg is offered.')
