"""
Monte-Carlo the compounded 1/4-Kelly floor sweep. The single-path result is
order-dependent; here we shuffle the bet order N times per threshold to get a
distribution of final bankrolls (median + 5th/95th percentile). The SET of bets
per threshold is fixed (first-crossing entries); only their sequence varies.
"""
import csv, glob, os, random, statistics
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
NSIM = 2000
random.seed(42)

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()

def run(seq):
    br = START
    for ask, pf, win in seq:
        b = (1 - ask) / ask
        f = max((pf * b - (1 - pf)) / b, 0.0)
        stake = round(min(f * KELLY_MULT, MAX_BET_PCT) * br, 2)
        if stake < 1.0: stake = 1.0
        if stake > br:  stake = round(br, 2)
        if win: br += stake * b
        else:   br -= stake
    return br

print(f"{NSIM} shuffles per threshold\n")
print(f"{'X%':>3}{'N':>6}{'median$':>10}{'p5$':>9}{'p95$':>9}{'P(loss)':>9}")
print('-' * 46)
for X in range(1, 13):
    thr = X / 100.0
    bets = []
    for key, d in series.items():
        ftr = d['ftr']
        if not ftr: continue
        win = (ftr == ('H' if key[3] == 'home' else 'A'))
        e = next(((ask, pf) for ts, clv, ask, pf in d['rows'] if clv >= thr), None)
        if e is None: continue
        bets.append((e[0], e[1], win))
    finals = []
    for _ in range(NSIM):
        random.shuffle(bets)
        finals.append(run(bets))
    finals.sort()
    med = statistics.median(finals)
    p5  = finals[int(0.05 * NSIM)]
    p95 = finals[int(0.95 * NSIM)]
    ploss = sum(1 for x in finals if x < START) / NSIM
    print(f"{X:>3}{len(bets):>6}{med:>10.0f}{p5:>9.0f}{p95:>9.0f}{ploss:>8.0%}")
