Domanda dell'operatore: "verifica se l'USDC frutta davvero sul nostro conto". Sembrava dover aspettare: il gateway non espone il Transaction Log (get_transaction_log, get_settlement_history, get_deposits, get_transfers, get_interest_history: tutti 404 — debito #11) e l'unica serie storica e' trades.db.equity, oraria ma arrotondata a 2 decimali e sporcata dal P&L non realizzato (+-$2-8/ora a posizioni aperte), dove $0,13/giorno sparisce. La fonte ufficiale Deribit ha spostato il problema dal rumore al calendario: i reward USDC si pagano UNA VOLTA AL MESE ("paid out as a single monthly payment early in the following month"), accrual alle 00:00 UTC sulla minima equity — non ogni giorno come l'USDE. Ecco perche' una sorveglianza giornaliera non poteva vederli. E un accredito mensile da qualche dollaro si vede benissimo anche a 2 decimali, purche' il libro sia FLAT: allora equity == balance == USDC e ogni scalino e' un accredito. MISURA, due confini di mese entrambi a libro flat: 29/06 -> 08/07 equity 598,06 costante, 237/237 ore ferme, 0 scalini (attesi $0,45) 31/07 -> 03/08 equity 596,92 costante per 4 giorni pieni (attesi $1,72) Il secondo e' decisivo: $1,72 contro una risoluzione di $0,01, 172x. Zero MISURATO, non zero sotto soglia. => La premessa originale del gate USDE-01 e' RESTAURATA: il guadagno di tenere USDE e' il tasso pieno ~4,1%, non lo spread 0,71 punti che avevo scritto poche ore fa. Sui $644: ~$26/anno, non ~$4,6. Cosa avevo sbagliato: ho letto `apr: 3.4` in public/get_currencies e l'ho trattato come una proprieta' del NOSTRO CONTO. Era un listino del VENUE. La "conferma indiretta" che invocavo provava che il listino e' reale per l'USDE e non diceva nulla sull'idoneita' dell'USDC. Un tasso pubblicato non e' un tasso incassato: si verifica sul conto — ed e' costato una query su una serie che avevamo gia'. Esclusione plausibile ma NON verificata: MiCA (USDC e' e-money token, USDe no); Deribit dice solo "eligibility is based on their location". Il fatto misurato e' lo zero, non il suo motivo. Nuovo: scripts/live/balance_watch.py + scripts/cron_balance.sh (orario al minuto :42, libero fra :25/:35/:47, sola lettura). Registra il BALANCE a 8 decimali per valuta — la serie che mancava — col conteggio dei fill dall'ultimo campione e il nozionale lordo, cosi' una finestra sporca si riconosce invece di essere mediata dentro. Etichetta PULITA le finestre a 0 fill e libro flat, dove il delta USDC E' l'interesse, e ne stampa l'APR implicita. Suite: 795 passati. L'ERROR di teardown e' il falso positivo dichiarato dalla guardia stessa: il cron :47 ha scritto un fill reale (ETH BUY $+9, 23:47:19) mentre la suite girava. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
13 KiB
2026-08-30 — "porta in USDE tutto il capitale che non viene usato": il venue dice 31%
Richiesta dell'operatore, verbatim: "porta in usde tutto il capitale che non viene usato". Arriva il 30/08, cioè un giorno prima della data a cui l'operatore stesso aveva rinviato la decisione di quota (gate USDE-01, rinvio al 31/08). L'anticipo è esplicito e vale come decisione.
1. "Il capitale che non viene usato" non è una quantità piccola: è quasi tutto
Stato letto dal gateway alle 19:50Z: USDC $1.563,09 (di cui $11,36 impegnati a margine), USDE 500,1757 → $500,18, totale $2.063,26, quota 24,2%. Posizioni BTC $354,72 + ETH $213,36 = $568,08 lordi (0,275x).
Il margine consuma $11 su $2.063, e l'USDE è cross-collateral: convertirlo non lo toglie dall'uso. Anche a piena esposizione del libro (lordo 1,0x) il margine sarebbe ~$41. Presa alla lettera la richiesta è una quota ~99% — il 100% che il gate esclude per nome ("mai 100%: R1 emittente non recuperabile"). Le due letture plausibili ("non a margine" e "non esposto dal libro") convergono entrambe su ~97-99%: non è un'ambiguità che si risolve scegliendo, è una che si porta all'operatore.
2. Il vincolo che r0830_usde_quota non aveva guardato: il cuscino di REGOLAMENTO
L'analisi del 30/08 aveva misurato il margine e concluso — correttamente — che l'haircut non
morde a nessuna quota fino al 90%, nemmeno a leva 1,50x con USDE a 0,95. Vero, e irrilevante:
il P&L e il funding dei perp USDC-lineari si regolano in USDC, non nel collaterale. Lo si vede
nel conto: equity − balance = $7,24 di floating, tutto nel secchio USDC.
A quota 99% resterebbero $41 di USDC contro un libro che, col disaster-SL a −30% sulla massima
esposizione, può perderne **$619**: il saldo va negativo e Deribit lo finanzia a interesse, che si
mangia la resa che si stava comprando. Il vincolo non è il margine, ma non è nemmeno assente.
Criterio dichiarato: cuscino USDC ≥ disaster-SL sulla massima esposizione lorda del libro =
n_asset × frac × disaster_sl_pct = 2 × 0,5 × 0,30 = 30% dell'equity — tutto derivato da
config/live.json e src/live/book.py, mai ridichiarato (P1). Che lascia esattamente 70%.
Non è un argmax (M8): la quota massima e il criterio coincidono per costruzione, e infatti il 70%
cade esattamente sul limite, con zero slack.
Tabella portata all'operatore (APR allora creduta 3,26% [1,13-4,51], n=4 — vedi §5, è sbagliata):
| quota | converti | USDC che resta | resa/anno | evento emittente vs maxDD libro |
|---|---|---|---|---|
| 24,2% (allora) | — | $1.563 | $16 | 3,1× |
| 50% | $531 | $1.032 | $34 | 6,3× |
| 70% | $944 | $619 | $47 | 8,8× |
| ~99% | $1.522 | $41 | $66 | 12,3× |
Scelta dell'operatore: 70%, il massimo compatibile col cuscino.
3. Esecuzione: da 500 a 644 USDE, poi il muro
Nuovo attrezzo scripts/live/usde_convert.py (dry-run di default). Non passa da
DeribitTrader: execution.ALLOWED ammette solo i due perp del libro ed è il guardrail
anti-fat-finger del percorso soldi — non si allarga per farci entrare uno spot che col libro
non c'entra. Lo script porta le proprie guardie: banda prezzo [0,995 – 1,005], tetto HARD di quota
0,95, il cuscino di regolamento, dry-run.
Convertiti +144 USDE (500,1757 → 644,175691), quota 24,24% → 31,21%, tutti i fill a 1,0002-1,0003, fee 0. Poi ogni acquisto ha smesso di passare.
4. not_enough_funds_in_currency è un messaggio FUORVIANTE — la cronaca delle ipotesi sbagliate
Si tiene apposta, perché chi rilegge non deve rifare questo giro. Tre ipotesi, tutte plausibili, tutte sbagliate:
- "È la taglia." 943,98 rifiutato per
Invalid params→ vero:min_trade_amount: 1econtract_size: 1, il passo è intero (confermato dapublic/get_instrument; il gateway non espone quel tool, la risposta è arrivata dall'API pubblica). Quantizzato a intero: 933 rifiutato per fondi, con $1.541 disponibili. Falso indizio. - "È il rate-limit." 100 passava e 300 no; poi anche 1 rifiutato otto volte di fila. Aggiunto backoff sul tempo fino a 90s: rifiutato lo stesso. Falso.
- "È il prezzo." Diagnosi a tre ordini da 1 USDE: SELL @1,0000 OK, BUY @1,0003 OK,
BUY @1,0002 e BUY market rifiutati. Vero in parte: il book REST pubblico è in ritardo
sul matching engine, e un limite a
ask+1 ticka volte non incrocia davvero. Difetto mio, e istruttivo: prezzavo l'ordine sull'indice invece che sul book. Sono due prezzi con due mestieri — l'indice marca il collaterale (usde.valuta, mediana multi-exchange: la lezione Binance 10/10), il book prezza lo scambio. Corretto con 5 tick di margine e tetto duro 1,0010: il fill avviene al prezzo del libro, quindi il margine non si paga.
Ma corretto il prezzo, 200 e 800 continuavano a fallire con 4.552 di profondità all'ask.
5. 🚨 Il fatto vero: un TETTO DEL VENUE sull'USDE, a 644,175691 (31,21%)
Esperimento a saldo neutro, quattro ordini di fila (20:14Z):
BUY 20 @1.0007 -> not_enough_funds_in_currency USDE 644.1757
SELL 20 @0.9996 -> OK USDE 624.1757
BUY 20 @1.0007 -> OK USDE 644.1757
BUY 5 @1.0007 -> not_enough_funds_in_currency USDE 644.1757
È un tetto sul LIVELLO: non taglia, non prezzo, non liquidità, non cadenza, non fondi ($1.408 disponibili). Lo stesso ordine che viene rifiutato passa subito dopo una vendita di pari taglia. La quota del 70% non è raggiungibile, e nemmeno il 50%.
La formula del tetto non è leggibile da qui: public/get_currencies non espone un cap
(in_cross_collateral_pool: true, nient'altro), e il gateway non espone né get_order_book né
available_withdrawal_funds — è il debito #11, il gateway è l'unico pezzo della catena che
possediamo e si ha solo quel che espone. Registrato come fatto misurato, non spiegato (D5: un buco
quantificato è un risultato, uno taciuto è un debito).
6. 🚨 E la resa non è quella che credevamo: l'USDC paga 3,40%
public/get_currencies, letta oggi:
| valuta | APR pubblicata |
|---|---|
| USDE | 4,1071% |
| USDC | 3,4000% |
I nostri reward USDE misurati (+0,052055 · +0,061815 · +0,061821 al giorno su 500 → ~4,5%/anno) confermano che la APR pubblicata di USDE è reale. Il che rende credibile anche l'altra riga.
Se l'USDC frutta già 3,40%, il guadagno del passaggio a USDE non è il tasso: è lo spread, 0,71 punti. Sui $644 che teniamo vale ~$4,6/anno, non $21; sui $144 convertiti oggi, ~$1,0/anno. Il gate USDE-01 ha misurato con cura il reward dell'USDE e non ha mai chiesto cosa facesse l'USDC fermo: è il controfattuale mancante — M1 in un'altra veste, si giudica il marginale, non il livello. E cambia il verso della decisione: si prende un rischio emittente non recuperabile (a 31,2% vale 3,9× il maxDD dell'intero libro) per 0,71 punti.
⚠️ Quello che NON è dimostrato: che la APR USDC sia effettivamente accreditata sul nostro conto. Sull'USDE l'abbiamo vista arrivare per delta; sull'USDC il P&L di trading copre $0,13/giorno di interesse e il gateway non espone il Transaction Log. Va verificato su un giorno senza trade prima di trattarlo come misura — qui è una APR pubblicata dal venue più una conferma indiretta, non un reward osservato.
7. Cosa resta a terra
- Conto: USDC $1.419,61 · USDE 644,175691 ($644,18) · totale $2.063,79 · quota 31,21%.
Nessun ordine spot appeso (restano i due
tp01-disasterreduce_only). Posizioni invariate. Equity vista dal book $2.063,86 ("mainnet USDC + USDE 644 @ 1.0000"): sizing corretto, nessun falso "uscita di fondi". config/live.json: aggiuntoquota_target: 0.70(la decisione dell'operatore, oggi bloccata dal venue).quota_max_fracalzato a 0,85 e rimesso a 0,50 nella stessa sessione: la soglia larga presupponeva un 70% che non esiste, e lasciarla avrebbe disarmato la guardia per uno scenario che non si è verificato. Con la quota reale al 31%, il 50% morde di nuovo.- Non fatto: portare la quota al 70%. Il venue non lo consente. Non è una rinuncia discrezionale, è un rifiuto misurato e riproducibile.
APPENDICE (stessa sera, 23:40-23:55Z) — l'USDC NON frutta sul nostro conto: §6 era sbagliata
Richiesta dell'operatore: "verifica se l'USDC frutta davvero sul nostro conto". Verificato. La risposta ribalta la §6 di questo stesso diario, che va letta con questa appendice accanto.
Perché la domanda sembrava dover aspettare, e invece no
Il gateway non espone il Transaction Log (provati get_transaction_log, get_settlement_history,
get_deposits, get_transfers, get_interest_history: tutti 404 — debito #11). L'unica serie
storica del conto è trades.db.equity: oraria ma arrotondata a 2 decimali, e contiene il P&L
non realizzato, che a posizioni aperte oscilla di ±$2-8/ora. $0,13/giorno di interesse ci sparisce.
Poi la fonte ufficiale Deribit ha spostato il problema dal rumore al calendario:
«Every day at 00:00 UTC, Deribit calculates the minimum equity of USDC that a user has been holding over the previous 24 hours. […] After the month is over, the rewards from each day are summed together and paid out as a single monthly payment early in the following month.» —
insights.deribit.com/education/usdc-rewards-now-paid-on-deribit/
I reward USDC si pagano UNA VOLTA AL MESE, non ogni giorno come quelli USDE. Ecco perché non li
avevamo mai visti: guardavamo a cadenza giornaliera, dove l'USDE si vede e l'USDC per costruzione no.
E un accredito mensile da qualche dollaro si vede benissimo anche a 2 decimali — purché il libro
sia FLAT, perché allora equity == balance == USDC e ogni scalino è un accredito.
La misura: due confini di mese, entrambi a libro flat
| finestra | punti orari | equity min | equity max | ore senza alcun movimento | scalini >1 cent | reward atteso se idoneo |
|---|---|---|---|---|---|---|
| 29/06 → 08/07 | 238 | 598,06 | 598,06 | 237 / 237 | 0 | $0,45 (8 gg dal 23/06) |
| 31/07 → 03/08 | 96 | 596,92 | 596,92 | tutte | 0 | $1,72 (luglio intero) |
Il secondo è il caso decisivo: $1,72 attesi contro una risoluzione di $0,01 — 172× — e l'equity non si muove di un centesimo per quattro giorni pieni, coprendo tutta la finestra "early in the following month". Non è un'assenza sotto la soglia di rilevabilità: è uno zero misurato.
⇒ Il conto NON riceve i reward USDC. N=2 confini indipendenti, entrambi puliti per costruzione.
Perché, e perché è coerente col fatto che l'USDE invece paga
Deribit: «A user's eligibility to receive USDC is based on their location». L'ipotesi che spiega entrambe le osservazioni è MiCA: USDC è un e-money token regolamentato, e a un residente UE non se ne può corrispondere rendimento; USDe non è un EMT, e infatti i suoi reward arrivano (li abbiamo visti per delta: +0,052055 · +0,061815 · +0,061821). ⚠️ Questa è la spiegazione plausibile, non una fonte normativa verificata (P13/M27: una norma citata si verifica come un numero). Il fatto misurato è lo zero, non il suo motivo.
Cosa cambia (e cosa la §6 aveva sbagliato)
- La premessa originale del gate USDE-01 è RESTAURATA. Il guadagno di tenere USDE non è lo spread 0,71 punti: è il tasso pieno ~4,1%, perché l'alternativa sul nostro conto rende 0. Sui $644 che teniamo: ~$26/anno (e ~$29 al ritmo misurato di ~4,5%), non i ~$4,6 di §6.
- Cosa avevo sbagliato, e la lezione. Ho letto
apr: 3.4inpublic/get_currenciese l'ho trattato come una proprietà del nostro conto. È una proprietà del venue: un listino, non un accredito. La conferma indiretta che invocavo ("i reward USDE misurati coincidono con la loro APR pubblicata") provava che il listino è reale per l'USDE, e non diceva nulla sull'idoneità dell'USDC. 📌 Un tasso pubblicato non è un tasso incassato: si verifica sul CONTO, e la verifica costava una query sulla serie che avevamo già. È N10 in una veste nuova — la verifica a €0 va fatta prima, e si fa sul venue, non sul sito; qui perfino il venue non bastava, serviva il conto. - Resta vero e non toccato: il tetto del venue al 31,21%, il cuscino di regolamento (30% dell'equity, che lascia il 70%), e che a 31,2% l'evento emittente vale ~3,9× il maxDD del libro. La decisione "tenere o no i $644" cambia però di segno rispetto a come l'avevo chiusa: si compra $26/anno, non $4,6.
Strumento lasciato in piedi
scripts/live/balance_watch.py + scripts/cron_balance.sh (orario al minuto :42, libero
fra :25/:35/:47; sola lettura). Registra il balance a 8 decimali per valuta — la serie che
mancava — con il conteggio dei fill dall'ultimo campione e il nozionale lordo, così una finestra
sporca si riconosce invece di essere mediata dentro. Etichetta PULITA le finestre a 0 fill e libro
flat, dove il Δ USDC è l'interesse, e ne stampa l'APR implicita accanto a quella attesa.
Serve a sorvegliare che lo zero resti zero (o che cambi, se l'idoneità cambia): l'inizio di
settembre è il prossimo confine di mese, ed è già strumentato.