"""mc5replay.py (A1.20 live match): replay Price Predict's mc5 paper trades with mc5health.py's code. Usage: python3 mc5replay.py pool [pool ...]"""
import sys
pools_arg = [a.lower() for a in sys.argv[1:]]
sys.argv = [sys.argv[0], "7"]
HS = open("/root/fwa1/mc5health.py").read()
pre = HS[:HS.index("V = sqlite3.connect")]
exec(pre)
V = sqlite3.connect("file:/opt/sw/v3live.db?mode=ro", uri=True)
fns = HS[HS.index("def pull(jobs):"):HS.index("done = {tuple")]
exec(fns)
r = json.loads(urllib.request.urlopen(urllib.request.Request("https://api.coingecko.com/api/v3/coins/ethereum/market_chart?vs_currency=usd&days=2", headers={"User-Agent": "Mozilla/5.0"}), timeout=30).read())["prices"]
fns2 = HS[HS.index("EUt = "):HS.index("cand = []")]
exec(fns2)
import datetime
def bkk(ts): return datetime.datetime.utcfromtimestamp(ts + 7 * 3600)
for pool in pools_arg:
    row = V.execute("SELECT pool, token, token_is0, fee, created_b FROM pools WHERE pool=?", (pool,)).fetchone()
    if not row: print(pool, "not in v3live"); continue
    body = [{"jsonrpc": "2.0", "id": 0, "method": "eth_call", "params": [{"to": row[1], "data": "0x18160ddd"}, "latest"]}, {"jsonrpc": "2.0", "id": 1, "method": "eth_call", "params": [{"to": row[1], "data": "0x313ce567"}, "latest"]}]
    rr = {x["id"]: x.get("result") for x in post(body)}; dec = int(rr[1], 16); sup = int(rr[0], 16) / 10 ** dec
    D.execute("INSERT OR REPLACE INTO meta VALUES(?,?,?,?,?,?,?)", (row[0], row[1].lower(), row[2], row[3], row[4], sup, dec)); D.commit()
    meta = {x[0]: x for x in D.execute("SELECT pool, token, is0, fee, cb, supply, dec FROM meta")}
    D.execute("DELETE FROM done WHERE pool=?", (pool,)); D.commit()
    pull([(pool, f, min(f + CH - 1, head)) for f in range(row[4], head + 1, CH)])
    e = entry(pool)
    if not e: print(pool, "no entry state"); continue
    (pth, pull_t, pf, sup_, fb), i, eu, mc = e
    L = Lat(pth, i); x = 100 / eu; gas = 0.05 / eu
    if not L:
        we5 = sum(p_[3] for p_ in pth[:i + 1])
        print(pool, 'NO TRADE in my rule: no swap of 0.001+ ETH that moved price before +5 min (depth unknown); cap +5m $%.0fk, pool WETH %.4f, swaps before +5m %d, ETH swapped %.4f' % (mc / 1e3, pth[i][4], i + 1, we5)); continue
    xin = x * (1 - pf) * 0.99 - gas; q = cpm(pth[i][1], L, xin)
    Tm, M = [], []
    for k in range(i + 1, len(pth)):
        if pth[k][0] > 300 + HOLD: break
        Lk = Lat(pth, k)
        if not Lk or pth[k][3] < 0.01: continue
        out = min(cpm(pth[k][1], Lk, q, True), 0.9 * (pth[k][4] + xin))
        Tm.append(pth[k][0]); M.append(max(0, out * (1 - pf) * 0.99 - gas) / x)
    v, why, tt = None, "open", None
    for k in range(len(M)):
        if pull_t is not None and pull_t <= Tm[k]: v, why, tt = 0.0, "pull", pull_t; break
        if M[k] <= 0.5:
            j = max(k, bisect.bisect_right(Tm, Tm[k] + 3) - 1); v, why, tt = M[j], "stop", Tm[j]; break
    if v is None and (now - btime(fb)) > 300 + HOLD: v, why = (M[-1] if M else 0.0), "time"
    print("%s first swap %s BKK | cap +5m $%.0fk | pool WETH %.3f | L %.3g | exit %s at +%s s | x %s | peak %.2fx | max 0.01+ swaps after entry %d" % (pool,
        bkk(btime(fb)).strftime("%d %b %H:%M:%S"), mc / 1e3, pth[i][4], L or 0, why, int(tt) if tt else "-", "%.2f" % v if v is not None else "-", max(M) if M else 0, len(M)))
