"""v3exit.py (A1.18): exit grid on mc5 entries with 12 h of data. Hard stop 0.5x and pull = 0 always.
Time stop 2/4/8/12 h; trailing stop armed at 2x (sell at f x peak, f 0.5/0.6/0.7); sell half at 3x then trail the rest. Pick on H1, test once on H2."""
import sqlite3, collections, statistics as st, random, numpy as np
exec(open("/root/fwa1/v3frag.py").read().split("random.seed(7)")[0])
E = sqlite3.connect("file:/root/fwa1/v3/v3ext.db?mode=ro", uri=True)
W12 = int(12 * 3600 / SPB)
head = E.execute("SELECT MAX(b) FROM sw").fetchone()[0]
def path12(p):
    pool, tok, is0, fee, cb, sup, dec = meta[p["pool"]]; fb = p["fb"]
    ev = []
    for DB in (D, E):
        for b, li, a0, a1, sq in DB.execute("SELECT b, li, a0, a1, sq FROM sw WHERE pool=?", (pool,)): ev.append((b, li, "s", (a0, a1, sq)))
        for b, li, kind, data in DB.execute("SELECT b, li, kind, data FROM lp WHERE pool=?", (pool,)): ev.append((b, li, kind, data))
    ev = sorted(set(ev), key=lambda e: (e[0], e[1]))
    out = []; prev = None; res = 0.0; added = 0.0; pull = None
    for b, li, kind, d in ev:
        if kind != "s":
            w = words(d); amt = (w[3] if is0 else w[2]) / 1e18 if kind == "m" else (w[2] if is0 else w[1]) / 1e18
            liq = w[1] if kind == "m" else w[0]
            if kind == "m": added += liq; res += amt
            else:
                res -= amt
                if added > 0 and liq >= 0.5 * added and pull is None: pull = (b - fb) * SPB
            continue
        a0, a1, sq = d
        Pr = (int(sq, 16) / 2 ** 96) ** 2
        sw_we = (s256(a1) if is0 else s256(a0)) / 1e18; res += sw_we
        if Pr <= 0: continue
        px = (Pr if is0 else 1 / Pr) * 10 ** dec / 1e18
        we = abs(sw_we); r = math.sqrt(px); L = None
        if prev is not None and we >= 0.001 and abs(r - prev) / prev > 1e-5: L = we / abs(r - prev)
        out.append(((b - fb) * SPB, r, L, we, max(res, 0.0))); prev = r
    return out, pull, fee / 1e6, sup
extdone = {r[0] for r in E.execute("SELECT DISTINCT pool FROM done")}
full = [p for p in pools if p["pool"] in extdone and meta[p["pool"]][4] + W12 <= head]
for p in full: CACHE[p["pool"]] = path12(p)
SC.clear()
S = []
for p in full:
    s = series_t(p, 100, 300)
    if s and 2.5e5 <= s[4] < 1e6: S.append((p, s))
print("trades with full 12 h data:", len(S), "H1", sum(p["t"] < CUT for p, s in S), "H2", sum(p["t"] >= CUT for p, s in S), flush=True)
def run(s, tstop, trail=None, arm=2.0, half=None):
    T, M, pull, m0, mc = s
    ok = T <= tstop; T, M = T[ok], M[ok]
    def fill(k):
        j = max(k, int(np.searchsorted(T, T[k] + 3, "right")) - 1); return float(M[j]), T[j]
    got = 0.0; left = 1.0; peak = 0.0; armed = False
    for k in range(len(M)):
        t, m = T[k], M[k]
        if pull is not None and pull <= t: return got + 0.0
        if m <= 0.5 * left / left and left == 1.0 and m <= 0.5:          # hard stop on full position
            v, tt = fill(k); return got + left * v
        if half and left == 1.0 and m >= half:
            v, tt = fill(k); got += 0.5 * v; left = 0.5; armed = True; peak = max(peak, m); continue
        peak = max(peak, m)
        if trail and m >= arm: armed = True
        if trail and armed and m <= trail * peak:
            v, tt = fill(k); return got + left * v
        if left < 1.0 and m <= 0.5 and not trail:
            v, tt = fill(k); return got + left * v
    if pull is not None and pull <= tstop: return got
    return got + left * (float(M[-1]) if len(M) else m0)
H = 3600
d1 = len({day(p["t"]) for p, s in S if p["t"] < CUT}); d2 = len({day(p["t"]) for p, s in S if p["t"] >= CUT})
for hh in (2, 2.5, 3, 3.5, 4, 4.5, 5, 6):
    out = []
    for h_ in (1, 2):
        v = [run(s, tstop=hh * H) for p, s in S if (p["t"] < CUT) == (h_ == 1)]
        out.append("H%d mean %.2fx w/o top3 %.2fx $%.0f/day" % (h_, st.mean(v), st.mean(sorted(v)[:-3]), sum(x - 1 for x in v) * 100 / (d1 if h_ == 1 else d2)))
    print("time %.1fh" % hh, " | ".join(out), flush=True)
# where is the money: per-trade gain 4h vs 2h
g = sorted([(run(s, tstop=4 * H) - run(s, tstop=2 * H), p["pool"], run(s, tstop=2 * H), run(s, tstop=4 * H)) for p, s in S], reverse=True)
print("biggest 4h gains:", [(b, round(c, 1), round(d, 1)) for a, b, c, d in g[:5]])
print("biggest 4h losses:", [(b, round(c, 1), round(d, 1)) for a, b, c, d in g[-5:]])
print("trades better at 4h: %d, worse: %d" % (sum(a > 0.01 for a, *_ in g), sum(a < -0.01 for a, *_ in g)))
