"""A1-V2RAMP 19-day replay (#318): same rule/maths as /root/tm/v2ramp/v2ramp.py, but Sync reserves come from r6tape.db (21 Sep - 8 Oct) instead of RPC.
Seed = reserve of the first Sync of the pair, rounded to 3 decimals == 1.000. No feed lag in replay (lag 0)."""
import sqlite3, csv, json, sys, time, collections
sys.path.insert(0, "/root/tm"); import capx
c = sqlite3.connect("file:/opt/ppcopy/r6tape.db?mode=ro", uri=True)
M = {r[0]: r[1:] for r in c.execute("select pool,token,token0,quote,created_t from meta where venue='v2'")}
AMT = 0.05; F = 0.997; ENTRY = 8; EXIT = 303
S = collections.defaultdict(list)
for pool, t, r0, r1 in c.execute("select pool,t,reserve0,reserve1 from v2ev where kind='sync' order by pool,block,li"):
    if pool in M: S[pool].append((t, r0, r1))
rows = []; skipped = collections.Counter(); notape = []; end = max(s[-1][0] for s in S.values())
for pool, ev in S.items():
    tok, t0_, q, ct = M[pool]; w0 = t0_ == q
    ev = [(t, (a if w0 else b) / 1e18, (b if w0 else a) / 1e18) for t, a, b in ev]
    if round(ev[0][1], 3) != 1.0: continue
    if ev[0][2] <= 0: skipped["seed no token"] += 1; continue
    if ct + EXIT + 20 > end: skipped["tape ended"] += 1; continue
    ent = next((s for s in ev if s[0] >= ct + ENTRY), None); ex = [s for s in ev if s[0] <= ct + EXIT]
    if not ent or not ex: skipped["no sync at entry"] += 1; notape.append(pool); continue
    ex = ex[-1]; tk = AMT * F * ent[2] / (ent[1] + AMT * F); out = tk * F * ex[1] / (ex[2] + tk * F); net = out / AMT
    rows.append(dict(pair=pool, token=tok, t=ct, entry_t=ent[0], exit_t=ex[0], net=round(net, 3), exit_weth=round(ex[1], 3), nsync=len(ev), px_in=ent[1] / ent[2], px_out=ex[1] / ex[2]))
rows.sort(key=lambda r: r["t"])
for r in rows:
    r["cb"] = capx.cap_usd(r["token"], r["px_in"]); r["cs"] = capx.cap_usd(r["token"], r["px_out"])
capx.save()
with open("trades.csv", "w") as fh:
    w = csv.writer(fh); w.writerow("pool entry_t exit_t why net_x late cap_buy_usd cap_sell_usd arm".split())
    for r in rows: w.writerow([r["pair"], int(r["entry_t"]), int(r["exit_t"]), "time 300s", r["net"], 0, r["cb"], r["cs"], "A"])
    for r in rows:
        prior = sorted((q for q in rows if q["exit_t"] <= r["entry_t"] and q is not r), key=lambda q: q["exit_t"])[-2:]
        half = len(prior) == 2 and all(q["net"] < 1 for q in prior)
        w.writerow([r["pair"], int(r["entry_t"]), int(r["exit_t"]), "time 300s" + (" half" if half else ""), round(1 + 0.5 * (r["net"] - 1), 3) if half else r["net"], 0, r["cb"], r["cs"], "B"])
with open("notape.txt", "w") as fh: fh.write("\n".join(notape))
n = len(rows); m = sum(r["net"] for r in rows) / n; mc = sum(min(r["net"], 10) for r in rows) / n
streak = best = 0
for r in rows: streak = streak + 1 if r["net"] < 1 else 0; best = max(best, streak)
days = collections.defaultdict(list)
for r in rows: days[time.strftime("%d %b", time.gmtime(r["t"]))].append(r["net"])
print(f"n {n} mean {m:.2f} capped10 {mc:.2f} <1x {sum(1 for r in rows if r['net']<1)} <0.2x {sum(1 for r in rows if r['net']<0.2)} best loss streak {best} skipped {dict(skipped)}")
for d, v in days.items(): print(d, len(v), round(sum(v) / len(v), 2))
