import pickle, collections, statistics, time, itertools
P, WAL = pickle.load(open("/root/fwa1/v3/an.pkl", "rb"))
CUT = 1790787600 - 6 * 86400 + 0   # placeholder replaced below
CUT = 1790701200 - 5 * 86400       # 25 Sep 00:00 Bangkok = 24 Sep 17:00 UTC
CUT = 1790269200                   # 25 Sep 2026 00:00 Bangkok
bk = lambda t: time.strftime("%d %b", time.gmtime(t + 7 * 3600))
pi = {p["pool"]: p for p in P}
print("pools with swaps", len(P), "| reached $1M within 2 h", sum(1 for p in P if p["t1m"] is not None),
      "| half A", sum(1 for p in P if p["t"] < CUT), "half B", sum(1 for p in P if p["t"] >= CUT))
byd = collections.Counter(bk(p["t"]) for p in P if p["t1m"] is not None)
print("$1M in 2h by day:", sorted(byd.items(), key=lambda x: time.strptime(x[0] + " 2026", "%d %b %Y")))
# ---- 1. real results of early buyers
def grp(w):
    return "new" if w[6] == 0 else ("rep1-2" if w[6] <= 2 else "rep3+")
def win(s): return "0-1 min" if s < 60 else ("1-5 min" if s < 300 else "5-15 min")
agg = collections.defaultdict(lambda: [0, 0.0, 0.0, 0.0, 0, []])
for w in WAL:
    pool, wal, s, ein, eout, left, mem, t1m = w
    if ein < 0.0005: continue
    later1m = t1m is not None and t1m > s
    for key in ((win(s), grp(w)), (win(s), grp(w), "coin hit $1M later" if later1m else "coin did not")):
        a = agg[key]; a[0] += 1; a[1] += ein; a[2] += eout; a[3] += left; a[4] += (eout + left > ein); a[5].append((eout + left) / ein)
print("\nwindow | wallet class | wallets | ETH in | realized out/in | out+left/in | share in profit | median wallet")
for k in sorted(agg, key=str):
    a = agg[k]
    print(" | ".join(map(str, k)), "|", a[0], "| %.1f" % a[1], "| %.2f" % (a[2] / a[1]), "| %.2f" % ((a[2] + a[3]) / a[1]), "| %.0f%%" % (100 * a[4] / a[0]), "| %.2f" % statistics.median(a[5]))
# ---- 2. launch facts at T that pick $1M-in-2h coins (not yet $1M at T), walk forward by halves
def rows(T):
    out = []
    for p in P:
        f = p["feats"][T]
        if f["mc"] is None or f["nswap"] < 1: continue
        if p["t1m"] is not None and p["t1m"] <= T: continue
        y = p["t1m"] is not None
        usd = f["buyeth"] * p["eu"]
        peak_after = p["peak"] if (p["peak"] > (f["mcmax"] or 0)) else f["mc"]
        ret = 3.0 if peak_after >= 3 * f["mc"] else (p["last_mc"] / f["mc"] if f["mc"] else 0)
        ret = ret * 0.98 - 0.02
        out.append(dict(y=y, half="A" if p["t"] < CUT else "B", nnew=f["nnew"], nbuy=f["nbuy"], usd=usd, rep1=f["rep1"], rep3=f["rep3"], mc=f["mc"], ret=ret, pool=p["pool"]))
    return out
for T in (60, 300, 900):
    R = rows(T)
    A = [r for r in R if r["half"] == "A"]; Bh = [r for r in R if r["half"] == "B"]
    base = lambda S: (sum(r["y"] for r in S), len(S))
    print("\n== T = %d s: candidates A %d (hit %d), B %d (hit %d)" % (T, len(A), base(A)[0], len(Bh), base(Bh)[0]))
    grid = []
    for nn, us, mcap, rp in itertools.product((0, 5, 10, 20, 40, 80), (0, 500, 2000, 5000, 15000), (0, 20e3, 50e3, 100e3, 250e3), (1.01, 0.5, 0.2, 0.05)):
        f = lambda r, nn=nn, us=us, mcap=mcap, rp=rp: r["nnew"] >= nn and r["usd"] >= us and r["mc"] >= mcap and r["rep1"] < rp
        sa = [r for r in A if f(r)]
        if len(sa) < 15: continue
        prec = sum(r["y"] for r in sa) / len(sa)
        grid.append((prec, len(sa), (nn, us, mcap, rp), f))
    grid.sort(key=lambda g: (-g[0], -g[1]))
    for prec, n, par, f in grid[:6]:
        sb = [r for r in Bh if f(r)]
        pb = sum(r["y"] for r in sb) / len(sb) if sb else 0
        ra = statistics.mean(r["ret"] for r in A if f(r)); rb = statistics.mean(r["ret"] for r in sb) if sb else 0
        print("rule new>=%d buyUSD>=%d mc>=%d rep1<%.2f | A: %d coins, %.0f%% hit $1M, paper %.2fx | B: %d coins, %.0f%% hit, paper %.2fx | B base %.1f%%" % (
            par[0], par[1], par[2], par[3], n, 100 * prec, ra, len(sb), 100 * pb, rb, 100 * base(Bh)[0] / max(1, len(Bh))))
