"""
Measure the REAL Polymarket bid/ask spread on open soccer match-winner markets,
bucketed by price level, so we can estimate the ask the mid-only backfill lacks.

The poly backfill stored only a mid (CLOB prices-history). To estimate execution
cost we need the spread. polymarket_live.get_all_prices exposes live bestBid/bestAsk,
so sample every currently-open match-winner market, compute spread = ask-bid and
half-spread = ask-mid, and report the distribution by mid bucket -- focus on the
longshot range (mid 0.05-0.35) the strategy actually bets.

Read-only, hits the public Gamma API, NOTHING traded.
"""
import sys, os
sys.path.insert(0, r"E:\soccer\main")
import re
import polymarket_live as P

def _f(x):
    try: return float(x)
    except (TypeError, ValueError): return None

def collect():
    """Return list of (mid, bid, ask) for every YES match-winner market now open."""
    evs = P.fetch_soccer_events()
    out = []
    for e in evs:
        title = e.get('title', '')
        if ' vs' not in title.lower() or 'more market' in title.lower():
            continue
        for m in (e.get('markets') or []):
            q = (m.get('question') or '').lower()
            if 'end in a draw' not in q and not re.search(r'will (.+?) (?:beat|win on)', q):
                continue   # only match-winner / draw markets
            bid, ask, mid = P._yes_prices(m)
            if ask and 0 < ask < 1:
                out.append((mid, bid, ask))
    return out

def main():
    rows = collect()
    print(f"open Poly match-winner YES markets sampled: {len(rows)}\n")
    if not rows:
        print("No open markets right now -- can't sample a live spread.")
        return
    buckets = [(0.0,0.05),(0.05,0.10),(0.10,0.15),(0.15,0.25),(0.25,0.35),
               (0.35,0.50),(0.50,0.70),(0.70,1.01)]
    print(f"{'mid bucket':14s} {'n':>4} {'noBid%':>7} {'medSpread':>10} {'medHalf':>8} {'medHalf%ofMid':>14}")
    for lo, hi in buckets:
        sel = [(mid,bid,ask) for mid,bid,ask in rows if lo <= mid < hi]
        n = len(sel)
        if not n:
            print(f"  [{lo:.2f},{hi:.2f})   {0:4d}"); continue
        nobid = sum(1 for _,bid,_ in sel if not bid or bid <= 0)
        # real spreads only where a bid exists
        real = [(mid,bid,ask) for mid,bid,ask in sel if bid and bid > 0]
        def med(xs):
            xs = sorted(xs); k = len(xs)
            return (xs[k//2] if k % 2 else (xs[k//2-1]+xs[k//2])/2) if k else float('nan')
        spreads = [ask-bid for _,bid,ask in real]
        halves  = [ask-(ask+bid)/2 for _,bid,ask in real]  # = (ask-bid)/2
        halfpct = [ (ask-(ask+bid)/2)/((ask+bid)/2)*100 for _,bid,ask in real if (ask+bid)>0]
        ms = med(spreads); mh = med(halves); mhp = med(halfpct)
        print(f"  [{lo:.2f},{hi:.2f})   {n:4d}  {100*nobid/n:6.1f}%  "
              f"{ms:10.3f}  {mh:8.3f}  {mhp:13.1f}%")
    # longshot rollup (mid 0.05-0.35 = our betting range)
    ls = [(mid,bid,ask) for mid,bid,ask in rows if 0.05 <= mid < 0.35 and bid and bid > 0]
    if ls:
        halves = sorted(ask-(ask+bid)/2 for _,bid,ask in ls)
        k = len(halves); med = halves[k//2] if k%2 else (halves[k//2-1]+halves[k//2])/2
        mean = sum(halves)/k
        print(f"\nLONGSHOT range mid[0.05,0.35) with a live bid: n={k}  "
              f"median half-spread={med:.3f}  mean={mean:.3f}")
        nobid_ls = sum(1 for mid,bid,ask in rows if 0.05<=mid<0.35 and (not bid or bid<=0))
        print(f"  (+{nobid_ls} markets in range had NO bid at all -> spread effectively huge)")

if __name__ == '__main__':
    main()
