"""Flatten one-shot del conto Deribit testnet per il RESET del portafoglio (2026-06-10).

Cancella gli ordini resting noti (TP limit / disaster-SL dai status.json dei worker),
poi chiude TUTTE le posizioni USDC con market reduce-only (close_position di cerbero
non supporta i lineari USDC) e verifica che il conto sia flat.

Uso: uv run python scripts/analysis/reset_flatten.py
"""
import glob
import json
import time

from src.live.cerbero_client import CerberoClient
from src.live.execution import ExecutionClient, contract_spec, register_contract


def main():
    c = CerberoClient()
    ex = ExecutionClient(client=c)

    # 1) ordini resting noti dai status.json (TP limit + disaster bracket)
    oids = set()
    for f in glob.glob("data/portfolio_paper/*/status.json"):
        s = json.load(open(f))
        for k in ("real_tp_order_id", "real_dsl_order_id"):
            if s.get(k):
                oids.add(s[k])
    for oid in sorted(oids):
        r = ex.cancel_order(oid)
        print(f"cancel {oid}: {r.get('state', r)}")

    # 2) flatten posizioni USDC (market reduce-only, max 5 passate)
    for attempt in range(5):
        live = [p for p in c.get_positions("USDC")
                if abs(float(p.get("size", 0) or 0)) > 0]
        if not live:
            print("FLAT — conto pulito")
            return True
        for p in live:
            inst = p["instrument"]
            register_contract(inst, c)
            size_usd = abs(float(p["size"]))
            mark = float(p.get("mark_price") or 0)
            step = contract_spec(inst)["step"]
            entry_side = "buy" if p["direction"] == "long" else "sell"
            units = size_usd / mark if mark else 0
            # _quantize_step (Decimal): round(units/step)*step in float binario
            # produce artefatti (0.07200000000000001) che Deribit rifiuta con
            # 'Invalid params' — il bug e' documentato in execution.py
            from src.live.execution import _quantize_step
            amount = _quantize_step(units, step, contract_spec(inst)["min"]) if units >= step / 2 else 0.0
            if amount <= 0:
                print(f"  {inst}: residuo {size_usd:.2f} USD sotto mezzo step, ok")
                continue
            f = ex.close_amount(inst, entry_side, amount, label="reset_flatten")
            print(f"  close {inst} amt={amount} -> {f.order_state} fill={f.fill_price} "
                  f"verified={f.verified} {f.notes[:60]}")
        time.sleep(3)

    left = [(p["instrument"], round(float(p["size"]), 4))
            for p in c.get_positions("USDC") if abs(float(p.get("size", 0) or 0)) > 0]
    print("RESIDUO FINALE:", left or "FLAT")
    return not left


if __name__ == "__main__":
    ok = main()
    raise SystemExit(0 if ok else 1)
