#!/usr/bin/env python """r0831_margini_conto.py — riconcilia la pagina margini del conto. Riproduce due numeri. PERCHE'. Due domande erano rimaste aperte e nessuna era rispondibile dal gateway (debito #11: `account_summary` filtrato a 8 campi, niente initial_margin, `extended` ignorato): 1. l'HAIRCUT sull'USDe: la KB ufficiale dice 5%, `config/live.json` diceva 10% "verificato sul venue il 26/08" senza traccia di come; 2. quale MODELLO DI MARGINE e' attivo — che nessuno aveva mai chiesto. Lo screenshot della pagina `Standard Margin` (2026-08-31 07:50:30 UTC, fornito dall'operatore) le chiude entrambe. Qui la riconciliazione, perche' un numero pubblicato deve avere uno script che lo riproduce (N11) e perche' l'haircut non si legge nella pagina: si RICAVA per differenza fra due righe, ed e' un conto che va mostrato invece che asserito. uv run python scripts/research/r0831_margini_conto.py """ from __future__ import annotations # --- dalla schermata (2026-08-31 07:50:30 UTC) --- SEG_USDC = 1400.86 # S:SM (ATTIVO) -> riga USDC, Available Balance. USDE NON e' in tabella. CROSS_XSM = 2011.73 # X:SM -> riga CROSS, Available Balance PX_INDICE = 0.9998 # prezzo mostrato in cima alla pagina # --- dal conto, letti via gateway alle ~07:55 dello stesso giorno --- USDC_EQ = 1412.281074 USDE_EQ = 643.175691 IM_MIS = 11.5530 # riservato in USDC = equity - available (misurato) ETH_DUST_USD = 0.000078 * 2500 # riga ETH della schermata, ~$0.20 TOLL = 2.0 # $: sotto questo scarto due ipotesi non si distinguono def haircut_implicito(cross: float, usdc: float, eth_dust: float, im: float, usde: float, px: float) -> tuple[float, float]: """PURA. -> (contributo dell'USDE al cross in USD, haircut implicito). L'haircut non e' scritto da nessuna parte nella pagina: si ricava perche' il CROSS conta l'USDE scontato e il SEGREGATO non lo conta affatto. La differenza fra le due righe, tolto cio' che e' comune, E' il contributo dell'USDE.""" contributo = cross - (usdc + eth_dust - im) return contributo, 1.0 - contributo / (usde * px) def main() -> int: print("=" * 78) print(" PAGINA MARGINI — riconciliazione (screenshot 2026-08-31 07:50:30Z)") print("=" * 78) atteso_seg = USDC_EQ - IM_MIS print(f"\n [1] S:SM, il modello ATTIVO — solo il silo USDC") print(f" USDC equity {USDC_EQ:,.2f} - IM {IM_MIS:,.2f} = {atteso_seg:,.2f}" f" schermata {SEG_USDC:,.2f} scarto ${abs(atteso_seg-SEG_USDC):.2f}") print(f" → l'USDE non compare in questa tabella: nel modello attivo NON fa margine.") contrib, h = haircut_implicito(CROSS_XSM, USDC_EQ, ETH_DUST_USD, IM_MIS, USDE_EQ, PX_INDICE) print(f"\n [2] X:SM — l'haircut si RICAVA per differenza") print(f" contributo USDE al cross = ${contrib:,.2f} su ${USDE_EQ*PX_INDICE:,.2f} di valore") print(f" → haircut implicito {h:.4%}") for cand, nome in ((0.05, "KB ufficiale"), (0.10, "config al 30/08")): att = USDE_EQ * PX_INDICE * (1 - cand) ok = abs(att - contrib) < TOLL print(f" {cand:.0%} ({nome:16s}) → atteso ${att:,.2f}, scarto ${abs(att-contrib):6.2f}" f" {'TORNA' if ok else 'NON torna'}") verdetto_h = "5%" if abs(USDE_EQ*PX_INDICE*0.95 - contrib) < TOLL else "indeterminato" delta_modelli = CROSS_XSM - SEG_USDC print(f"\n VERDETTO (calcolato a runtime, N11):") print(f" haircut USDe = {verdetto_h} → `config/live.json` diceva 10%: SBAGLIATO") print(f" modello attivo = SEGREGATO (S:SM) → l'USDE non e' collaterale del book") print(f" passare a X:SM aggiungerebbe ${delta_modelli:,.2f} di margine utilizzabile") return 0 if __name__ == "__main__": raise SystemExit(main())