Files
PythagorasGoal/scripts/research/r0831_margini_conto.py
T
Adriano Dal Pastro fd7595e819 margini: haircut 5% (la config aveva torto) — e il conto NON e' cross-collateral
Lo screenshot della pagina margini era su Wasabi (rclone remote wasabi:, bucket
adp-work, cartella _scambio), non sulla VPS: per questo il percorso non esisteva.
Riconciliazione riproducibile in scripts/research/r0831_margini_conto.py (N11).

(a) HAIRCUT = 5%. La pagina non lo espone come numero: si ricava per differenza,
perche' il CROSS conta l'USDE scontato e il SEGREGATO non lo conta affatto.
  S:SM (attivo)  USDC Available 1.400,86  vs  equity 1.412,28 - IM 11,55 = 1.400,73
  X:SM           CROSS Available 2.011,73
  contributo USDE al cross = $610,81 su $643,05  ->  5,0137%
    5% (KB)     atteso $610,89  scarto $ 0,09  TORNA
   10% (nostra) atteso $578,74  scarto $32,06  NON torna
config/live.json: haircut 0.10 -> 0.05. Il 26/08 il 10% fu registrato come
"verificato sul venue" senza traccia di COME, e non lo era.

(b) 🚨 IL CONTO NON E' CROSS-COLLATERAL: modello attivo "Segregated: Standard
Margin" (S:SM). Nella tabella del modello attivo l'USDE NON COMPARE: non fa
margine per i perp USDC-settled del book, e l'haircut oggi non si applica. Il che
spiega a posteriori perche' la misura di stamattina trovava $0,0000 accantonati:
non stavo guardando nel secchio sbagliato, cercavo un parametro che sul nostro
conto non e' in vigore.

NON MORDE: al massimo lordo del libro (1,0x = ~$2.056 di nozionale) l'IM sarebbe
~$41 contro $1.400 di USDC disponibile, 34x di copertura. Nessuna decisione
operativa cambia oggi.

Ma la premessa in CLAUDE.md era falsa, e il modo in cui lo era e' istruttivo:
"l'equity del book e' il TOTALE cross-collateral" metteva due cose sotto un nome
solo. Come RICCHEZZA sommare USDC+USDE e' giusto ed era il punto della riparazione
del 26/08 (evito' il falso "USCITA DI FONDI -24%"); come CAPACITA' DI MARGINE e'
sbagliato, perche' nel modello attivo l'USDE vale zero. Finche' il margine non
morde le due coincidono nell'uso, e infatti non era mai emerso.

Corretta anche la riga di usde_watch che stampava "margine utilizzabile ~$2.013
(haircut 10%)": era falsa due volte insieme. Ora stampa il solo silo USDC e,
accanto, cosa darebbe il cross.

La quota USDE non e' "collaterale diversificato": e' cassa a rendimento FUORI dal
sistema di margine. Passare a X:SM aggiungerebbe $610,87 di margine utilizzabile
ma porta la meccanica cross (collateral fee 0,05%/giorno sul saldo negativo,
ribilanciamento automatico): decisione dell'operatore, oggi non serve.

Ipotesi nuova e non verificata: il tetto del ~31,2% potrebbe dipendere proprio dal
modello segregato. Si saprebbe passando a X:SM e ri-sondando.

Suite: 800 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 08:01:21 +00:00

77 lines
3.8 KiB
Python

#!/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())