de83909db9
MISURATO oggi durante la revisione: `trades_db.py --help` non stampava l'uso, cadeva in sync() e riscriveva meta.ultimo_sync. Nessuno dei 18 script di scripts/live/ usava argparse: un flag sbagliato era il ramo else. Su journal.py avrebbe scritto pagina e riga di DB, su analista.py avrebbe speso una chiamata al modello e mandato un Telegram. - src/live/cli.valida: prima istruzione di ogni __main__, prima di connect()/sync/rete. --help -> 0 con l'uso; flag ignoto, valore mancante o posizionale -> 2 con l'elenco dei previsti (P4). NIENTE argparse: cambierebbe messaggi, codici d'uscita e --help di script che il cron gia' chiama. - 18 script cablati (i 3 che scrivono + 14 + cc01), flag invariati. - tests/test_cli_flag.py (30): elenco DERIVATO dalla cartella (P1), valida come prima istruzione, uso che documenta i flag, e i flag che il CRON usa davvero restano accettati (P15/P16); end-to-end su --help e flag ignoto con trades.db non toccato (M15). Verificato a mano: monitor_health --quiet, trades_db --sync --quiet, book_execute dry-run. Debito §5.15, primo passo: balance_watch (orario) registra `usde_usdc` a ogni campione — None con la ragione se illeggibile, mai 1,0. Il cablaggio nel bound quando la serie ha storia. Pulizia dalla revisione: tests/helpers.carica_script al posto della 15a copia del loader importlib (5 file del libro live); il fill di prova via upsert_fills invece di un INSERT che lasciava verified NULL; asserzioni non ancorate al padding; movimenti_capitale accetta le righe gia' lette (una SELECT invece di due ai due lati di una scrittura del cron). Test 910 verdi (+52). Diario 2026-09-02c. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
102 lines
4.3 KiB
Python
102 lines
4.3 KiB
Python
"""MICRO-TEST esecuzione su Deribit mainnet — round-trip minimo su BTC_USDC-PERPETUAL, apri+chiudi.
|
|
|
|
Conto reale = USDC -> strumento ESEGUIBILE = perp LINEARE `BTC_USDC-PERPETUAL` (amount in BTC, step
|
|
0.0001 ~ $6). Valida il percorso ordine->fill->reconciliation->chiusura con soldi VERI a size MINIMA
|
|
(~0x leva, decoupled dal segnale): test della plumbing, non della strategia. Usa open()/close()
|
|
verificati di src/live/execution.py (logica entrata/uscita presa da Old).
|
|
|
|
Sicurezze: default DRY-RUN. Pre-flight ABORT se posizione preesistente. La chiusura (reduce_only,
|
|
sempre permessa) flatta comunque dopo l'apertura; verifica finale di FLAT (alert se no).
|
|
|
|
uv run python scripts/live/microtest.py # DRY-RUN: nessun ordine inviato
|
|
uv run python scripts/live/microtest.py --live # invia il round-trip REALE
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from src.live.execution import FLAT_USD, MAX_AMOUNT, DeribitTrader
|
|
|
|
INSTRUMENT = "BTC_USDC-PERPETUAL"
|
|
AMOUNT = 0.0001 # base-coin (BTC) = 1 contratto minimo (~$6 a $63k)
|
|
|
|
|
|
def main():
|
|
live = "--live" in sys.argv[1:]
|
|
t = DeribitTrader()
|
|
|
|
print("=" * 82)
|
|
print(" MICRO-TEST esecuzione TP01 — round-trip 0.0001 BTC su BTC_USDC-PERPETUAL (leva ~0x)")
|
|
print("=" * 82)
|
|
try:
|
|
equity = float(t.account_summary("USDC").get("equity") or 0)
|
|
mark = t.mark_price(INSTRUMENT)
|
|
pos0 = t.position_usd(INSTRUMENT)
|
|
except Exception as e:
|
|
print(f" PRE-FLIGHT FALLITO (read): {type(e).__name__}: {e}\n -> non procedo.")
|
|
return
|
|
|
|
notional = AMOUNT * mark
|
|
print(f" conto USDC equity : ${equity:,.2f}")
|
|
print(f" mark {INSTRUMENT} : ${mark:,.1f}")
|
|
print(f" posizione attuale : ${pos0:,.2f} notional (dev'essere 0)")
|
|
print(f" apertura : BUY {AMOUNT:.4f} BTC market (~${notional:.2f}, leva {notional/equity:.4f}x)")
|
|
print(f" chiusura : SELL {AMOUNT:.4f} BTC market reduce_only")
|
|
print(f" guardrail: solo {INSTRUMENT}, cap apertura {MAX_AMOUNT[INSTRUMENT]} BTC")
|
|
|
|
if abs(pos0) >= FLAT_USD:
|
|
print(f"\n ABORT: posizione preesistente (${pos0:,.2f}). Non la tocco. Chiudila a mano e ripeti.")
|
|
return
|
|
if not live:
|
|
print("\n DRY-RUN: nessun ordine inviato. Rilancia con --live per il round-trip reale.")
|
|
return
|
|
|
|
# ---- LIVE: apertura ----
|
|
print("\n >>> LIVE: APERTURA ...")
|
|
fo = t.open(INSTRUMENT, "buy", AMOUNT, label="tp01-microtest-open")
|
|
if not fo.verified:
|
|
print(f" apertura NON verificata: {fo.notes}")
|
|
# safety: assicura comunque il flat
|
|
fc = t.close(INSTRUMENT, label="tp01-microtest-safeclose")
|
|
print(f" safe-close: {'eseguita' if fc else 'gia flat'}; posizione ${t.position_usd(INSTRUMENT):,.2f}")
|
|
return
|
|
print(f" FILL: {fo.filled:.4f} BTC @ ${fo.price:,.1f} fee {fo.fee_usdc:.6f} USDC (state={fo.state})")
|
|
|
|
# ---- LIVE: chiusura (reduce_only) ----
|
|
print(" >>> LIVE: CHIUSURA (reduce_only) ...")
|
|
fc = t.close(INSTRUMENT, label="tp01-microtest-close")
|
|
pos_end = t.position_usd(INSTRUMENT)
|
|
if fc:
|
|
print(f" FILL: {fc.filled:.4f} BTC @ ${fc.price:,.1f} fee {fc.fee_usdc:.6f} USDC (state={fc.state})")
|
|
print(f" posizione finale: ${pos_end:,.2f} notional")
|
|
|
|
# ---- report ----
|
|
print("\n " + "-" * 62)
|
|
if abs(pos_end) < FLAT_USD:
|
|
print(" ✓ ROUND-TRIP COMPLETO — posizione tornata a FLAT.")
|
|
else:
|
|
print(f" ⚠️ posizione NON flat (${pos_end:,.2f}) — INTERVENTO MANUALE: chiudi a mano.")
|
|
if fo.verified and fc:
|
|
tot_fee = fo.fee_usdc + fc.fee_usdc
|
|
pnl = AMOUNT * ((fc.price or 0) - (fo.price or 0))
|
|
print(f" entry ${fo.price:,.1f} -> exit ${fc.price:,.1f} | fee {tot_fee:.6f} USDC | "
|
|
f"pnl lordo {pnl:+.4f} | netto {pnl - tot_fee:+.4f} USDC")
|
|
print(" Validato: invio ordine reale, fill, fee reali, reconciliation, ritorno a flat.")
|
|
|
|
|
|
USO = """uso: microtest.py [--live]
|
|
|
|
uv run python scripts/live/microtest.py # DRY-RUN: nessun ordine inviato
|
|
uv run python scripts/live/microtest.py --live # invia il round-trip REALE
|
|
|
|
Dettaglio nel docstring in testa al file."""
|
|
|
|
if __name__ == "__main__":
|
|
from src.live.cli import valida
|
|
valida("microtest.py", USO, flag=("--live",), con_valore=())
|
|
main()
|