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
89 lines
4.4 KiB
Python
89 lines
4.4 KiB
Python
"""TP01 LIVE — SHADOW MODE (Deribit mainnet, SOLA LETTURA, nessun ordine inviato).
|
|
|
|
Valida l'esecuzione di TP01 a RISCHIO ZERO: gira il loop live completo contro dati/conto/posizioni
|
|
REALI del mainnet, calcola i target causali (stesso codice del backtest/paper), costruisce gli ordini
|
|
di ribilancio esatti — e li STAMPA invece di inviarli. Confronta i target col paper trader (parita').
|
|
|
|
Perche' non testnet: il testnet Cerbero/Deribit e' la causa del reset v2.0.0 (feed farlocco). La
|
|
validazione a rischio zero qui e' "shadow su mainnet reale in sola lettura"; il fill (slippage/fee)
|
|
si valida solo col micro-test mainnet a size minima, in un passo successivo.
|
|
|
|
Logica condivisa con la dashboard in src/live/shadow.py (un solo codice, niente drift).
|
|
|
|
uv run python scripts/live/live_trend.py # shadow su mainnet reale
|
|
uv run python scripts/live/live_trend.py --equity 2000 # forza la base di sizing
|
|
uv run python scripts/live/live_trend.py --no-net # offline: solo matematica + parita'
|
|
"""
|
|
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.deribit import notional_to_amount
|
|
from src.live.shadow import shadow_report
|
|
|
|
|
|
def main():
|
|
argv = sys.argv[1:]
|
|
offline = "--no-net" in argv
|
|
equity_override = float(argv[argv.index("--equity") + 1]) if "--equity" in argv else None
|
|
r = shadow_report(offline=offline, equity_override=equity_override)
|
|
|
|
print("=" * 84)
|
|
print(" TP01 LIVE — SHADOW MODE (Deribit mainnet, SOLA LETTURA — NESSUN ORDINE INVIATO)")
|
|
print("=" * 84)
|
|
real_eq = r["real_equity"]
|
|
conto = f"${real_eq:,.2f}" if real_eq else r["eq_basis"]
|
|
print(f" ultima barra 1d chiusa : {r['last_data']}")
|
|
print(f" rete : {'mainnet via Cerbero MCP' if r['online'] else 'OFFLINE / fallback close'}")
|
|
print(f" prezzi mark : " + " | ".join(f"{a['asset']} ${a['mark']:,.1f} ({a['mark_src']})" for a in r["assets"]))
|
|
print(f" conto reale : {conto}")
|
|
print(f" posizioni reali : " + ", ".join(f"{a['asset']} ${a['position_usd']:,.0f}" for a in r["assets"]) + f" ({r['pos_src']})")
|
|
print(f" base di sizing : ${r['equity']:,.2f} [{r['eq_basis']}]")
|
|
|
|
print("\n PER ASSET (target causale @ ultima barra chiusa):")
|
|
for a in r["assets"]:
|
|
state = "FLAT" if abs(a["target"]) < 1e-9 else ("LONG" if a["target"] > 0 else "SHORT")
|
|
line = (f" {a['asset']:<3} {state:<5} target {a['target']:+.3f}x -> notional ${a['target_notional']:,.0f}"
|
|
f" (pos reale ${a['position_usd']:,.0f})")
|
|
o = a["order"]
|
|
if o:
|
|
print(line + f"\n -> ORDINE: {o['side'].upper()} {o['amount']:.0f} {a['instrument']} "
|
|
f"(market{', reduce_only' if o['reduce_only'] else ''}, delta ${o['delta_notional']:,.0f})")
|
|
else:
|
|
print(line + " -> nessun ordine (gia' a target / sotto-soglia)")
|
|
|
|
print("\n PARITA' vs paper trader (target = current_target):")
|
|
if all(a["paper"] is None for a in r["assets"]):
|
|
print(" (paper TP01 standalone RITIRATO 2026-07-17: la parita' vive ora in paper_portfolio/shadow)")
|
|
else:
|
|
for a in r["assets"]:
|
|
print(f" {a['asset']}: paper {a['paper']:+.3f}x shadow {a['target']:+.3f}x -> {'OK' if a['parity'] else 'DIFFERISCE'}")
|
|
if not r["paper_aligned"]:
|
|
print(" NB paper non all'ultima barra -> avanzalo se i target differiscono")
|
|
|
|
print("\n VERIFICA costruttore ordini (quantizzazione step/minimo):")
|
|
for inst, samples in (("BTC-PERPETUAL", [1000, 1005, 7, 250.4]), ("ETH-PERPETUAL", [1000, 0.4, 33.7])):
|
|
got = ", ".join(f"${s}->{notional_to_amount(inst, s):.0f}" for s in samples)
|
|
print(f" {inst}: {got}")
|
|
|
|
print("\n => NESSUN ORDINE INVIATO (shadow). " +
|
|
(f"{len(r['orders'])} ordine/i costruito/i sopra." if r["orders"] else "Target flat: 0 ordini."))
|
|
|
|
|
|
USO = """uso: live_trend.py [--equity V] [--no-net]
|
|
|
|
uv run python scripts/live/live_trend.py # shadow su mainnet reale
|
|
uv run python scripts/live/live_trend.py --equity 2000 # forza la base di sizing
|
|
uv run python scripts/live/live_trend.py --no-net # offline: solo matematica + parita'
|
|
|
|
Dettaglio nel docstring in testa al file."""
|
|
|
|
if __name__ == "__main__":
|
|
from src.live.cli import valida
|
|
valida("live_trend.py", USO, flag=("--no-net",), con_valore=("--equity",))
|
|
main()
|