"""What did COMPLETED books actually collect, over four months of paper trading?

Today's three live books each collected less than the $1.00 they owed. Three is
an anecdote. mm_paper_results.csv holds every leg the paper maker quoted since
April with what it filled at and whether it settled, so the same question can be
asked at n in the hundreds:

  - of books where all three legs filled, how many collected more than 1.00?
  - how much more, after fees?
  - and does quoting a premium over the touch actually fix it, or does it just
    trade completed books for unfilled ones?

The last question is the one that decides whether this strategy exists. A
premium always improves the books that DO complete; it only makes money if
enough of them still complete.
"""
import csv, collections, statistics

RESULTS = r'E:\soccer\research\mm_paper_results.csv'
MAKER_FEE_RATE = 0.0175


def maker_fee(p):
    return MAKER_FEE_RATE * p * (1.0 - p)


def _f(x, lo=0.0, hi=1.0):
    try:
        v = float(x)
        return v if lo < v < hi else None
    except (TypeError, ValueError):
        return None


def event_of(t):
    return t.rsplit('-', 1)[0] if t else None


def load():
    books = collections.defaultdict(dict)
    with open(RESULTS, encoding='utf-8', errors='replace') as fh:
        for r in csv.DictReader(fh):
            ev = event_of(r.get('leg_ticker'))
            side = (r.get('side') or '').lower()
            if not ev or not side:
                continue
            ask = _f(r.get('our_ask'))
            if ask is None:
                continue
            filled = str(r.get('filled') or '0').strip() in ('1', 'True', 'true')
            fill = _f(r.get('fill_px')) if filled else None
            # keep the LAST quote per leg per book
            books[ev][side] = {'ask': ask, 'filled': filled,
                               'fill': fill if fill is not None else ask,
                               'regime': r.get('regime') or '?'}
    return books


def main():
    books = load()
    three = {e: b for e, b in books.items() if len(b) == 3}
    done = {e: b for e, b in three.items() if all(l['filled'] for l in b.values())}
    print(f'{len(books):,} books quoted, {len(three):,} with all three legs, '
          f'{len(done):,} completed (all three filled) '
          f'= {100.0*len(done)/max(1,len(three)):.1f}%\n')

    if not done:
        return

    print('=== what completed books collected ===')
    rows = []
    for e, b in done.items():
        coll = sum(l['fill'] for l in b.values())
        fees = sum(maker_fee(l['fill']) for l in b.values())
        rows.append({'ev': e, 'coll': coll, 'fees': fees,
                     'net': coll - fees - 1.0,
                     'regime': list(b.values())[0]['regime']})
    coll = sorted(r['coll'] for r in rows)
    n = len(coll)
    print(f'  collected: median {statistics.median(coll):.4f}  '
          f'p25 {coll[n//4]:.4f}  p75 {coll[3*n//4]:.4f}')
    above = sum(1 for c in coll if c > 1.0)
    print(f'  above 1.00 before fees : {above}/{n} ({100.0*above/n:.0f}%)')
    net = [r['net'] for r in rows]
    win = sum(1 for x in net if x > 0)
    print(f'  PROFITABLE after fees  : {win}/{n} ({100.0*win/n:.0f}%)')
    print(f'  mean net per book      : {statistics.mean(net)*100:+.2f}c')
    print(f'  median net per book    : {statistics.median(net)*100:+.2f}c')
    print(f'  TOTAL over {n} books    : {sum(net)*100:+.1f}c')

    # did we fill at our quote, or worse?
    slip = [l['fill'] - l['ask'] for b in done.values() for l in b.values()]
    if any(abs(s) > 1e-9 for s in slip):
        print(f'\n  fill vs quote: median {statistics.median(slip)*100:+.3f}c')
    else:
        print('\n  fills land exactly at our quote (no per-leg slippage)')

    # ── the decisive test: does a premium help, or just kill completion? ──
    print('\n=== would quoting a premium have helped? ===')
    print('  Premium is added to EVERY leg at quote time. A book completes only')
    print('  if each leg still fills -- proxied here by the leg having filled')
    print('  with enough headroom between our ask and 1.00 to absorb it.')
    print(f'\n{"premium/leg":>12} {"books done":>11} {"mean net":>10} {"total":>10}')
    for prem_c in (0.0, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0):
        prem = prem_c / 100.0
        kept, tot = [], 0.0
        for e, b in three.items():
            # every leg must have filled AND still be sellable at ask+premium
            if not all(l['filled'] for l in b.values()):
                continue
            legs = [l['fill'] + prem for l in b.values()]
            if any(p >= 0.99 for p in legs):
                continue                     # cannot quote through the dollar
            c = sum(legs)
            f = sum(maker_fee(p) for p in legs)
            kept.append(c - f - 1.0)
        if not kept:
            continue
        tot = sum(kept)
        print(f'{prem_c:>10.2f}c {len(kept):>11} {statistics.mean(kept)*100:>9.2f}c '
              f'{tot*100:>9.1f}c')
    print('\n  NOTE: this holds completion FIXED, so it is an upper bound --')
    print('  it shows what a premium is worth IF fills survive it. Whether they')
    print('  do is a queue question the paper log cannot answer; the live')
    print('  fill data is the only thing that can.')


if __name__ == '__main__':
    main()
