"""
Does the Kalshi CLV signal work on the DRAW outcome? The live strategy is home/away only.
Reconstruct draw signals with the SAME rules (clv_kalshi_draw in [5,12)%, first band entry,
dedupe per game), settle vs ftr=='D', and score ROI/significance. Also try the wider band
and a train/test split so the read is honest. Pure analysis.
"""
import os, sys
import numpy as np, pandas as pd
from scipy import stats
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
os.chdir(r'E:\soccer')

EDGE_LO, EDGE_HI = 0.05, 0.12
GAME = ['game_date', 'home', 'away']

dfs = [pd.read_csv('live_data/' + f) for f in os.listdir('live_data')
       if f.endswith('.csv') and f != 'test.csv']
df = pd.concat(dfs, ignore_index=True)
df['ts'] = pd.to_datetime(df['timestamp'], format='mixed', errors='coerce')
df = df[df['ts'].notna()]
pre = df[(df['status'] == 'PRE') & (df['elapsed'] < 0)].copy()

def build(lo, hi):
    c = 'clv_kalshi_draw'
    q = pre[(pre[c] >= lo) & (pre[c] < hi)].copy()
    q = q.sort_values('ts').drop_duplicates(GAME, keep='first')
    q['clv'] = q[c]
    q['ask'] = q['kalshi_draw_ask']
    q['p_win'] = q['pin_fair_draw']
    q['odds'] = np.where(q['ask'] > 0, 1.0 / q['ask'], np.nan)
    q['won'] = (q['ftr'] == 'D').astype(int)
    q = q.dropna(subset=['odds', 'p_win', 'ftr']).reset_index(drop=True)
    q['net'] = np.where(q['won'] == 1, q['odds'] - 1, -1.0)
    return q.sort_values('ts').reset_index(drop=True)

def zp(net):
    n = len(net)
    if n < 2: return float('nan'), float('nan')
    z = net.mean() / (net.std(ddof=1) / np.sqrt(n))
    return z, 1 - stats.norm.cdf(z)

def report(name, s):
    if len(s) == 0:
        print(f'  {name:<26} n=  0'); return
    z, p = zp(s['net'].values)
    print(f'  {name:<26} n={len(s):>4} | WR {s.won.mean():>5.1%} | ROI {s.net.mean():>+7.1%} | '
          f'net {s.net.sum():>+7.1f}u | mean odds {s.odds.mean():>4.2f} | z={z:+.2f} p={p:.3f}')

print("DRAW outcome -- does the CLV signal carry?  (live strategy is home/away only)\n")
sig = build(EDGE_LO, EDGE_HI)
print("Same rules as live (band [5,12)%):")
report('draws [5,12)%', sig)

print("\nWider/alt bands (draws sit in a narrow prob region, so the band may bite differently):")
for lo, hi in [(0.03, 0.05), (0.05, 0.08), (0.08, 0.12), (0.12, 0.20), (0.05, 0.20), (0.03, 0.30)]:
    report(f'[{lo:.0%},{hi:.0%})', build(lo, hi))

print("\nPer-league (band [5,12)%):")
for lg in sig.groupby('league')['net'].sum().sort_values().index:
    report(lg, sig[sig.league == lg])

print("\n" + "="*80)
print("Honest train/test on the [5,12)% draw set (first 60% TRAIN / last 40% TEST):")
s = build(EDGE_LO, EDGE_HI)
cut = int(len(s) * 0.60)
zt, pt = zp(s.iloc[cut:]['net'].values)
report('TEST (last 40%)', s.iloc[cut:])

print("\n" + "="*80)
print("For reference -- HOME/AWAY (the live edge) on the same data/band:")
ha = []
for side in ['home', 'away']:
    c = f'clv_kalshi_{side}'
    q = pre[(pre[c] >= EDGE_LO) & (pre[c] < EDGE_HI)].copy()
    q = q.sort_values('ts').drop_duplicates(GAME, keep='first')
    q['side'] = side; q['clv'] = q[c]
    q['ask'] = q[f'kalshi_{side}_ask']
    q['won'] = (q['ftr'] == {'home': 'H', 'away': 'A'}[side]).astype(int)
    ha.append(q)
ha = pd.concat(ha, ignore_index=True)
ha = ha.sort_values('clv', ascending=False).drop_duplicates(GAME, keep='first')
ha['odds'] = np.where(ha['ask'] > 0, 1.0/ha['ask'], np.nan)
ha = ha.dropna(subset=['odds', 'ftr']).reset_index(drop=True)
ha['net'] = np.where(ha['won'] == 1, ha['odds']-1, -1.0)
report('home/away [5,12)%', ha)
