"""
Is the Kalshi bid-ask spread small enough that our edge survives paying it?
At each signal moment (first PRE snapshot where clv_kalshi in [5,12]% for a side),
measure: bid-ask spread (cents), edge vs MID, edge vs ASK (what we pay), and the
spread tax = edge_mid - edge_ask. Settle outcomes to get at-ask ROI.
"""
import csv, glob, sys
from collections import defaultdict
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
files = sorted(glob.glob(r'E:\soccer\live_data\*.csv'))

def fval(r, k):
    try: return float(r.get(k, ''))
    except (TypeError, ValueError): return None

series = defaultdict(lambda: {'rows': [], 'ftr': None})
for fp in files:
    with open(fp, newline='', encoding='utf-8', errors='replace') as f:
        for r in csv.DictReader(f):
            if r.get('status') != 'PRE': continue
            el = fval(r, 'elapsed')
            if el is None or el >= 0: continue
            ftr = r.get('ftr') or None
            for side in ('home', 'away'):
                clv = fval(r, f'clv_kalshi_{side}')
                ask = fval(r, f'kalshi_{side}_ask')
                bid = fval(r, f'kalshi_{side}_bid')
                pf  = fval(r, f'pin_fair_{side}')
                d = series[(r['game_date'], r['home'], r['away'], side)]
                if clv is not None and ask and bid and pf and 0 < bid < ask < 1:
                    d['rows'].append((-el, clv*100, bid, ask, pf))
                if ftr: d['ftr'] = ftr
for d in series.values():
    d['rows'].sort(reverse=True)

FLOOR, CAP = 5.0, 12.0
spreads=[]; edge_mid=[]; edge_ask=[]; units=0.0; n=0; nwin=0
for key, d in series.items():
    if not d['ftr'] or not d['rows']: continue
    win = (d['ftr'] == ('H' if key[3]=='home' else 'A'))
    ei = next((i for i,(m,c,b,a,p) in enumerate(d['rows']) if FLOOR<=c<=CAP), None)
    if ei is None: continue
    m,c,bid,ask,pf = d['rows'][ei]
    mid = (bid+ask)/2
    spr = (ask-bid)*100
    em = (pf-mid)/mid*100
    ea = (pf-ask)/ask*100
    spreads.append(spr); edge_mid.append(em); edge_ask.append(ea)
    bo = (1-ask)/ask
    units += bo if win else -1
    n += 1; nwin += win

def stats(x):
    x=sorted(x); k=len(x)
    return sum(x)/k, x[k//2], x[int(k*0.9)]

ms,meds,p90s = stats(spreads)
mm,_,_ = stats(edge_mid)
ma,_,_ = stats(edge_ask)
print(f"signals (first clv in [{FLOOR:.0f},{CAP:.0f}]): {n}, winners {nwin} ({100*nwin/n:.0f}%)\n")
print(f"bid-ask spread (cents): mean {ms:.2f}  median {meds:.2f}  p90 {p90s:.2f}")
print(f"edge vs MID  : mean {mm:+.2f}%")
print(f"edge vs ASK  : mean {ma:+.2f}%   (this is what the signal/CLV uses)")
print(f"spread tax    : {mm-ma:.2f} pts of edge lost to crossing half the spread")
print(f"\nat-ask flat ROI: {100*units/n:+.1f}%  ({units:+.1f} units over {n} bets)")
print("=> edge survives the spread" if units>0 else "=> spread eats the edge")
