From 8d391ed29aedafd7c2d8b91b117a5449a2048ba9 Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Mon, 31 Aug 2026 08:39:45 +0000 Subject: [PATCH] =?UTF-8?q?margini:=20la=20pagina=20si=20ricostruisce=20da?= =?UTF-8?q?l=20gateway=20=E2=80=94=20e=20l'"IM=20%"=20non=20e'=20il=20marg?= =?UTF-8?q?ine=20delle=20posizioni?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'operatore ha incollato la riga CROSS col modello ATTIVO invece che proiettato: Available $2.010,81 · IM 2,15% · MM 0,37%. Il gateway, letto allo stesso minuto, dice available_funds = 2010,82299383. Scarto $0,01. (a) LO SCREENSHOT NON SERVE PIU'. La riga CROSS della pagina E' `available_funds`, che leggiamo da soli a ogni giro. Ieri quella schermata era l'UNICA fonte per l'haircut e per il modello attivo, e per averla e' servito un passaggio dall'operatore e da Wasabi. r0831_margini_conto.live() la ricostruisce. (b) TERZA CONFERMA DEL 5%, E LA PRIMA ESATTA: 1.400,71 + 0,95x654,176 + 0,20 dust - 11,553 IM = $2.010,82 contro pagina $2.010,81 Scarto $0,007. Il 10% della vecchia config non e' improbabile: invertendo la stessa riga da' IM = -$21,16, aritmeticamente impossibile. Tre strade indipendenti, stesso numero. (c) MIA LETTURA SBAGLIATA, CORRETTA. L'"IM %" della pagina e' (margin_balance - available)/margin_balance, non il margine delle posizioni: haircut USDE $32,71 = 1,592% + IM vera $11,55 = 0,562% = 2,153% Il 74% di quella percentuale e' HAIRCUT. E' salita da 2,13% a 2,15% perche' abbiamo comprato collaterale a rendimento — letta come rischio direbbe che ieri sera abbiamo alzato la leva comprando USDE, l'opposto di quello che e' successo. La MM invece e' pulita ($7,60) e non puo' contenere l'haircut, che da solo la renderebbe negativa: le due colonne hanno basi DIVERSE e la pagina non lo dice. Regola: una percentuale letta da una schermata va INVERTITA nella sua definizione prima di essere confrontata (P7 su superficie nuova). (d) LA BOCCIATURA DI X:PM ESCE RAFFORZATA. La KB da' USDe al 5% sotto entrambi i modelli: l'haircut si cancella e l'inversa da' il margine di POSIZIONE sulle stesse due posizioni, stesso istante — X:SM $11,64 contro X:PM $88,23, 7,6x, e 9,3x la MM. Due misure pulite, stesso verso. E la riga X:SM era una PROIEZIONE di un modello inattivo che oggi si riproduce al centesimo: anche la riga X:PM era affidabile, quindi decidere senza provare era corretto. Ora si sa perche', non solo che. Suite: 800 passati. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01BmkQty4a99pVmvwGfxAMQ9 --- CLAUDE.md | 2 +- docs/diary/2026-08-31b-venue-news-annunci.md | 70 +++++++++++++++++++- scripts/research/r0831_margini_conto.py | 62 +++++++++++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ee46bdf..ec98b2a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -67,7 +67,7 @@ lorda massima 1,0x**, e nessun livello di capitale cambia il profilo di rischio `min_order_usd` 5 · `disaster_sl_pct` 0.30 on-book sulla posizione **netta** · staleness-gate feed 2 giorni (blocca) · `skh_feed_max_age_min` 30 (allerta, **non** blocca) · alert Telegram. -📌 **Modello di margine: `Cross: Standard Margin` (X:SM) dal 2026-08-31**, cambiato dall'operatore. Prima era **Segregated** (S:SM), e sotto quello l'USDE **non faceva margine**: e' il motivo per cui la misura dell'haircut trovava $0,0000 accantonati — si cercava un parametro non in vigore. Il passaggio e' verificabile dal gateway: `available_funds` USDC e' passato da ~$1.400 a **$2.011,09**, contro $2.010,90 attesi con haircut 5% (scarto **$0,19** — seconda conferma indipendente del 5%). ⚠️ **Cosa ha comprato, misurato**: **$611** di margine utilizzabile — inutile a 0,28x di leva, serve solo sopra ~1,4x che non e' autorizzata — e **+11 USDE (~$11)** di capienza sul tetto. **Cosa e' costato**: sotto segregato l'USDE era **ring-fenced** dalle perdite del libro (solo il silo USDC rispondeva delle posizioni); sotto cross **l'intero conto risponde**. Non morde oggi (perdita massima plausibile ~$617 col disaster-SL, dentro il solo USDC), ma il rischio strutturale e' cambiato verso: **se un giorno il cross non servisse piu', tornare a S:SM ri-recinta l'USDE**. 📌 **X:PM valutato e SCARTATO il 31/08 senza provarlo** — la risposta era gia' nella pagina margini: **Available Balance $1.935,14 contro $2.011,73** di X:SM (−$76,59) e margini piu' alti su entrambe le misure, **MM 3,43% contro 0,37% (~9×)**. Il PM e' basato su scenari e premia il rischio che si **compensa**: due long direzionali nudi sono il suo caso peggiore, e paga lo scenario di stress invece dell'aliquota piatta. **Cosa lo riapre**: il deploy di VRP01 o di un altro sleeve di opzioni — allora il rischio inizia a compensarsi e il confronto cambia di segno. 📌 **L'equity che il book somma e' la RICCHEZZA, non la capacita' di margine** — giusta per accorgersi di un'uscita di fondi (il difetto del 26/08), sbagliata se la si usasse per dire quanto margine c'e'. +📌 **Modello di margine: `Cross: Standard Margin` (X:SM) dal 2026-08-31**, cambiato dall'operatore. Prima era **Segregated** (S:SM), e sotto quello l'USDE **non faceva margine**: e' il motivo per cui la misura dell'haircut trovava $0,0000 accantonati — si cercava un parametro non in vigore. Il passaggio e' verificabile dal gateway: `available_funds` USDC e' passato da ~$1.400 a **$2.011,09**, contro $2.010,90 attesi con haircut 5% (scarto **$0,19** — seconda conferma indipendente del 5%). ⚠️ **Cosa ha comprato, misurato**: **$611** di margine utilizzabile — inutile a 0,28x di leva, serve solo sopra ~1,4x che non e' autorizzata — e **+11 USDE (~$11)** di capienza sul tetto. **Cosa e' costato**: sotto segregato l'USDE era **ring-fenced** dalle perdite del libro (solo il silo USDC rispondeva delle posizioni); sotto cross **l'intero conto risponde**. Non morde oggi (perdita massima plausibile ~$617 col disaster-SL, dentro il solo USDC), ma il rischio strutturale e' cambiato verso: **se un giorno il cross non servisse piu', tornare a S:SM ri-recinta l'USDE**. 📌 **X:PM valutato e SCARTATO il 31/08 senza provarlo** — la risposta era gia' nella pagina margini: **Available Balance $1.935,14 contro $2.011,73** di X:SM (−$76,59) e margini piu' alti su entrambe le misure, **MM 3,43% contro 0,37% (~9×)**. Il PM e' basato su scenari e premia il rischio che si **compensa**: due long direzionali nudi sono il suo caso peggiore, e paga lo scenario di stress invece dell'aliquota piatta. **Cosa lo riapre**: il deploy di VRP01 o di un altro sleeve di opzioni — allora il rischio inizia a compensarsi e il confronto cambia di segno. ✅ **Confermato il 31/08 a X:SM attivo** e su misure pulite: la KB da' l'USDe al 5% sotto entrambi i modelli, quindi l'haircut si cancella e l'inversa della riga CROSS da' il margine di POSIZIONE — **$88,23 sotto PM contro $11,64 sotto SM, 7,6×**, e 9,3× la MM. La riga X:SM era una **proiezione di un modello inattivo** e oggi si riproduce al centesimo ⇒ anche la riga X:PM era affidabile: decidere senza provare era corretto. 🚨 **L'«IM %» della pagina margini NON e' il margine delle posizioni**: e' `(margin_balance − available)/margin_balance`, e da noi e' **74% haircut** (e' salita da 2,13% a 2,15% *perche' abbiamo comprato USDE*, non perche' sia salito il rischio). La **MM** e' pulita e ha base diversa. 📌 **La pagina margini non serve piu' come schermata**: la riga CROSS **e'** `available_funds` del gateway (scarto $0,01) e `r0831_margini_conto.live()` la ricostruisce, haircut compreso. 📌 **L'equity che il book somma e' la RICCHEZZA, non la capacita' di margine** — giusta per accorgersi di un'uscita di fondi (il difetto del 26/08), sbagliata se la si usasse per dire quanto margine c'e'. 📌 **Dal 2026-08-26 l'equity del book somma USDC + USDE** (valutato all'indice pubblico `usde_usdc`): il conto tiene **643 USDE** (**IDONEO** dal 28/08; portati da 500 a diff --git a/docs/diary/2026-08-31b-venue-news-annunci.md b/docs/diary/2026-08-31b-venue-news-annunci.md index 374053a..6f6ec59 100644 --- a/docs/diary/2026-08-31b-venue-news-annunci.md +++ b/docs/diary/2026-08-31b-venue-news-annunci.md @@ -341,7 +341,9 @@ nella schermata di §6. | **X:PM** | **$1.935,14** | 5,85% | **3,43%** | Sulla colonna il cui significato è inequivocabile — stessa riga, stesse unità — **X:PM dà $76,59 -di collaterale utilizzabile in MENO**, e chiede più margine su entrambe le misure. +di collaterale utilizzabile in MENO**, e chiede più margine. ⚠️ *La frase «su entrambe le misure» +è stata corretta in §9: l'«IM %» stampata dalla pagina non è il margine delle posizioni. +La conclusione non cambia — migliora.* **Perché**, ed è strutturale e non contingente: il Portfolio Margin è **basato su scenari di rischio** e premia i portafogli in cui il rischio si **compensa**, tipicamente i book di opzioni. @@ -356,3 +358,69 @@ comprato **$11**. ⇒ **SCARTATO.** ⚠️ *Non "PM è peggio", ma "PM è peggio PER QUESTO portafoglio"*: **cosa lo riapre** — il giorno che VRP01 o un altro sleeve di opzioni entra in deploy, il rischio inizia a compensarsi e quel confronto **cambia di segno**. Va rifatto allora, non prima. + +--- + +## 9. X:SM attivo: la pagina si ricostruisce dal gateway — e una mia lettura era sbagliata + +L'operatore ha incollato la riga CROSS col modello **attivo** invece che proiettato: +`Available $2.010,81 · IM 2,15% · MM 0,37%`. Il gateway, letto **allo stesso minuto** (08:34Z), dice +`available_funds` = **2010,82299383**. **Scarto $0,01.** + +### (a) Lo screenshot non serve più + +⇒ **La riga CROSS della pagina È `available_funds`**, che leggiamo da soli a ogni giro. Ieri quella +schermata era l'**unica** fonte per l'haircut e per il modello attivo, e per averla è servito un +passaggio dall'operatore e da Wasabi. Oggi non serve a niente: `r0831_margini_conto.live()` la +ricostruisce. + +### (b) Terza conferma del 5%, e la prima ESATTA + + 1.400,71 + 0,95 × 654,176 + 0,20 dust − 11,553 IM = $2.010,82 pagina $2.010,81 + +**Scarto $0,007.** E il 10% della vecchia config non è *improbabile*: invertendo la stessa riga dà +**IM = −$21,16**, cioè **aritmeticamente impossibile**. Le tre strade — differenza fra le righe +della pagina (31/08 07:50), salto di `available_funds` al passaggio S:SM→X:SM ($0,19), e ora questa +ricostruzione al centesimo — sono indipendenti e danno lo stesso numero. + +### (c) 🚨 L'«IM %» della pagina NON è il margine delle posizioni — mia lettura sbagliata + +`(margin_balance − available)/margin_balance = 2,1532%`, ed è **esattamente** ciò che la pagina +stampa come «IM 2,15%». Ma si scompone così: + +| voce | USD | % di margin_balance | +|---|---|---| +| haircut sull'USDE (5% × 654,18) | $32,71 | **1,592%** | +| IM vera delle due posizioni | $11,55 | 0,562% | +| **totale riservato** | **$44,26** | **2,153%** | + +⇒ **il 74% di quella percentuale è haircut, non rischio.** È salita da 2,13% a 2,15% **perché +abbiamo comprato collaterale a rendimento** — cioè per un motivo che con l'esposizione del libro +non c'entra nulla. *Letta come misura di rischio direbbe che ieri sera abbiamo alzato la leva +comprando USDE: l'opposto di quello che è successo.* + +La **MM invece è pulita**: 0,37% = $7,60, e non può contenere l'haircut ($32,71 da solo la +renderebbe negativa). **Le due colonne hanno basi diverse**, e la pagina non lo dice. + +📌 Regola: *una percentuale letta da una schermata va **invertita nella sua definizione** prima di +essere confrontata.* Due colonne affiancate, con la stessa unità e lo stesso aspetto, possono avere +denominatori — e qui numeratori — diversi. È P7 su una superficie nuova: un numero si etichetta +con la sua configurazione, e una pagina del venue non è obbligata a farlo per noi. + +### (d) La decisione su X:PM esce RAFFORZATA + +La KB dà **USDe al 5% sotto entrambi i modelli** (§6b): nel confronto l'haircut **si cancella**, e +l'inversa restituisce il margine di posizione puro sulle stesse due posizioni, stesso istante: + +| modello | available | **IM di posizione** | +|---|---|---| +| X:SM | $2.011,73 | **$11,64** | +| X:PM | $1.935,14 | **$88,23** | + +**PM chiede 7,6× il margine iniziale e 9,3× la MM.** Due misure ora pulite, stesso verso: la +bocciatura di §8 **regge, meglio fondata di quando l'ho scritta**. + +E c'è una conferma che ieri mancava: la riga X:SM era una **proiezione** di un modello **inattivo**, +e oggi che è attivo la stessa aritmetica la riproduce al centesimo. ⇒ **anche la riga X:PM, che +resta una proiezione, è affidabile**: la decisione presa senza provare il modello era presa su un +numero buono. *Non provare X:PM è stato corretto, e ora si sa perché e non solo che.* diff --git a/scripts/research/r0831_margini_conto.py b/scripts/research/r0831_margini_conto.py index c2d48bd..5f25047 100644 --- a/scripts/research/r0831_margini_conto.py +++ b/scripts/research/r0831_margini_conto.py @@ -69,8 +69,70 @@ def main() -> int: 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") + print(f"\n{'=' * 78}") + live() return 0 +# --- 2026-08-31 08:34Z: X:SM e' ATTIVO. La pagina non serve piu': si RICOSTRUISCE. -------------- +# +# L'operatore ha incollato la riga CROSS a X:SM attivo: Available $2.010,81, IM 2,15%, MM 0,37%. +# Il gateway, letto allo stesso minuto, dice `available_funds` = 2010.82299383 — **scarto $0,01**. +# ⇒ la riga CROSS della pagina E' `available_funds`, che leggiamo da soli. Lo screenshot che ieri +# era l'unica fonte per l'haircut e per il modello attivo NON e' piu' necessario a nulla. +PAG_AVAIL, PAG_IM_PCT, PAG_MM_PCT = 2010.81, 0.0215, 0.0037 # incollati dall'operatore, 08:34Z +GW_AVAIL, GW_MB = 2010.82299383, 2055.07348077 # gateway, stesso minuto +GW_USDC_EQ, GW_USDE = 1400.70809113, 654.175691 +XPM_AVAIL = 1935.14 # riga X:PM della schermata delle 07:50 (proiezione, modello inattivo) + + +def im_di_posizione(avail: float, usdc_eq: float, usde: float, px: float, h: float, + dust: float = ETH_DUST_USD) -> float: + """PURA. -> IM di POSIZIONE in USD, ripulita dall'haircut. + + Inversa esatta della riga CROSS: available = usdc_eq + (1-h)*usde*px + dust - IM. + Serve perche' la percentuale stampata dalla pagina NON e' questa (vedi live()).""" + return usdc_eq + (1 - h) * usde * px + dust - avail + + +def live() -> None: + print(" X:SM ATTIVO (2026-08-31 08:34Z) — la pagina si ricostruisce dal gateway") + print("=" * 78) + ric = GW_USDC_EQ + 0.95 * GW_USDE + ETH_DUST_USD - IM_MIS + print(f"\n [3] la riga CROSS, ricostruita con haircut 5%") + print(f" {GW_USDC_EQ:,.2f} + 0,95x{GW_USDE:,.3f} + {ETH_DUST_USD:.2f} dust" + f" - {IM_MIS:.3f} IM = ${ric:,.2f}") + print(f" pagina ${PAG_AVAIL:,.2f} · gateway ${GW_AVAIL:,.2f} → scarto ${abs(ric-PAG_AVAIL):.4f}") + for h in (0.05, 0.10): + im = im_di_posizione(GW_AVAIL, GW_USDC_EQ, GW_USDE, 1.0, h) + print(f" haircut {h:5.0%} → IM implicita ${im:9,.2f}" + f" {'coerente con gli $11,55 misurati' if im > 0 else 'IMPOSSIBILE: IM negativa'}") + print(" → terza conferma del 5%, ed e' la prima ESATTA. Il 10% non e' improbabile:" + "\n e' aritmeticamente impossibile.") + + riserv = GW_MB - GW_AVAIL + hc = 0.05 * GW_USDE + print(f"\n [4] 🚨 l'\"IM %\" della pagina NON e' il margine delle posizioni") + print(f" (margin_balance - available)/margin_balance = {riserv/GW_MB:.4%}" + f" → la pagina stampa {PAG_IM_PCT:.2%}") + print(f" scomposta: haircut USDE ${hc:,.2f} ({hc/GW_MB:.3%})" + f" + IM vera ${IM_MIS:,.2f} ({IM_MIS/GW_MB:.3%})") + print(f" ⇒ il {hc/riserv:.0%} di quella percentuale e' HAIRCUT, non rischio.") + print(f" E' salita da 2,13% a 2,15% perche' abbiamo COMPRATO COLLATERALE A RENDIMENTO.") + print(f" La MM invece e' pulita: {PAG_MM_PCT:.2%} = ${PAG_MM_PCT*GW_MB:,.2f}, e non puo'" + f" contenere\n l'haircut (${hc:,.2f} da solo la renderebbe negativa):" + " le due colonne hanno basi DIVERSE.") + + print(f"\n [5] X:PM — il confronto rifatto sulla misura pulita") + print(f" La KB da' USDe al 5% sotto ENTRAMBI i modelli: l'haircut si CANCELLA nel confronto.") + for nome, av in (("X:SM", CROSS_XSM), ("X:PM", XPM_AVAIL)): + im = im_di_posizione(av, USDC_EQ, USDE_EQ, PX_INDICE, 0.05) + print(f" {nome}: available ${av:,.2f} → IM di POSIZIONE ${im:6,.2f}") + im_sm = im_di_posizione(CROSS_XSM, USDC_EQ, USDE_EQ, PX_INDICE, 0.05) + im_pm = im_di_posizione(XPM_AVAIL, USDC_EQ, USDE_EQ, PX_INDICE, 0.05) + print(f" → PM chiede {im_pm/im_sm:.1f}x il margine iniziale sulle STESSE due posizioni," + f"\n e {0.0343/PAG_MM_PCT:.1f}x la MM. Due misure pulite, stesso verso: SCARTATO confermato.") + + if __name__ == "__main__": raise SystemExit(main())