"""
What-if sweep: lower the CLV entry floor, measured both flat-unit and as a
COMPOUNDED 1/4-Kelly bankroll. Using live_data/*.csv pre-kickoff snapshots,
for each fixture+side find the FIRST moment Kalshi CLV >= X%, enter at that
snapshot's ask, settle via ftr. Sweep X = 1..12.

Kelly: p = pin_fair_<side> at entry, b = (1-ask)/ask,
       f = max((p*b-(1-p))/b, 0), stake = min(f*0.25, 0.25)*bankroll, floor $1.
"""
import csv, glob, os
from collections import defaultdict

os.chdir(r'E:\soccer')
files = sorted(glob.glob(r'live_data\*.csv'))

KELLY_MULT, MAX_BET_PCT, START = 0.25, 0.25, 1000.0

# key=(date,home,away,side) -> {'rows':[(ts,clv,ask,pinfair)], 'ftr':?}
series = defaultdict(lambda: {'rows': [], 'ftr': None})

def fval(r, k):
    try: return float(r.get(k, ''))
    except (TypeError, ValueError): return 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
            base = (r['game_date'], r['home'], r['away'])
            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')
                pf  = fval(r, f'pin_fair_{side}')
                d = series[base + (side,)]
                if clv is not None and ask is not None and 0 < ask < 1 and pf:
                    d['rows'].append((r['timestamp'], clv, ask, pf))
                if ftr:
                    d['ftr'] = ftr

for d in series.values():
    d['rows'].sort()

print(f"fixture-sides observed: {len(series)}\n")
print(f"{'X%':>3}{'N':>6}{'W':>5}{'WR%':>7}{'flatROI%':>10}{'KellyBR$':>11}{'Kelly%':>9}")
print('-' * 51)

for X in range(0, 26):
    thr = X / 100.0
    # gather entries (with entry timestamp for chronological compounding)
    entries = []
    for key, d in series.items():
        ftr = d['ftr']
        if not ftr:
            continue
        side = key[3]
        win = (ftr == ('H' if side == 'home' else 'A'))
        e = next(((ts, clv, ask, pf) for ts, clv, ask, pf in d['rows'] if clv >= thr), None)
        if e is None:
            continue
        ts, clv, ask, pf = e
        entries.append((ts, ask, pf, win))
    entries.sort(key=lambda x: x[0])

    n = w = 0
    flat = 0.0
    br = START
    for ts, ask, pf, win in entries:
        n += 1
        b = (1 - ask) / ask
        f = max((pf * b - (1 - pf)) / b, 0.0)
        frac = min(f * KELLY_MULT, MAX_BET_PCT)
        stake = round(frac * br, 2)
        if stake < 1.0:
            stake = 1.0
        if stake > br:
            stake = round(br, 2)
        if win:
            w += 1
            flat += b
            br += stake * b
        else:
            flat -= 1
            br -= stake
    flatroi = 100 * flat / n if n else 0
    kpct = 100 * (br - START) / START
    print(f"{X:>3}{n:>6}{w:>5}{(100*w/n if n else 0):>6.1f}{flatroi:>+10.1f}{br:>11.2f}{kpct:>+9.1f}")
