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>
This commit is contained in:
@@ -302,9 +302,15 @@ def main() -> int:
|
||||
print(f" equity USDE : {eq_usde:,.4f} @ {px if px is not None else 'n/d'}"
|
||||
f" ({px_fonte}) -> ${usd:,.2f}" if usd is not None else " equity USDE : n/d")
|
||||
if quota is not None:
|
||||
margine = eq_usdc + usd * (1.0 - c["haircut"])
|
||||
print(f" quota : {quota:.1%} del totale (tetto allerta {c['quota_max_frac']:.0%})"
|
||||
f" · margine utilizzabile ~${margine:,.0f} (haircut {c['haircut']:.0%})")
|
||||
# Il conto e' Segregated Standard Margin (letto sulla pagina margini il 31/08):
|
||||
# l'USDE NON fa margine per i perp USDC-settled, e l'haircut non si applica. Il
|
||||
# margine del book e' il solo silo USDC. Si stampa anche cosa DAREBBE il cross,
|
||||
# perche' e' la differenza che rende la cosa una decisione invece che un dettaglio.
|
||||
cross = eq_usdc + usd * (1.0 - c["haircut"])
|
||||
print(f" quota : {quota:.1%} del totale (tetto allerta {c['quota_max_frac']:.0%})")
|
||||
print(f" margine : ~${eq_usdc:,.0f} — il solo USDC (conto SEGREGATO: l'USDE non"
|
||||
f" fa margine). Con cross X:SM sarebbero ~${cross:,.0f} (haircut"
|
||||
f" {c['haircut']:.0%})")
|
||||
if an["delta"] is not None:
|
||||
attr = ("non attribuibile (trade non leggibili)" if an["reward_stimato"] is None
|
||||
else f"reward stimato {an['reward_stimato']:+.6f} USDE"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user