"""What does CHARGING MORE cost us in fills? (historical)

The live quoter posts at min(fair + margin, market_ask), so it is almost always
capped AT the market ask -- we join the queue, we never charge more. The user's
idea: charge more on legs where xlow says the market is cheap.

The core question does not need Pinnacle fair at all:
    if we post k cents ABOVE the market ask, how much fill do we give up?
Every extra cent is +1c of gross edge per leg and some loss of fill probability.
There is an optimum and it is measurable.

PART 1 (big sample, 370 clean books x 3 legs): fill rate and expected book P&L
as a function of k.
PART 2 (small sample): does an xlow signal on a leg change that curve -- i.e. is
xlow a way to know WHICH legs can absorb a higher ask? Needs pin_fair, which
only exists where live_data overlaps the backfill, so n is much smaller and this
half is directional only.

Fill model, and its known optimism: a leg counts as filled if any maker-sell
trade (taker_book_side='bid') printed at or above our ask in the last NEAR_H
hours pre-kickoff. That ignores QUEUE PRIORITY -- in reality we join behind
existing size at the same price, so true fills are lower than modelled. The
error is conservative for this test's PURPOSE though: it applies equally at
every k, and posting above the book's best ask actually puts us FIRST in queue
at that price, so the k>0 numbers are the least distorted.
"""
import csv
import datetime as dt
import statistics
import sys
from collections import defaultdict

sys.path.insert(0, r'E:\soccer\research')
import mm_gross_gate_history as H          # reuse loaders + the two data filters

MAX_K = 5


def main():
    books = H.load_books()
    fills = H.load_fills(books)
    smap = H.leg_suffixes(books, fills)
    print(f'{len(smap)} clean books ({len(smap)*3} legs) after spread<=6c and sum(bids)<100c\n')

    # PART 1 -----------------------------------------------------------------
    print('PART 1 -- posting k cents above the market ask')
    print(f"  {'k':>3s} {'leg fill %':>11s} {'all-3 %':>9s} {'2-of-3 %':>9s} "
          f"{'mean gross':>11s} {'E[net]/book':>12s}")
    for k in range(0, MAX_K + 1):
        legfill = []
        per_book = []
        for ev, sfx in smap.items():
            b = books[ev]
            nf = 0
            for s in ('home', 'draw', 'away'):
                our = b['asks'][s] + k / 100.0
                f = H.filled(fills[(ev, sfx[s])], our, b['ko'], True)
                legfill.append(f)
                nf += f
            gross = b['gross'] + 3 * k                 # +k on each of 3 legs
            if nf == 3:
                net = gross
            elif nf == 2:
                # the unsold leg is completed by selling into the bid; charging
                # more does not help the leg we end up crossing on
                net = gross - k - 1.0 - H.FEE(min(b['bids'].values()))
            else:
                net = 0.0                              # book never formed
            per_book.append({'nf': nf, 'gross': gross, 'net': net})
        n = len(per_book)
        a3 = sum(1 for x in per_book if x['nf'] == 3) / n * 100
        a2 = sum(1 for x in per_book if x['nf'] == 2) / n * 100
        print(f'  {k:3d} {sum(legfill)/len(legfill)*100:10.1f}% {a3:8.1f}% {a2:8.1f}% '
              f'{statistics.mean([x["gross"] for x in per_book]):10.2f}c '
              f'{statistics.mean([x["net"] for x in per_book]):11.2f}c')

    print('\n  E[net] counts a book that never forms as 0 (no position, no P&L).')
    print('  A 2-of-3 book is completed by crossing, so it pays the fee.')


if __name__ == '__main__':
    main()
