"""
Bootstrap and Monte Carlo for the Range Breakout EA backtests (Part 2).
Usage:  python rb_resampling.py trades_GBPUSD_IS.csv trades_GBPUSD_OOS.csv trades_EURUSD.csv
Each CSV holds one closed trade per row: close_time, profit (USD).
Every file gets its own generators seeded with SEED, so results do not depend on file order.
"""
import csv, random, statistics as st, sys

SEED, N_ITER, START = 42, 10_000, 10_000.0

def load(path):
    with open(path, newline="") as f:
        return [float(r["profit"]) for r in csv.DictReader(f)]

def pf(p):
    w = sum(x for x in p if x > 0); l = -sum(x for x in p if x < 0)
    return w / l if l > 0 else float("inf")

def max_dd(p):
    eq = pk = START; md = 0.0
    for x in p:
        eq += x; pk = max(pk, eq); md = max(md, pk - eq)
    return md

def analyse(path):
    p = load(path); n = len(p)
    rb = random.Random(SEED)                 # bootstrap stream
    means, pfs = [], []
    for _ in range(N_ITER):
        s = [p[rb.randrange(n)] for _ in range(n)]
        means.append(st.mean(s)); pfs.append(pf(s))
    rm = random.Random(SEED)                 # Monte Carlo stream
    dds = []
    for _ in range(N_ITER):
        s = p[:]; rm.shuffle(s); dds.append(max_dd(s))
    means.sort(); pfs.sort(); dds.sort()
    q = lambda a, x: a[int(x * (N_ITER - 1))]
    print(f"{path}: trades={n} net={sum(p):.2f} PF={pf(p):.2f} expectancy={st.mean(p):.2f}")
    print(f"  expectancy 95% CI  {q(means,.025):+.2f} to {q(means,.975):+.2f}")
    print(f"  PF 95% CI          {q(pfs,.025):.2f} to {q(pfs,.975):.2f}")
    print(f"  resamples exp<=0   {100*sum(m <= 0 for m in means)/N_ITER:.1f}%")
    print(f"  MC drawdown median {q(dds,.5):.0f} ({100*q(dds,.5)/START:.1f}%)  "
          f"95th {q(dds,.95):.0f} ({100*q(dds,.95)/START:.1f}%)")

if __name__ == "__main__":
    for f in sys.argv[1:]:
        analyse(f)
