Commit Graph

649 Commits

Author SHA1 Message Date
Adriano Dal Pastro 41f83b5dd8 BUIDL-01 CHIUSO: non entrabile — e la frase pubblicata da Deribit e' falsa per noi
Esito del test pre-registrato dieci minuti prima (7b8e356). Si chiude con un esito
che NON era fra i due previsti: i criteri contemplavano ">=1 reward -> IDONEO" e
"zero reward -> NON IDONEO", ma non si riesce a comprare BUIDL affatto, quindi la
domanda sull'eligibilita' ai reward e' priva di oggetto. Un gate puo' fallire sulla
sua PRECONDIZIONE invece che sul suo criterio, e va scritto cosi'.

Undici ordini rifiutati con not_enough_funds_in_currency, fino a 1 unita' a limite
1,0100 contro ask 1,0004 con 10.730 di profondita', tenendo ZERO BUIDL e avendo
$1.412 disponibili per comprarne $1. Esclusi uno per uno tutti i sospetti che
sull'USDE avevano portato fuori strada: prezzo (incrocia di 96 bps), liquidita',
taglia (il minimo dello strumento), fondi, tetto sul livello (teniamo zero), wallet
(account_summary risponde). Costo del test: $0, nessun fill.

🚨 "All Deribit users are permitted to buy and sell BUIDL tokens in the spot markets
on Deribit, with no extra requirements" — insights.deribit.com. NON per noi.
Motivo plausibile e non verificato: BUIDL e' un titolo (fondo BlackRock via
Securitize), distribuzione ristretta a monte dell'exchange. Il fatto misurato e' il
rifiuto, non il suo motivo.

REGOLA (due affermazioni pubblicate smentite dal conto in due giorni — APR USDC
3,40% e "all users can buy BUIDL"): una capacita' PUBBLICATA dal venue non e' una
capacita' del CONTO. Si verifica sul conto, prima che entri in un piano, e costa un
ordine da $1. E' N10 un passo piu' in la': non basta il sito, non basta il venue,
serve il conto.

SOTTOPRODOTTO che vale piu' del test: not_enough_funds_in_currency e' il messaggio
GENERICO di Deribit per "non puoi acquisire altra di questa valuta" — permesso
(BUIDL, zero in mano) o tetto (USDE, ~31,2% dell'equity), mai i fondi. Chi lo
incontra salti subito alla domanda giusta invece di inseguire taglia, cadenza e
prezzo come e' successo il 30/08.

=> L'USDE resta l'unico collaterale a rendimento che il conto puo' usare, ed e' al
suo tetto; i $1.412 di USDC continuano a rendere zero. Non per mancanza di
alternative: le tre alternative sono chiuse per giurisdizione (USDC), per permesso
(BUIDL) e perche' non e' un dollaro (stETH).

balance_watch esteso a BUIDL: se l'accesso si aprisse, un balance non nullo lo
direbbe da solo. Suite: 795 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:35:32 +00:00
Adriano Dal Pastro 7b8e35633d BUIDL-01: criteri pre-registrati PRIMA dell'esecuzione e dell'esito
Test di eligibilita' sul collaterale BlackRock (Treasury USA tokenizzati), taglia
500 BUIDL come il test USDE del 26/08. Nasce dalla domanda su stETH: stETH rende
2,22% (meta' dell'USDE) ed e' ETH, non un dollaro — coprirlo e' CC01, gia'
parcheggiato a scala 20k+. I custodi sono istituzionali e comunque nessuna via
custodiale restituisce i reward USDC (esclusione italiana per giurisdizione).

BUIDL invece e' comprabile, liquido, in cross-collateral, e soprattutto e' un
emittente DIVERSO: oggi il conto ha $1.412 di USDC che rendono zero e il rischio
emittente concentrato al 100% su Ethena.

Criteri dichiarati adesso, esito da leggere il 2026-09-04:
  ELIGIBILITA': >=1 reward entro le 23:00 UTC del 03/09 -> IDONEO; zero -> NON
  IDONEO, si riconverte e la pista si chiude. Tre finestre feriali piene.
  TETTO: sondato a saldo neutro, registrato col suo bracket E l'equity del
  momento (sull'USDE il tetto e' una frazione, non un livello).
  HAIRCUT: dichiarato NON misurabile a questa taglia, e non vincolante.

Committato PRIMA dell'esecuzione: l'ordine dei fatti sta in git.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:30:40 +00:00
Adriano Dal Pastro f151316bdf usde: il tetto e' una FRAZIONE dell'equity (~31,2%), non un livello — e ora e' in config
Fonte: articolo ufficiale Deribit "Yield/reward bearing coins" (WebFetch lo prende
403, si legge dall'API Help Center in JSON). Tre correzioni alle conclusioni di
ieri.

1) L'ITALIA e' nella lista delle giurisdizioni escluse dai reward USDC. Lo zero
misurato e' confermato dalla fonte, ma la mia ipotesi MiCA era SBAGLIATA: la
lista contiene Canada e Giappone, non e' il perimetro MiCA. E' policy di
giurisdizione Deribit. M27: una fonte normativa si verifica, non si deduce.

2) La finestra di pagamento USDC e' di DUE SETTIMANE ("within the first two
weeks of the following month"), non tre giorni. Avevo verificato su 8/14 e 3/14
giorni. Rifatto sulle finestre vere: LUGLIO conclusivo (atteso $1,72 contro
un'escursione TOTALE dell'equity di $0,48 in 1-16/08, zero scalini compatibili),
GIUGNO no (il libro opera da meta' mese, rumore della taglia del segnale). La
conclusione non cambia, ma l'evidenza e' UNA finestra piu' la lista ufficiale,
non due: il "172x" del 30/08 era sovra-affermato.

3) IL TETTO NON E' UN LIVELLO, E' UNA FRAZIONE. L'articolo documenta un Cap
ETHENA che diluisce il TASSO a livello di exchange e nessun limite sulle
quantita' detenibili: il muro non aveva base documentale e andava ri-sondato.
Fatto il 31/08 (giorno UTC nuovo -> non e' un limite giornaliero): ieri si
tornava a 644,18, oggi no, con l'equity scesa di $8.
    30/08  tetto [644,18 · 645,18)  equity $2.063,79  = 31,21-31,26%
    31/08  tetto [643,18 · 644,18)  equity $2.055,56  = 31,29-31,34%
0,05pp di scarto, dentro il rumore dell'equity (+-$2-8/ora). Candidato pulito
5/16 = 31,25%, ma a questa risoluzione non si distingue da una regola sul
collaterale scontato dell'haircut (~29%): si cita la banda (M25).
=> Il tetto SCALA col conto: la quota resta ~31%, il valore in dollari cresce
col capitale, il 70% non e' raggiungibile ne' ora ne' mai. E, essendo pinnati
al tetto, il rischio emittente resta una frazione COSTANTE del conto.

Cablato (rispondeva a "dove e' scritto il valore del tetto": in tre note di
testo e in nessun posto che il codice leggesse, tanto che usde_convert --quota
0.70 dichiarava "piano valido" per un ordine che il venue rifiuta):
  - config/live.json usde.venue_cap_frac 0.312 + venue_cap_misurato
  - src/live/usde.py lo porta nei default (unica autorita', P1)
  - usde_convert.piano() rifiuta il bersaglio sopra il tetto PRIMA di sparare
    e stampa il massimo raggiungibile. Verificato su entrambi i rami.

Anche: l'USDe ha un fee Deribit del 5% mai nominato prima. Il nostro misurato
(~4,5%/anno) e' gia' netto: e' l'unico numero da citare.

Stato: USDE 643,175691 (31,29%, al tetto), USDC $1.412,40, totale $2.055,57.
Suite: 795 passati.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:27:23 +00:00
Adriano Dal Pastro c250c04371 usde: l'USDC NON frutta sul nostro conto — misurato, e §6 di stasera era sbagliata
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>
2026-08-30 23:48:52 +00:00
Adriano Dal Pastro a45794d2cb usde: il venue mette un TETTO al 31,21% — e l'USDC paga gia' 3,40%
Richiesta dell'operatore: "porta in usde tutto il capitale che non viene
usato". Il margine consuma $11 su $2.063 e l'USDE e' cross-collateral: preso
alla lettera vale una quota ~99%, cioe' il 100% che il gate esclude. Portata
all'operatore con le cifre, ha scelto 70%.

Il 70% non e' un argmax (M8): e' il massimo compatibile col CUSCINO DI
REGOLAMENTO, il vincolo che r0830_usde_quota non aveva guardato. P&L e funding
dei perp USDC-lineari si regolano in USDC, non nel collaterale, quindi la
quota non la limita l'haircut ma il saldo USDC che deve reggere il disaster-SL
sulla massima esposizione: 2 x 0,5 x 0,30 = 30% dell'equity, che lascia il 70%.

ESEGUITO +144 USDE (500,1757 -> 644,175691), quota 24,24% -> 31,21%, fee 0.
Poi il muro.

(a) TETTO DEL VENUE, misurato e non documentato da nessuna parte. Provato a
saldo neutro: BUY 20 rifiutato, SELL 20 OK, BUY 20 OK, BUY 5 rifiutato, con
$1.408 disponibili. E' un tetto sul LIVELLO. Il messaggio del venue
(not_enough_funds_in_currency) e' fuorviante e ha fatto inseguire tre ipotesi
sbagliate: taglia (falso, ma min_trade_amount=1 e' vero), rate-limit (falso),
prezzo (vero in parte: il book REST pubblico e' in ritardo sul matching engine
e prezzavo l'ordine sull'INDICE invece che sul BOOK — l'indice marca il
collaterale, il book prezza lo scambio). La cronaca resta nel diario: chi
rilegge non deve rifare il giro.

(b) L'USDC PAGA 3,40%. public/get_currencies: USDE 4,1071%, USDC 3,4000%, e i
nostri reward USDE misurati (~4,5%/anno) confermano che quelle APR sono reali.
Il guadagno non e' il tasso, e' lo SPREAD: 0,71 punti, ~$4,6/anno sui $644 che
teniamo, non i $21 che il gate implicava. Il gate ha misurato il reward
dell'USDE e non ha mai chiesto cosa facesse l'USDC fermo: manca il
controfattuale, M1 in un'altra veste. NON dimostrato che sia accreditato sul
nostro conto — da verificare su un giorno senza trade.

Nuovo attrezzo scripts/live/usde_convert.py: dry-run di default, banda prezzo,
tetto hard di quota, cuscino di regolamento derivato da config. NON passa da
execution.ALLOWED, che resta ai soli due perp.

config: quota_target 0.70 registrato; quota_max_frac alzato 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 e'
verificato.

Suite: 795 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 20:18:31 +00:00
Adriano Dal Pastro 3cf884fa39 CLAUDE.md: la riga USDE-01 cita il tasso con la sua banda — 3,26% [1,13-4,51], n=4
Citava "3,80% su UNA finestra, 1,90% su DUE": due letture di n=1 e n=2, senza banda,
cioe' esattamente cio' che la §2 vieta. A quattro finestre il numero e' 3,26% annuo
con banda bootstrap [1,13% - 4,51%], e la larghezza (3,4 punti su un livello di 3,2%)
E' il risultato: a n=4 il tasso non e' misurato.

Aggiunto il risultato che governa la decisione di domani: l'EV e' lineare in q, quindi
non puo' scegliere una quota interna. E i tre numeri che la incorniciano: il margine
non e' il vincolo (l'haircut non morde fino al 90% di quota, nemmeno a leva 1,50x con
USDE marcato alla soglia critica 0,95 — 29x di cuscino), la resa vale $16/anno cioe'
meno di un mese di versamento, e aspettare quattro settimane costa $1,33 per 8x le
finestre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1gJmWPA4rEhmc6CQQuNZw
2026-08-30 17:41:14 +00:00
Adriano Dal Pastro 035bd086a2 usde: l'EV non puo' scegliere la quota — e aspettare 4 settimane costa $1,33
La decisione di quota e' dovuta lunedi' 31/08. Il risultato strutturale, dichiarato
prima di guardare i numeri: l'EV e' LINEARE in q, quindi il suo argmax e' sempre un
angolo (0% o 100%) e non puo' produrre una quota interna. Ogni quota intermedia nasce
da un criterio sulla CODA, che va dichiarato e non ottimizzato (M8). Lo script quindi
non sceglie: mette il prezzo accanto a ogni criterio candidato.

Misure:
- rendimento 3,26% annuo su n=4 finestre (3 pagate), banda bootstrap 95%
  [1,13% - 4,51%] su 200.000 ricampionamenti. Larga 3,4 punti su un livello di 3,2%:
  a n=4 il tasso non e' misurato, e' abbozzato. Il punto stimato si DERIVA da
  usde_watch.rendimento() invece di essere ridichiarato (P1), e la divergenza fra i
  due denominatori (0,06 punti) e' stampata, non appianata (P12).
- l'hazard annuo di pareggio E' l'APR: la quota e' EV-positiva se e solo se si crede
  che Ethena stia sotto il 3,3%/anno di evento catastrofico. Numero ASSUNTO, non
  stimato, come il p di Deribit del 26/07 — il cui framework P=1-(1-p)^20 lo script
  riproduce prima di usarlo (10/18/33/64% contro 10/18/34/64% registrati).
- il haircut 10% NON morde a nessuna quota testata, fino al 90%: il libro gira al
  2,00% di margine ($11,37 su $568,64), tre ordini di grandezza sotto il collaterale.
  Il vincolo non e' il margine (D5: buco quantificato e innocuo).
- il churn da depeg critico vale ~$52 di nozionale a quota 50%: secondo ordine.

Il numero che decide (N10 — una data si giustifica col COSTO della misura): la
conversione e' fee 0 e ~3 bps di spread, quindi la decisione e' reversibile a
~6 bps. Alzare a 50% fra quattro settimane invece che domani costa $1,33 di resa non
incassata e porta il campione da 4 a 32 finestre, stringendo la banda da ~3,4 punti
a ~1,2.

Due letture del rischio che non si annullano (M28): l'USDE fa perdere soldi solo nel
mondo in cui Ethena salta E Deribit sopravvive, quindi il rischio aggiunto e' di
secondo ordine — ma e' un terzo strato sullo stesso conto, e N4 dice che un rischio
di venue si compra con un secondo CONTO. La prima dice che costa poco, la seconda
che non e' li' che si compra sicurezza.

Verdetto a runtime: risoluzione insufficiente per alzare · nessun vincolo operativo ·
scala (la resa di oggi vale $16/anno, meno di UN mese di versamento: la leva binding
resta il bonifico) · asimmetria (gia' a 24,2% l'evento emittente vale 3,1x il maxDD
dell'intero libro) · reversibile e quasi gratis da rimandare.

La scelta resta dell'operatore: lo script mette i prezzi, non ne sceglie uno (N4).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1gJmWPA4rEhmc6CQQuNZw
2026-08-30 17:38:35 +00:00
Adriano Dal Pastro fc24ee5f52 journal: voce COMPLETA del 29/08 sostituisce la parziale — 24/24 giri
Il cron notturno (00:37Z del 30/08) ha riscritto la pagina come annunciato
dalla versione parziale. I numeri di GIORNO passano dalla frazione di 7 giri
al giorno intero: equity $2,056.87 (era $2,051.29), P&L giorno +$4.51 (era
-$1.07), trading cumulato +$59.42, DD dal picco -0.81%.

Implicita ancora sotto la realizzata su entrambe le gambe (BTC 37.4 vs 44.0,
ETH 51.1 vs 68.9), DVOL al 19° e 18° percentile dell'anno: VRP01 resta fermo
per costruzione, IV-rank 0.07 e 0.12 sotto la soglia 0.30 del gate.

Aggiunta la sezione Analisi (agente), assente nella parziale. Salute pulita:
24/24 giri di book_execute, feed SKH a 0 min.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E1gJmWPA4rEhmc6CQQuNZw
2026-08-30 13:11:48 +00:00
Adriano Dal Pastro bb33df472f journal: voce PARZIALE del 29/08 — implicita al 24° e 17° percentile, VRP01 resta fermo
Scritta a mano alle 06:49Z, quindi marcata PARZIALE: copre 7 giri su 24 e non si
aggiorna da sola. Il cron la riscrive completa dopo le 00:30 di domani.

Equity $2.051,29, nozionale $555, leva 0.27x. Giornata -$1,07 su 7 letture, 1 fill
e 1 round-trip (+$0,02 netto). Cumulato dall'arming +$1.453,23, di cui $1.399,39
versati -> trading +$53,84. Entrambe le gambe a target, SKH01 flat su tutte e due:
il rischio resta interamente TP01.

Due cose che la Lettura tira fuori:
- l'implicita e' crollata in un giorno — DVOL BTC dal 47° al 24° percentile di un
  anno, ETH dal 45° al 17° — MENTRE la realizzata 30g saliva (44,1% e 68,9%). E'
  lo spread in cui vivrebbe VRP01, ma il suo gate guarda l'IV-rank espandente
  (0,09 e 0,12 contro una soglia di 0,30) e tiene lo sleeve fermo: dice di no
  esattamente dove l'occhio direbbe di si', ed e' per questo che esiste.
- prima comparsa della riga [drawdown]: -1,08% dal picco di $2.073,59, con la sua
  avvertenza attaccata (letture ORARIE, non minimo intra-giorno: e' un pavimento).

Campo `nota` lasciato vuoto: e' dell'operatore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 06:51:22 +00:00
Adriano Dal Pastro 993d17556a usde: gate CHIUSO IDONEO, quota rinviata a lunedi' — l'APR si legge col suo n
Il 2026-08-28 12:35Z `usde_watch` ha rilevato il primo reward (+0.052055 USDE su
500), e la regola pre-registrata il 26/08 PRIMA dell'esito ha chiuso il gate
USDE-01 su IDONEO. Si apre la decisione di QUOTA, che e' dell'operatore.

DECISIONE DELL'OPERATORE (29/08): la quota si decide lunedi' 31/08, su tre-quattro
finestre invece che su una. Il motivo e' un numero: sul solo pagamento il tasso
implicito e' 3,80% annuo, su DUE finestre — il 27/08 aveva pagato ZERO — e' 1,90%.
Fra i due c'e' tutta la decisione, e il campione e' UN pagamento.

`rendimento()`: APR sulle finestre OSSERVATE, col denominatore sul TEMPO VERO e
non sul numero di finestre pagate — cosi' una finestra che non paga ABBASSA la
stima invece di sparire (P5: quel silenzio e' uno zero). Le letture con trade nel
mezzo si escludono, non si riparano in silenzio (P12). L'APR si stampa sempre col
suo `n`, e sotto 4 finestre la riga dice «un pagamento non e' un tasso». Sulle
letture vere: 1,97% annuo su 1,9 giorni, 1/2 finestre pagate.

`quota_da_decidere()`: vera SOLO se IDONEO E il rinvio e' scaduto. Da lunedi' il
watch manda il 📌 OGNI giorno — quota attuale, tetto di allerta, APR osservato —
finche' non si decide (N9: una decisione rinviata senza promemoria e' rinviata per
sempre). Stesso schema della soglia $15k di GTAA01, con la data al posto del
capitale. Si smette togliendo `DECISIONE_QUOTA_DAL`.

6 test nuovi, incluso il controllo positivo — «la finestra sola darebbe il doppio»
— che e' esattamente la ragione per cui l'APR non si cita senza il suo n.

CONFERMATO il fix IB di ieri: il giro delle 00:30 ha 0 righe
`orders request timed out` (erano 2 per giro, 63 su 63) e tutti e sei gli ETF
scaricati. E una conferma involontaria del debito §5.13: SPY e' passato da
1996-09-04 a 1996-09-05 — la finestra rotolante ha perso un altro giorno in una
notte, come misurato.

Diario: docs/diary/2026-08-29-usde-idoneo-e-ib.md
Suite: 795 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 06:45:47 +00:00
Adriano Dal Pastro 2beb11b764 fetch IB: client in readonly — via due righe d'errore da 63 notti su 63
`fetch_ib_equities.py` si connetteva senza `readonly`, e ogni notte il log del
cron si prendeva

    open orders request timed out
    completed orders request timed out

126 righe in 63 giri. Due errori innocui ripetuti per sempre sono il modo in cui
un errore VERO smette di farsi notare (P14): su `cron_daily.log`, 126 dei 146
match di "error" erano questi.

CAUSA, letta nel sorgente di ib_async e non indovinata: in `IB.connectAsync` le
richieste "open orders" e "completed orders" esistono SOLO se il client non e'
readonly (`if not readonly: reqs[...]`), e sul gateway paper non rispondono.
Questo client scarica storico e non manda ordini mai: `readonly=True` e' insieme
la cura del rumore e la dichiarazione corretta di cosa fa. Tolta la CAUSA, non
filtrato il messaggio — filtrarlo avrebbe nascosto anche il giorno in cui quel
timeout significasse qualcosa.

VERIFICATO con un A/B sul solo flag, contro il gateway vero:
  · readonly=False -> le due righe compaiono, e si apre sul gateway il dialogo
    modale "API client needs write access action confirmation" (visto nei log del
    container, resta su ~75s);
  · readonly=True  -> nessuna delle due righe, nessun dialogo.

⚠️ CIO' CHE NON E' STATO VERIFICATO, e va detto: in nessuna delle quattro prove
fra le 13:05 e le 15:35 UTC il gateway ha servito storico — 0 barre con ENTRAMBI
i flag, quindi la causa non e' questa modifica, ma non ho potuto confermare
end-to-end che il fetch continui a riportare barre. La conferma e' il log del
cron di stanotte: se SPY/QQQ/IWM/TLT/GLD/HYG tornano con le loro barre e senza
le due righe di timeout, e' a posto; se tornano tutti a 0, si revoca il flag.
Il fallimento e' comunque innocuo: con 0 barre lo script NON sovrascrive i
parquet (verificato: eq_spy/eq_qqq intatti dopo i tentativi falliti).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 13:31:22 +00:00
Adriano Dal Pastro 32e1649dcb test: la suite non parla piu' al canale di allarme vero
Difetto trovato addosso: `uv run pytest` mandava messaggi Telegram VERI sul
canale dell'operatore — cinque per giro, col testo delle fixture («Analisi di
ieri.», «rete KO», «Testo dell'agente.») sotto l'intestazione di una voce di
giornale del 21/08. Colpevoli i cinque test di `analista.CLI.scrivi()`, che non
passavano `telegram=False` e percorrevano `invia()` fino a `notifier.send()`.
`_cfg()` legge il token da `.env.mainnet`/`.env`: il fatto che non fosse
nell'ambiente non proteggeva niente.

NON E' COSMETICO. E' P9 al contrario — allarmi finti spesi su un canale che
deve restare credibile il giorno che l'allarme e' vero. Chi riceve cinque
messaggi identici a ogni giro di test impara a non aprirli, ed e' l'unico
canale da cui passano disaster-SL, uscita di fondi e venue giu'.

RIPARAZIONE STRUTTURALE, stessa lezione del watermark (§5.12): si blocca la
RETE in una fixture autouse, non si chiede a ogni autore di ricordarsi un
parametro. Un test che vuole davvero esercitare `send()` continua a funzionare
— patcha `urlopen` nel proprio corpo e vince su questo.

In piu' una guardia di sessione: bloccare non basta, un tentativo va TROVATO e
reso esplicito, o resta li' pronto a tornare vero il giorno che qualcuno cambia
il boundary. Validata su controllo positivo (M15): un test che chiama
`notifier.send()` fa fallire la sessione.

⚠️ E un difetto fatto e corretto nello stesso giro: la prima versione registrava
l'URL, che contiene il BOT TOKEN in chiaro — e quella lista finisce nel
messaggio di un assert, cioe' nell'output della suite e nei log. Ora si registra
solo "telegram sendMessage": serve sapere CHE si e' tentato, non VERSO DOVE.
Il token e' stato esposto una volta nell'output di quella verifica: va ruotato.

Suite: 789 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 13:04:19 +00:00
Adriano Dal Pastro 418f523be7 gtaa: la decisione tenere/bloccare va a $15k — gate (A) ritirato, soglia sorvegliata
Decisione dell'operatore: GTAA01 NON si blocca oggi, si decide quando il book
arriva a $15k. Il motivo registrato non e' «non contribuisce» — la misura dice
il contrario (+0,095/+0,124 di Sharpe a iso-rischio secondo la fase, positivo in
tutte e cinque, hold-out +0,247, 6 anni su 8, correlazione col resto +0,087).
Il motivo e' che sotto $15k di book lo sleeve NON E' ACCENDIBILE:
GTAA_MIN_CAPITAL e' $3.000 allocati, che al peso 20% fa $15.000 contro i $2.068
attuali. Finora era manutenzione senza beneficio incassabile.

Registrate anche le due ragioni contro il blocco, che restano valide: N7 (uno
sleeve difensivo si giudica sul sinistro, e questa finestra non lo contiene) e
N4 (togliendolo il portafoglio di ricerca diventa 100% cripto su un venue solo).
E il costo che sarebbe andato pagato: GTAA01 e' uno dei quattro nomi di
W_DEPLOY, da cui escono i $313k del muro.

PERCHE' LA DECISIONE NON SI DIMENTICHI (N9). Una decisione parcheggiata su un
numero che nessuno sorveglia e' parcheggiata per sempre. `journal.SOGLIE_CAPITALE`
legge l'equity ogni giorno — il giornale lo fa comunque — e il giorno che supera
la soglia la voce dice quale decisione si sblocca e perche'. Seconda riga: $20k,
dove si riapre «100% Deribit fino a $20k». Una riga si TOGLIE quando la decisione
e' presa. 5 test, incluso «equity non leggibile non e' una soglia superata» (P5).

GATE (A) RITIRATO come pass/fail, congelando il MOTIVO e non l'esito — come il
07/08 col confronto fra ranghi, e per la stessa ragione: il criterio decide su un
margine piu' piccolo del rumore che lo scuote. In piu' una guardia sulla CAUSA
(`test_la_fase_di_ribilanciamento_e_ancora_ancorata_alla_POSIZIONE`) che si rompe
il giorno che qualcuno ancorasse la fase al calendario: quel giorno il gate
potrebbe tornare decidibile, ed e' un fatto da guardare, non da ignorare.
Il test sul margine assoluto si e' auto-ritirato: diceva «se scendesse sotto un
centesimo questo criterio smetterebbe di essere una misura», ed e' sceso a 0,0074.

CLAUDE.md: §3 nuova riga · §5.2 RISOLTO (trasporto allarmi) · §5.4 riscritto (la
domanda fiscale (a) ha una risposta alla fonte: derivati in c-quater al 26%, non
c-sexies al 33% — Circolare AdE 30/E del 27/10/2023, citata verbatim) · §5.13
nuovo debito, la fase che ruota — quantificata e dichiarata INNOCUA oggi (D5):
0,029 di Sharpe a livello di portafoglio, dentro la banda [1,81-2,12].

Diario: docs/diary/2026-08-28-gtaa-fase-e-allarmi.md
Suite: 789 passati, 0 falliti.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 12:54:08 +00:00
Adriano Dal Pastro 21fe289383 research(gtaa): cosa cambia togliendo GTAA01 — +0.11 di Sharpe a iso-rischio, sul filo
Misura chiesta prima di decidere del gate (A): se togliere lo sleeve non
cambiasse niente, la domanda sul gate sarebbe accademica. Portafoglio di
RICERCA a 5 sleeve (33/15/12/20/20), NON il book live (dove GTAA01 non c'e').

Due lenti, ed e' la seconda che decide (M6: un diversificatore a basso CAGR si
giudica a iso-rischio, mai a iso-nozionale; M5: "meno drawdown" si testa a
iso-rischio o si sta comprando de-levering):
  · iso-nozionale: CON Sh 2.28 CAGR +19.2% DD 6.1% vol 7.8%
                   SENZA Sh 2.16 CAGR +23.8% DD 7.8% vol 10.1%
    -> togliendolo si guadagna DRIFT e si compra VOLATILITA'.
  · iso-rischio (×0.77): SENZA Sh 2.16 CAGR +18.0% DD 6.0%
    -> Δ Sharpe +0.121, Δ maxDD +0.02pp.
Hold-out 2025+: Δ +0.247. Per anno: GTAA01 aiuta in 6/8. Correlazione col resto
del portafoglio +0.087 — e' davvero altro. Standalone Sh 1.06, CAGR +5.8%.

⚠️ E LA BANDA DI FASE, che e' la ragione per cui questo numero va citato con la
sua incertezza: il Δ sulle 5 fasi va da +0.095 a +0.124 e supera la soglia
dichiarata (0.12) in 2 fasi su 5. Il SEGNO e' stabile — GTAA01 aiuta in ogni
fase — ma il verdetto BINARIO dipende dalla notte in cui lo si legge. Sanity:
la fase 0 riproduce lo sleeve di produzione bit-exact (max|Δ| = 0.00e+00).

Lettura: il contributo e' reale e sempre positivo, e vale ~+0.11 di Sharpe, cioe'
ESATTAMENTE quanto lo spread fra le tre baseline che il progetto gia' si porta
dietro (0.12, §2). Non e' "GTAA01 e' inutile": e' "sta al limite di cio' che
questi dati risolvono".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 12:34:44 +00:00
Adriano Dal Pastro 801bd13f10 allarmi: il marcatore "gia' detto" si scrive DOPO l'invio, non prima
Debito §5.2 chiuso su decisione dell'operatore. `run_once` salvava lo stato coi
marcatori `alerted` gia' a True e l'invio lo faceva il chiamante DOPO: col 6,9%
di invii falliti misurato (2 su 29), un 🚨 perso restava perso per l'EPISODIO
INTERO — l'ora dopo lo stato diceva "gia' detto" e usciva WATCH/MUTO. Gli
episodi storici durano 200-2.324 ore, quindi il buco non era teorico.

- `run_once(state_path, sender=None)`: il sender e' INIETTATO, non importato —
  e' cio' che tiene la funzione testabile senza rete d'uscita, che era la
  ragione del disegno precedente. Senza sender il comportamento resta quello di
  prima e il report lo DICE (`invio`), invece di lasciar credere che qualcosa
  sia partito.
- Su invio fallito si disfano SOLO i marcatori "gia' detto", non le misure:
  · asset in ALERT -> alerted=False, l'ora dopo ri-allerta;
  · lock MAINT/ALERT -> alerted_soft/hard=False ma le ORE restano a correre,
    cosi' una manutenzione che sfora la grazia sale ad ALERT anche col trasporto
    giu' (disfare anche le ore congelerebbe l'escalation proprio mentre non si
    riesce a parlare);
  · lock RIENTRATO -> si ripristina l'intero LockState, perche' il rientro si
    annuncia una volta sola e senza le ore non ci sarebbe piu' niente da dire.
- `notify(..., tentativi=)`: il retry esisteva in `send` e non arrivava qui.
  venue_watch ora manda con 3 tentativi.
- L'esito dell'invio finisce nel log del cron invece di sparire.

5 test nuovi. Il primo e' quello che conta — dopo un invio fallito, l'ora dopo
ri-allerta — col suo controllo positivo (un invio riuscito consuma l'allarme
UNA volta sola), senza il quale "ri-allerta sempre" passerebbe.

Suite: 782 passati, 2 falliti (i due del gate GTAA, non toccati qui).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 12:34:44 +00:00
Adriano Dal Pastro c21a0d4058 research(gtaa): criterio (C) — la mediana delle 5 fasi regge come strumento, e sceglie il 60%
Analisi richiesta prima di decidere che fare del gate (A). Il criterio: a cadenza
di produzione, la banda si sceglie sulla MEDIANA delle 5 fasi di ribilanciamento
invece che sulla fase capitata (M7: su ancore appaiate la statistica e' la
mediana). Toglie la componente di FASE; resta quella di DATO.

⚠️ DICHIARATO IN TESTA ALLO SCRIPT: (C) e' stato scelto DOPO aver visto la
tabella delle fasi di r0828_gtaa_band_phase. Sceglierne uno nuovo guardando
l'esito del vecchio e' selezione. Quindi (C) misura lo STRUMENTO — risoluzione
e potenza — e NON valida la proposta del 27/07. Pavimento tenuto a 0.01, quello
che il test si diede il 07/08: il metro non si ritocca sul risultato.

ESITO, coi tre criteri calcolati a runtime:
  (i)   scelta stabile su 10 notti : SI — ['60%'] in tutte e dieci
  (ii)  margine sempre >= 0.01     : SI — minimo 0.0197 (fase singola: 0.0026,
        e sotto il pavimento in 4 notti su 10)
  (iii) potenza (in-sample ≠ hold-out) : SI — al buio 60%, sull'hold-out 40%
Lo strumento funziona: l'escursione dello Sharpe in-sample su 10 notti cala del
74-99% per ogni banda (60%: da 0.1120 a 0.0006).

MA LA CELLA CHE SCEGLIE NON E' LA PROPOSTA. Al buio esce il **60%**; il 25%
vince **0 notti su 10**. Da tenere accanto: sull'hold-out il 60% e' penultimo
(0.7430 contro 0.9315 del 40%), coerente con lo Spearman IS/OOS ~0 misurato il
07/08 — la scelta in-sample non predice, e non va letta come "la banda giusta".

CONTORNO che vale piu' del verdetto: le 5 serie di fase correlano **0.988**,
quindi N_eff = 1.01. La mediana di 5 fasi e' UNA osservazione: toglie
l'artefatto, non compra precisione. Va citata come robustezza alla fase, mai
come campione (§2: «positivo in N/N ancore NON e' N osservazioni»).

Nessuna decisione presa qui: il gate (A) non e' toccato e i due test restano
rossi in attesa della scelta dell'operatore.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:51:43 +00:00
Adriano Dal Pastro 31f82e1730 research(gtaa): il gate (A) della banda e' una moneta — la finestra "congelata" rotola ogni notte
Il 28/08 falliscono `test_la_banda_proposta_e_quella_scelta_al_buio` e
`test_il_margine_del_blind_non_e_un_arrotondamento`, a codice fermo dal 07/08
(nessun commit su src/portfolio/gtaa.py ne' su r0727_gtaa_band_gate.py). Al buio
esce il 60% invece del 25%, con margine 0.0074 — sotto il pavimento di 0.01 che
il test si era dato. Questo script chiede, per la terza volta sullo stesso
parametro, se il criterio misura cio' che dichiara. Replica bit-exact della
produzione verificata a fase 0 / taglio 0 (max|Δ| = 0.00e+00 su 7.544 barre).

(0) LA FINESTRA IN-SAMPLE NON E' FERMA. IB serve una finestra ROTOLANTE di 30
    anni. SPY e' l'unica gamba al muro (30.0 anni), e nel cron log la sua data
    d'inizio avanza di un giorno di borsa ogni notte: 1996-07-02 il 24/06,
    1996-09-04 oggi. Il pre-2015, che tutto il progetto tratta come finestra
    congelata, perde il giorno piu' vecchio ogni notte. QQQ e IWM arriveranno
    allo stesso muro fra 2,5 e 3,7 anni.

(1) L'AMPLIFICATORE E' LA FASE. `_gated_returns` ribilancia su `i % every == 0`,
    indice di POSIZIONE nell'array: se la prima barra scivola, si ri-fasa ogni
    decisione di trent'anni. Il progetto sapeva che la fase conta
    (`r0726_loo_deluck.gtaa01_at(ph)`, 5 ancore) ma la assumeva fissa alla
    canonica 0. Non lo e': la fase canonica cambia da sola ogni notte.

MISURE. Sulla finestra CHIUSA pre-2015, che non puo' acquisire dati nuovi, lo
Sharpe si e' mosso fino a 0.0760 fra il 07/08 e oggi. Su 10 notti consecutive
la banda scelta al buio e' 25% / 40% / 60% — la proposta vince il 40% delle
notti — e il margine sta sotto il pavimento in 4 notti su 10 (minimo 0.0026).
A dato FISSO, muovendo la sola fase, il verdetto cambia lo stesso (25% su 3
fasi, 60% su 2): l'imputato e' la fase, non le barre perse.

VERDETTO calcolato a runtime coi criteri dichiarati in testa (M13): il gate (A)
NON ha risoluzione. Il verdetto non e' una proprieta' della banda, e' una
proprieta' della notte in cui lo si legge. La banda al 25% non e' ne' confermata
ne' smentita: non e' decidibile cosi'.

Lo script misura e basta. Ritirare il criterio, come si fece il 07/08 col
confronto fra ranghi, e' una decisione dell'operatore e non e' presa qui.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:44:25 +00:00
Adriano Dal Pastro cb40ab3e20 journal: recuperata l'analisi del 27/08, saltata dal guasto di autenticazione
Rigenerata con `analista.py --giorno 2026-08-27 --no-telegram`. Le sezioni
misurate escono IDENTICHE (ricostruzione deterministica da trades.db e dal
feed): cambiano solo l'ora di scrittura in testata e la sezione `Analisi`,
che ora c'e'. Controllo sui numeri: ok.

`--no-telegram` di proposito: la notifica delle 00:37:02Z era partita e diceva
«analisi non disponibile (errore)». Quel record e' la prova che l'allarme del
guasto e' uscito, e riscriverlo con un invio di oggi la cancellerebbe.

L'analisi legge lo storico com'e' OGGI, non com'era stanotte: la testata porta
l'ora vera di scrittura (08:29:00Z), quindi la pagina non si spaccia per una
scritta a ridosso del giorno chiuso.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:32:41 +00:00
Adriano Dal Pastro 05a698a83e analista: il motivo di un guasto si prende da stdout E da stderr, o si perde
Il 2026-08-28 alle 00:37:00Z la CLI `claude` e' uscita 1 scrivendo
«Failed to authenticate: OAuth session expired and could not be refreshed»
su STDOUT, con stderr VUOTO. `interroga()` componeva il motivo dal solo
stderr, quindi nel DB e' finito `analisi_stato='errore'`,
`analisi_motivi='uscita 1: '` — e su Telegram e' partito
«analisi non disponibile (errore): uscita 1:».

La meccanica ha retto (nessuna analisi di ieri spacciata per quella di oggi,
esito registrato, notifica partita): a mancare era solo il PERCHE'. P4 —
un'allerta risponde a due domande, e con la prima sola la causa si ricostruisce
aprendo a mano il transcript della sessione headless. P3 — quando la diagnosi
serve, il guasto e' gia' rientrato: il motivo si cattura li' o mai.

- `motivo_uscita(returncode, stdout, stderr)`: unisce i due canali (stderr per
  primo), tronca a 300 caratteri.
- Silenzio totale su entrambi i canali -> lo DICE, invece di lasciare i due
  punti a vuoto: «la CLI non ha detto perche'» e «il perche' l'abbiamo perso
  noi» sono guasti diversi e finora si scrivevano uguali.
- 4 test nuovi, fra cui la regressione col messaggio testuale del 28/08.

NON risolve la causa a monte: perche' quella refresh sia fallita non sta in
nessun log locale. Il refresh token era valido (rinnovo automatico riuscito
alle 08:03:35Z dello stesso giorno, scadenza 2026-09-25) e la stessa chiamata
rifatta a mano esce 0 -> guasto transitorio, unico su 24 sessioni locali.
Da qui in avanti, se ricapita, il motivo si legge dalla notifica.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:32:41 +00:00
Adriano Dal Pastro a6b5756cc0 journal: voci automatiche del 26-27/08 — rischio tutto su TP01, SKH01 flat
Due voci scritte dal cron delle 00:37Z (27/08 e 28/08). Numeri come registrati,
nessuna riscrittura a mano.

- 26/08: equity $2.065,45, giorno $+8,86, 4 fill / 2 round-trip, 24/24 giri.
  L'analisi dell'agente segnala il denominatore cambiato il 25/08 (conversione
  USDE): stessa esposizione ($582 lordi), leva 0,28x non confrontabile coi
  giorni precedenti.
- 27/08: equity $2.070,23, giorno $+4,78, 1 fill / 1 round-trip, 24/24 giri.
  Manca la sezione "Analisi (agente)" — il passo dell'analista nel cron e'
  a `|| true`, quindi un suo fallimento non lascia traccia nella voce.

Cumulato dall'arming $+1.472,17 di equity, di cui $+1.399,39 versati:
trading **$+72,78** su 65 giorni e 23 round-trip — taglia a cui il P&L non
distingue l'edge dalla fortuna, e con l'82% del cumulato negli ultimi 7 giorni
(la settimana in cui BTC ha fatto +9,94% e il libro era lungo su entrambe le
gambe).

SKH01 flat su BTC e ETH in entrambe le voci: l'esposizione e' interamente TP01.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:19:09 +00:00
Adriano Dal Pastro e5052a690f usde: da patch d'emergenza a struttura — config, modulo unico, sorveglianza
- config/live.json sezione `usde` (unica autorita', P1): indice, haircut 10%,
  tetto allerta quota 50%, soglie depeg 0.99/0.95 coi criteri dichiarati (P6)
- src/live/usde.py: config + catena di prezzo (indice pubblico -> ticker ->
  1.0 dichiarato) + valutazione PURA; shadow._collaterale_usde ora deriva da qui
- scripts/live/usde_watch.py + cron_usde.sh (12:35 UTC, dopo la finestra reward):
  reward per delta netto trade (P12: senza inventare attribuzioni), depeg
  (crit ripetuto, resto a transizione, P9), quota anche per deriva passiva (N4);
  applica il verdetto di eligibilita' pre-registrato (>=1 reward entro 29/08)
- serie data/live/usde_watch.jsonl sotto monitor_health (max 30h, P5: un watch
  fermo non deve leggersi come "va tutto bene"); baseline 14:17Z registrata
- GATE USDE-01 in CLAUDE.md §4; test 775 (+17 in tests/test_usde_watch.py)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 15:11:44 +00:00
Adriano Dal Pastro 631e854b29 live: l'equity del book e' il TOTALE cross-collateral — USDE valutato all'indice pubblico
Trovato eseguendo il test di eligibilita' USDE ($500 convertiti alle 13:04Z,
fill 1.0003 fee 0): shadow._equity leggeva solo il conto USDC -> il giro
successivo avrebbe visto -24,3%, mandato un falso "USCITA DI FONDI" e venduto
~$140 di posizioni. Riparato prima del giro delle 13:47: _collaterale_usde()
valuta l'USDE all'indice pubblico usde_usdc (mediana multi-exchange, lezione
Binance 10/10/2025), depeg passa nel sizing, clamp a 1.0 sopra la pari,
fallback 1.0 dichiarato (mai 0: il fallback si sceglie sul danno, P5).
6 test nuovi in tests/test_shadow_usde.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 13:07:29 +00:00
Adriano Dal Pastro 562e95338b ricerca: USDE come collaterale a rendimento — analisi da candidato + test di eligibilita' pre-registrato
Verificato sul venue: apr 4.0 (netto fee), spot USDE_USDC spread ~3bps fee zero,
haircut 10% (non morde al nostro profilo di leva), indice usde_usd multi-exchange
con mediana+clamp (la differenza strutturale dal caso Binance 10/10/2025).
Rischi dichiarati R1-R4, p non stimabile -> la leva di controllo e' la QUOTA (N4).
Aritmetica: a $5k/quota 50% ~$101/anno; -100% = 25 anni di resa, non si recupera.
Pre-registrato il test di eligibilita' (~$500, 3 giorni, regola dichiarata prima).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:44:58 +00:00
Adriano Dal Pastro c4c82a8fbd diario: USDC rewards — verdetto: Italia esclusa per MiCA, pista chiusa + episodio scam in chat
Coinbase (chi paga i reward del programma Deribit) ha cessato i reward USDC
nell'EEA dal 2024-12-01 per il divieto MiCA di remunerare gli EMT; l'espansione
Deribit del 2026-08-01 aggiunge 80 paesi, nessuno EEA. Nessun ticket necessario.
Registrato l'episodio dei finti agenti in chat ("Yes, Italy is supported" =
falso) con la regola permanente sul canale di supporto.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:37:30 +00:00
Adriano Dal Pastro e7a5fee2fd diario: USDC Rewards Deribit — prodotto verificato sul venue (apr 3.4), il conto NON li riceve
Verifica empirica sulla serie equity oraria: nelle finestre di pagamento
(1-14 lug, 1-14 ago) il libro era flat e nessun accredito da ~$0,65-2,00
compare (0-1 salti >=$0,40, tutti spiegati dai fill). Resta il ticket al
supporto sull'idoneita' dell'Italia. Vale ~$170/anno a $5k.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:15:47 +00:00
Adriano Dal Pastro 3034bfdc58 gate XSR01: riscrittura DICHIARATA (opzione A dell'operatore) + haircut con script
Decisione operatore 26/08, a 58 giorni dall'esito, in direzione che stringe:
(1) capitale deploy $5k -> $20k — riconcilia il gate (25/07) con la decisione
vincolante "100% Deribit fino a $20k" (26/07), posteriore, che governa (M28);
deploy XSR01 e scelta del venue ora coincidono in un punto solo.
(2) gamba haircut: numero decisivo da r0826_xsr_haircut.py (N11) a pavimento
$10 (il vero, HL-EXEC), citato con la frazione di ordini eseguiti (P7).
Misurato: FULL 968 barre floor $10 -> haircut -1,1% con 22% di eseguiti (la
guardia da sola era vacua: un libro fermo ha haircut piccolo); ticket mediano
$3,34/gamba, 84% sotto $10 — sostituisce il "$14,41" senza script.
(3) contesto 1.82 -> 1.79 (lente dei gate). Soglie numeriche INVARIATE.

Chiude il debito S5.3. Diario 2026-08-26-xsr01-gate-riscritto.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 11:04:57 +00:00
Adriano Dal Pastro d597fc64e8 monitor: advance() consuma solo barre CHIUSE — serie rigenerate, guardia PREMATURO, 4 debiti chiusi
S5.1 RIPARATO E RIGENERATO. Filtro condiviso src/live/paper_guard.py (barra
open-labeled chiusa = ts + cadenza <= adesso) importato da tutti e 6 i monitor;
serie rigenerate dallo stesso start_ts con scripts/live/paper_regen.py (evidenza
in *.pre_regen_20260826.*): statarb +1,95 -> -1,61 (il ribaltamento del gate
27/09 previsto dall'audit), dvolspread -14,73 -> -4,41, xsr -4,98 -> -2,72,
prevday invariato. Nessuna data di gate si sposta. Guardia cablata in
monitor_health: stato PREMATURO (ultima barra che chiude dopo l'mtime, grazia
5 min, open_labeled=False per collect_chain) — sul dato vivo segnala i 5 rotti
e tace sui 2 sani; dopo la rigenerazione 7/7 OK. paper_portfolio non rigenerato
(GTAA su ADJUSTED_LAST: replay != serie registrata, P12), tolta la coda non
chiusa. D6 pagata di nuovo nel fix: asi8 in pandas 3 e' in us, non ns —
blindata con test su tre risoluzioni.

S5.12 ESTESO: conftest devia anche trades.db (wrapper su connect: il default
e' catturato alla definizione) e docs/journal/; book_executions.jsonl
sorvegliato con impronta inizio/fine suite.

S5.5 FATTO: test_leva_massima cancellato con nota (misurava frac*n_asset:
con una chiave di scala avrebbe continuato a passare smettendo di controllare).

S5.9 INDAGATO E RIPARATO (r0826_skh_band_drift): il dato regge (taglio 02/07
riproduce l'audit 1,6376, in-sample identico su ogni taglio); la deriva era la
finestra hold-out — e la sola settimana 15-22/08 vale +0,35 di Sharpe hold-out.
Il test ora taglia il feed al 02/07 e verifica la riproduzione stretta.

Suite: 751 passati, 0 falliti.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 10:12:23 +00:00
Adriano Dal Pastro a51844875b journal: i versamenti non sono piu' P&L — movimenti di capitale scorporati dal trading
Il P&L di giornale era un delta di equity: la voce del 25/08 dichiarava +$1.414,57
di "giorno" quando $1.399,39 erano il deposito USDC, e il cumulato dall'arming
avrebbe mentito per sempre. Nuova `movimenti_capitale()`:
- soglia IMPORTATA da book.EQUITY_JUMP_ALERT, non ridichiarata (P1);
- "movimento" solo se il salto supera di >2x il massimo che il mercato MISURATO
  (feed certificato, tetto di leva da config) poteva produrre fra le due letture;
- altrimenti AMBIGUO: dichiarato con attenzione e NON scorporato (P12 -- un crash
  vero a tutta leva non deve diventare "prelievo"); idem a feed illeggibile (P5).
Scansione dell'intera storia: 1 evento, esattamente il deposito (+209,6% contro
mercato max 0,22%), zero falsi positivi. `concentrazione` ora lavora sul cumulato
di TRADING; le regole sui movimenti stanno sopra l'early-return "nessun giro".
Limite dichiarato (D5): un movimento sotto il 10% dell'equity resta nel P&L.
7 prove nuove (31 -> 37), incluso il controllo M15 al contrario. Voce del 25/08
rigenerata: giorno -> trading +$15,18; cumulato -> trading +$59,14.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 07:35:15 +00:00
Adriano Dal Pastro f10d847816 ricerca: XSR01 sotto la lente RENDITA (filone 70) + cosa compra un versamento da $3k
XSR-RENDITA (r0825_xsr_rendita.py): prima valutazione di XSR01 sul criterio della
perpetua. A iso-nozionale alza il muro; a iso-rischio lo abbassa del 20,6% MA il null
mostra che il meccanismo vale 0,8% (mescolare i rendimenti non cambia nulla) e un
conto remunerato allo stesso tasso lo eguaglia a vol zero senza secondo venue.
A drift zero il muro SALE: si compra un drift scorrelato, non la scorrelazione.
L'haircut non pareggia un conto al 4% nemmeno a zero. Vincolo binding: capitale
($60k per un 25% sopra C*). Corretta in CLAUDE.md la riga Sharpe 1,82 (terza lente;
la lente dei gate da' 1,79 alla scoperta / 1,56-1,63 a oggi).

VERSAMENTO-3K (r0825_versamento_3k.py): $2.065 -> $5.065 appaiato sugli stessi path
del piano = 5,5 mesi di versamenti anticipati; 10a $114.929 -> $122.491 (+6,6%);
$15k in 1,3a e $20k in 1,9a. P(cap >= $5k al gate XSR01 del 23/10): 0% -> 100% --
il lump rende il gate leggibile senza rendere XSR01 comprabile: la decisione sulle
soglie (S5.3) va presa PRIMA che il lump atterri.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 06:56:40 +00:00
Adriano Dal Pastro 4f91b25b72 journal: voce automatica completa del 25/08 (riscritta dal cron delle 00:37Z)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-26 06:56:40 +00:00
Adriano Dal Pastro ee5c6ed539 ricerca: il piano a 10 anni dal conto vero, l'ETF-quando-flat SCARTATO, slippage rifatto
Giornata partita da "stato trades" e finita sul disegno del sistema. Versamento di
1.400 USDC atterrato alle 11:03:35Z (equity $667,88 -> $2.066,88); il giro delle 11:47
ha ribilanciato correttamente e ha ripiazzato i disaster-SL alla taglia nuova -- prima
volta che il ramo riparato stamattina gira sul serio.

(1) PIANO A 10 ANNI DAL CONTO VERO -- r0825_piano_10a_500.py (nuovo)
Le tabelle pubblicate partono da $600/$635: rifatte su $2.067, lente L3 CONGIUNTA.
Replica superata: chiede EUR 1.718/m dove la tabella da $635 chiedeva EUR 1.733.
EUR 500/mese per 10 anni -> mediana $114.934, rendita 18,35 EUR/g, P(>=50 EUR/g) = 0,0%
su 3.000 traiettorie. Il bersaglio con EUR 500/m arriva al 17o anno.

  L'EQUIVALENZA CHE ORDINA IL PIANO: EUR 100/mese in piu' == +4,07%/anno di drift,
  cioe' +27% su TUTTO il drift del libro. A 10 anni i bonifici fanno il 59%.
  Tutta la leva autorizzabile vale quanto EUR 100-150/mese: k=1,25 (+15,6%) vale MENO
  di EUR 100/mese in piu' (+19,1%), e si porta dietro il peggior giorno al 21,48%.

  E il libro a k=1 rende MENO dell'S&P (15,19% vs 17,40%): il vantaggio sta nello
  Sharpe (1,35 vs 0,89) e senza leva NON si converte in rendimento. Senza leva il libro
  non si giustifica come veicolo di ACCUMULO -- si giustifica come veicolo di RENDITA,
  dove serve 2,5x meno capitale ($254k contro $646k) perche' la perpetua vive sul DD.

(2) "ETF QUANDO IL LIBRO E' FLAT" -- SCARTATO, r0825_capitale_fermo.py (nuovo)
Il libro e' flat il 28,0% dei giorni (2,7% nel 2021, 77,0% nel 2022, 75,6% nel 2026);
live, esposto 14 giorni su 64, leva lorda mediana 0,00x e max 0,52x su un tetto di 1,0x
-- il cap non ha mai morso, il vincolo e' il segnale.
A ISO-RISCHIO il dinamico PERDE: Sharpe 1,01 contro 1,40 del 50/50 e 1,35 del libro. E
il null a maschera casuale (400 estrazioni, stessa quota, blocchi 20g) lo mette al 30o
percentile: fa PEGGIO di commutare a caso.
A iso-nozionale sembrava vincere (drift 17,09%, il piu' alto) perche' aveva la vol piu'
alta: e' la trappola di M6, il de-levering e' il PRIMO test.

  E IL MECCANISMO CHE SEMBRAVA OVVIO NON ESISTE. Aggregato: SPY 4,91% nei giorni flat
  contro 21,48% negli altri (-16,57%), e la storia si scrive da sola. FALSA: scomposta
  per anno il segno ALTERNA (3 su, 4 giu') e il 2022 -- l'anno che doveva reggerla --
  ha il segno OPPOSTO. Artefatto di composizione: i giorni flat stanno negli ANNI brutti
  per l'azionario, non nei GIORNI brutti. M9 ha fatto il suo lavoro su di me.

(3) SLIPPAGE RIFATTO ALLA TAGLIA VERA -- r0822_slip_audit.py riparato
26 fill (erano 18), $6-$319. I due piu' grandi mai eseguiti sono di oggi e hanno preso
1,01% e 0,54% della loro barra 5m, con il print a meta' del range (q=0,50). Il caso
peggiore resta un fill da $74 del 18/07 al 21,9%: un sabato, nastro inesistente.
L'attrito non e' funzione della TAGLIA ma di taglia/volume-della-barra -- l'estrapolazione
lineare che prevedeva ~71% a questo capitale e' refutata dalla misura diretta.
NB non e' "assente", e' "non ancora testato": manca un fill grande in una barra sottile,
e il weekend e' dove TP01 fa il 38% del proprio gross.

  DIFETTO P1 RIPARATO: l'equity era CABLATA a 636.0 con un commento che diceva di
  leggerla dal watermark. Il giorno del versamento avrebbe stampato $636 sbagliando di
  3,3x proprio la sezione che esiste per dire QUANDO la misura scade. Riparata leggendo
  il watermark -- e poi riparata di nuovo, perche' i fill del campione sono stati
  eseguiti a conti diversi ($597-$2.067) e una base sola e' sbagliata comunque la si
  scelga. Ora la normalizzazione e' PER FILL, e a $600 riproduce il 22,0% originale.

DUE ERRORI MIEI, CATTURATI PRIMA DI PUBBLICARLI
- maschera VUOTA vestita da risultato: la prima stesura di r0825_capitale_fermo prendeva
  i giorni flat dalla serie DE-LUCKATA, ma `deluck` sottrae una costante e lo zero esatto
  sparisce -> maschera vuota, dinamico identico al book, e lo script ha stampato tabelle
  piene e un p-value. Lo ha rivelato solo la riga "0 = 0.0%".
  REGOLA: stampare la CARDINALITA' di una maschera prima di usarla.
- il meccanismo falso della (2), demolito dalla scomposizione per anno.

Suite: 730 passati, 1 fallito -- quello gia' noto di 5.9 (deriva dati, non codice).
Watermark del libro live sopravvissuto intatto alla suite (fixture autouse di stamattina).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-25 18:13:15 +00:00
Adriano Dal Pastro 14e1567125 docs: il cap per-asset non ha tetto assoluto — CLAUDE.md dichiarava la formula del fallback
CLAUDE.md 1 descriveva il guardrail live come `min($3.000, equity_osservata x 0.5)`.
Il codice dice altro (src/live/book._cap):

    if trusted:                      # equity reale leggibile
        return float(equity) * float(frac)          # <-- nessun min() con `fixed`
    return min(fixed, wm * float(frac)) ...         # <-- il $3.000 vive SOLO qui

Cioe' `max_notional_per_asset_usd` NON morde mai sul percorso normale: e' il tetto del
ramo di FALLBACK (equity illeggibile), e la riga lo spacciava per quello vivo. Stessa
classe del difetto 5.7 — una descrizione puntata su una configurazione diversa da quella
che gira.

Conseguenza da sapere, emersa da "cosa succede se arrivo a 3.000 USDC": nessun livello
di capitale cambia il profilo di rischio RELATIVO. Il book scala indefinitamente a leva
lorda massima 1,0x (0,40x al segnale corrente), e $3.000 non e' una soglia — il numero
compare in tre posti del progetto e nessuno scatta li':
  - max_notional_per_asset_usd: cap sul nozionale, non soglia di equity, non morde;
  - "la soglia $3k" di 3: decisione CHIUSA il 26/07, si riapre a $20k;
  - C* ~$3.000 del monitor XSR01: difetto noto (5.3), il pavimento vero e' $15-20k.

CODICE NON TOCCATO: il comportamento e' intenzionale e documentato nel docstring di
_cap (la "frontiera" del 03/07 esiste apposta perche' un deposito non resti strozzato).
Era sbagliata la descrizione, non la scelta. Verificato anche che il tetto sul PRODOTTO
del GATE SCALA-01 (n_asset x frac x scala x disaster_sl_pct = 0,30 <= 0,50) non dipende
dall'equity, quindi regge identico a ogni capitale.

Contesto: versamento di 1.400 USDC atterrato alle 11:03:35Z, equity $667,88 -> $2.066,96.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-25 11:07:11 +00:00
Adriano Dal Pastro 426735448e live: diagnosi del guasto venue, disaster-SL scoperto, isolamento per asset, cron :47
Nato da "stato trades" durante una manutenzione Deribit (system_maintenance 11051,
08:57-09:20 UTC). Contati i log invece che ricordarli: 1.499 giri dal 23/06, 3 con
manutenzione, 5 traceback duri — e 4 dei 5 sono il NOSTRO gateway, non il venue.
Le release Deribit escono il martedi' alle 09:00 UTC: il cron al :07 ci cadeva dentro
per costruzione (21/07, 11/08, 18/08, 25/08).

DIAGNOSI (src/live/venue_probe.py, nuovo)
Sonda l'API PUBBLICA Deribit senza gateway e senza credenziali, e classifica il guasto:
VENUE_MANUTENZIONE / VENUE_GIU / GATEWAY / IGNOTO. Prima ogni causa stampava la stessa
riga ("conto non leggibile (offline)") con nota di diagnosi CABLATA — P4 violata, e il
18/08 il codice 11051 era gia' dentro il processo senza arrivare a chi decideva la
gravita'. Parte solo dopo un guasto: sul percorso sano costa zero. P1 rispettata: la
firma 11051 si importa da venue_watch.is_maintenance, non si ridichiara.

P9: la manutenzione dentro lo slot declassa il titolo a info, ma solo su EVIDENZA della
sonda (mai sull'orologio) e solo dentro la durata annunciata — oltre, RIALZA. Un gateway
rotto di martedi' mattina resta al massimo.

DISASTER-SL SCOPERTO (src/live/execution.py)
ensure_disaster_sl cancella i bracket incoerenti PRIMA di ripiazzarne uno: fra le due
chiamate la posizione e' senza stop. Se il ripiazzamento sollevava, l'eccezione risaliva
a main() e il guasto peggiore aveva la faccia di un errore qualunque. Ora: due tentativi,
poi stato `naked`, distinto da `place-failed` (P5). Non e' "non sono riuscito a
proteggere": e' "ho tolto la protezione e non sono riuscito a rimetterla" -> allarme
massimo, mai declassato. La SEQUENZA non e' stata invertita: piazza-poi-cancella sembra
piu' sicuro ma "sembra" non basta con soldi veri senza misurarlo.

ISOLAMENTO PER ASSET (scripts/live/book_execute.py)
Il 21/07 un 502 dentro ensure_disaster_sl su BTC ha ucciso il giro intero: nel log ETH
non compare — ne' ribilanciato ne' verificato nella protezione. Ora un asset che esplode
non ferma il ciclo, e il giro degradato esce con codice 2.

CRON :07 -> :47
Il vincolo vero non era ":07" ma "fuori dai ~26s del minuto tondo" (rate-limit per-IP
auto-saturato dal collettore catena, misura del 30/07). Il :47 lo soddisfa e in piu' sta
fuori dallo slot di release. PREVISIONE DICHIARATA (M12): 3 delle 4 finestre osservate
sono rientrate entro l'ora -> il :47 ne avrebbe scavalcate 3 su 4; se martedi' prossimo
becca comunque la manutenzione, la previsione e' sbagliata.

WATERMARK AVVELENATO DAI TEST (tests/conftest.py, nuovo)
Trovato addosso: lanciando la suite, data/live/equity_seen.json passava a $5.000 e il giro
successivo mandava un allarme Telegram FALSO ("USCITA DI FONDI -86,6%"). Non cosmetico:
cap_fallback = min(cap_config, watermark x frac) sarebbe passato da $334 a $2.500/asset,
~7,5x di leva su un conto da $668, sul ramo eq_fallback che allerta e NON blocca — cioe'
i test potevano armare il pericolo che il watermark esiste per impedire. Riparato con una
fixture AUTOUSE, non per-test: chiedere a ogni autore di ricordarsene ha gia' perso il
26/07 e il 21/08. Resta esposto lo stesso errore su trades.db e book_executions.jsonl.

BLOCCATO, NON RINVIATO
Il fallback diretto ai privati Deribit richiede chiavi API create dall'operatore: in
locale esiste solo CERBERO_TOKEN. Il gateway resta un punto singolo di guasto non
aggirabile (CLAUDE.md 5.11). La sonda dice di chi e' il guasto, non lo aggira.

Test: 20 nuovi, nessuno tocca la rete; controllo positivo fatto (5 su 7 falliscono contro
il codice vecchio). Suite 730 passati, 1 fallito — quello gia' noto di 5.9 (deriva dati).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9UyJLHzR7EJzxR3iQ3RN1
2026-08-25 10:27:36 +00:00
Adriano Dal Pastro 2751a7efd0 journal: la voce del giorno IN CORSO non si presenta piu' come una giornata
cron_daily (00:30 UTC) faceva DUE chiamate al giornale: chiudeva IERI (giusto)
e apriva OGGI. La pagina di oggi nasceva con ~30 minuti dentro e nessuno la
aggiornava fino alla notte dopo.

Il difetto non era il dato mancante: era che la pagina non lo diceva dove si
legge. Aveva TUTTE le sezioni di una chiusa -> passava ogni controllo di
completezza e freschezza, e la parzialita' stava solo in §Salute, quinta
sezione su otto. Stessa famiglia di "una barra presente non e' una giornata
presente", in veste nuova: la pagina e' presente, il giorno no.

Taglia misurata sul caso reale di oggi: la pagina congelata alle 00:37 diceva
"giorno: $+0.54 (1 letture)" e la regola [pnl] chiosava "senza operare". Alle
08:54 il libro aveva fatto 3 fill, 2 round-trip e +$25.86 ($642.56 -> $667.88).
Avrebbe raccontato una giornata ferma per tutta una giornata operativa.

Riparato in due pezzi indipendenti:
  1. la pagina dichiara la parzialita' nel TITOLO e nella prima riga —
     "PARZIALE (giorno in corso)", copertura esplicita (N giri su 24), il fatto
     che non si aggiorna da sola, e quali numeri sono di quella frazione;
  2. tolta la seconda chiamata dal cron. In docs/journal/ restano solo giorni
     chiusi; lo stato corrente si prende da journal.py a mano (pagina marcata)
     o da trades.db, che cron_book sincronizza ogni ora.

Scelta dichiarata: NON si rigenera ogni ora. Costerebbe una riga in cron_book
ma riscriverebbe un file tracciato da git 24 volte al giorno per un consumatore
che non esiste (l'analista legge il giorno chiuso). Se un domani servisse, la
strada e' RIGENERARLA, non congelarla: e' scritto nel commento del cron.

Prove (test_journal 28 -> 31): una accende la marcatura, una la tiene spenta su
un giorno chiuso (una marcatura sempre accesa non si legge), una e' guardia sul
SORGENTE di cron_daily.sh — ogni chiamata a journal.py deve avere --giorno
esplicito, perche' senza argomenti scrive OGGI.

Regolare docs/journal/2026-08-25.md rigenerato: ora si dichiara PARZIALE (9/24).

NON riparato, e registrato come debito aperto in CLAUDE.md §5:
test_wave_0726::test_t1_canonical_riproduce_il_backtest_ufficiale fallisce, e
falliva gia' prima di questa modifica (verificato con git stash sull'albero
pulito). Sharpe hold-out SKH01 canonical 1,9223 contro la banda cablata
1.3 < h < 1.9: il codice non e' cambiato, sono cambiati i dati (data/raw e'
gitignored, il cron lo ricostruisce ogni notte). La banda NON e' stata
allargata — lezione 07/08. Suite: 710 passati, 1 fallito.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 08:59:42 +00:00
Adriano Dal Pastro 11a2370027 journal: voci automatiche del 23-25/08
Giri notturni del cron. Il 23/08 e' stato rigenerato alle 00:36 del 24 col
giorno COMPLETO (24 giri invece di 20, equity $637.58, cumulato $+39.52):
la voce precedente era stata scritta alle 19:44 a giornata in corso.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 08:50:02 +00:00
Adriano Dal Pastro b237ad2e8b docs: compattazione di CLAUDE.md — 3458 -> 424 righe, memoria in docs/memory/
CLAUDE.md era arrivato a 310 KB (~80k token caricati a OGNI sessione) e la
sua funzione si era sdoppiata: era insieme il manuale operativo e l'archivio
di 69 filoni di ricerca. Le due cose hanno lettori diversi.

I 65 bullet-blocco sono stati spostati VERBATIM in docs/memory/ (nulla
riscritto). Verifica meccanica riga per riga prima del commit: 3272 righe
non vuote, 0 mancanti, 0 aggiunte, zero buchi e zero sovrapposizioni nella
copertura delle regioni estratte.

  10-sleeve-e-candidati.md    30 KB  TP01 XS01 VRP01 SKH01 GTAA01 XSR01
  20-ondate-e-scartati.md    126 KB  69 filoni, ogni scartato col suo perche'
  30-piano-capitale-fisco.md  59 KB  muri, versamenti, venue risk, fisco, prop
  40-produzione-e-deploy.md   66 KB  esecutore, tripwire, monitor, PRIIPs/UCITS
  50-dati-e-feed.md           14 KB  difetti del dato, catena opzioni
  60-metodo-e-gate.md          4 KB  i gate di altlib.py

In CLAUDE.md resta solo cio' che serve a non sbagliare una decisione: stato,
book live vs book di ricerca, i numeri da citare e quelli da NON citare,
7 decisioni vincolanti dell'operatore con "cosa le riapre", 6 gate
pre-registrati con la data, 9 debiti aperti non riparati, le regole di
prim'ordine (D/M/C/P/N, distillate dalle 113 righe che contenevano REGOLA),
IL DATO, metodologia, stack/struttura/comandi.

Tre fatti che erano sepolti in 3400 righe e ora stanno in testa: le TRE
baseline diverse che girano sotto il nome "libro 75/25" (spread piu' grande
di quasi tutti gli effetti misurati), il funding non modellato in nessun
backtest (-2,16%/anno), e che «N/N ancore» vale ~2 osservazioni.

Verificato prima del commit: 36/36 percorsi citati esistono su disco,
708 test collezionati, code fence bilanciati. Nessun file di codice toccato.

Convenzione aggiunta (§14) perche' il file non torni a crescere: quando un
risultato CAMBIA UNA DECISIONE si aggiorna CLAUDE.md; quando aggiunge
racconto, va in docs/memory/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 08:50:02 +00:00
Adriano Dal Pastro 214599e0a8 docs: libro di bordo in CLAUDE.md + diario del 23/08
CLAUDE.md: bullet del libro di bordo (il difetto dell'ora dei fill, il DB a
tre fonti incrociate, i quattro livelli della pagina, l'analista e i suoi
limiti, le due riparazioni al notifier), piu' i file nuovi nella Struttura e
i quattro comandi nella sezione Comandi.

Diario `2026-08-23-libro-di-bordo.md`: la storia per esteso, i numeri del
libro live dall'arming (+$37,50 in 64 giorni, ma l'80% delle giornate a
equity invariata e tutto il P&L in sei giorni), i cinque difetti trovati dai
test e il ciclo di retroazione dell'agente.

Le due cose che un lettore futuro deve trovare scritte: che l'analisi in
prosa NON e' parte del registro (una guardia sui numeri non copre il
ragionamento — due errori su due giri con sonnet-5, nessuno con una cifra
nuova), e che il modello e' stato cambiato su un campione di due
osservazioni, quindi e' un tentativo di abbassare un tasso e non una
garanzia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 19:50:56 +00:00
Adriano Dal Pastro 12dc04c969 analista: modello di default a opus-5
Sonnet-5 ha prodotto due errori di ragionamento in due giri: una frase su un
merge di cui nessuno gli aveva parlato, e un round-trip corretto sulla pagina
dichiarato inesistente, con una spiegazione inventata per il proprio dubbio.
Nessuno dei due contiene una cifra nuova, quindi numeri_non_supportati() non
li vede: e' il buco dichiarato quando la guardia e' stata scritta.

Primo giro con opus-5 sulla stessa giornata: nessuna affermazione inventata,
e le affermazioni numeriche verificate a mano contro il DB tornano tutte
(fill 1 contro 2/5/4/3 dei giorni precedenti, equity ferma a $597.12 dal 13
al 18/08, target BTC 189 -> 115). Resta un'imprecisione di nome: chiama
"target" un valore che nella fonte era la POSIZIONE. Il numero e' della
fonte, la classe di errore e' cambiata.

E ha prodotto una riformulazione che le regole non possono dare: la
concentrazione del P&L in 7 giorni ha una lettura alternativa altrettanto
compatibile — quei sette giorni sono anche gli UNICI in cui il libro e'
stato a mercato, quindi la finestra non separa l'edge dal beta a un rialzo
del 22-29%.

⚠️ Il campione e' di due osservazioni contro una: e' un tentativo di
abbassare un tasso, non una garanzia, ed e' scritto cosi' nel sorgente.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 19:47:11 +00:00
Adriano Dal Pastro 782c0ce4bc analista: manda l'analisi giornaliera su Telegram, con l'esito registrato
La notifica porta una testata coi numeri che si leggono senza aprire nulla
(equity, delta del giorno, cumulato, posizioni, leva, fill e round-trip) e
sotto l'analisi del modello.

Il trasporto Telegram e' pero' il punto singolo di guasto gia' misurato in
questo progetto: un tentativo, nessun retry, esito mai registrato, 6,9% di
invii persi (2/29). Su un messaggio al giorno sono ~25 messaggi persi
all'anno, quindi qui sono state fatte due delle tre riparazioni dichiarate
il 2026-08-23 e mai eseguite:

(a) `send(text, tentativi=1)` — retry OPZIONALE con backoff. Il default resta
    1, cosi' il comportamento e' invariato per tutti i chiamanti esistenti:
    alzarlo per tutti cambierebbe la latenza degli allarmi di venue_watch e
    book_execute su un percorso con soldi veri, e non e' una modifica da fare
    di straforo dentro un'altra funzionalita'. L'analista chiede 3.
(b) `ultimo_errore()` — il motivo si registra nel punto in cui l'eccezione
    veniva ingoiata, e NON sopravvive a un invio riuscito. Regola gia'
    codificata il 29/07 su un altro percorso e mai applicata al notifier.

La terza (marcare `alerted=True` solo a invio riuscito in venue_watch) cambia
il comportamento degli allarmi e resta una decisione dell'operatore.

L'esito finisce nel DB in tre stati: inviata / non configurato / FALLITA col
motivo. Un invio perso che non lascia traccia, il giorno dopo, non si
distingue da "non e' successo niente".

E se l'analisi manca, il messaggio parte lo stesso dicendo PERCHE': senza
quel ramo un guasto del modello si leggerebbe come una giornata senza nulla
da dire. Taglio a 4096 caratteri dichiarato, mai silenzioso; HTML del modello
neutralizzato.

708 test passano. Strategia, pesi, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 19:40:56 +00:00
Adriano Dal Pastro 7456be1ce5 merge: ondata di ricerca 0822 + libro di bordo del book live
114 commit. Due cose diverse dentro lo stesso ramo.

RICERCA (scripts/research/, docs/) — sei ondate, §21-69, 0 candidati promossi.
Il valore e' difensivo e reale: quattro monitor forward rotti che avrebbero
fatto decidere un gate al contrario, un costo gia' in essere mai contato (il
funding dei perpetual, -2,16%/anno di drift), un punto singolo di guasto nel
trasporto degli allarmi, quattro soglie pubblicate falsificate. Il finding di
prim'ordine e' §58: l'obiettivo del progetto ha DUE definizioni operative in
uso che danno 33,9% contro 0,33% sulla stessa domanda.

PRODUZIONE (src/live/, scripts/live/, cron) — il libro di bordo:
- data/live/trades.db, i trade allineati col tempo. Erano salvati ma datati
  alla BARRA DI SEGNALE: 19 righe su 19 a 00:00:00, e un trade registrato sei
  giorni prima di essere eseguito. L'ora vera viveva solo in cron_book.log,
  gitignored e fuori dal backup.
- book_execute.py: ts_utc = ora vera del fill, bar_ts = barra, con test di
  regressione sulla sorgente.
- docs/journal/: una voce al giorno, quattro livelli separati per
  provenienza — numeri misurati, Lettura a regole tracciabili, Analisi di un
  modello, Nota dell'operatore.
- sync orario in cron_book, giornale e analista in cron_daily.

Strategia, pesi e config del libro INVARIATI su tutto il ramo. Nessun ordine.
695 test passano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 17:48:24 +00:00
Adriano Dal Pastro f5d9409213 analista di bordo: un modello scrive la prosa del giorno, in un campo suo
Aggiunto il quarto livello della pagina, tenuto separato dagli altri tre:
  numeri   -> misurati dal feed e dal DB
  Lettura  -> regole deterministiche, ognuna col suo id
  Analisi  -> questo: prosa di un modello, che puo' sbagliare
  Nota     -> l'operatore

NON scrive dentro `nota`, che era la richiesta letterale: quel campo e'
dell'operatore, ed e' cio' che a rileggere il giornale fra sei mesi permette
di sapere chi ha scritto cosa. L'agente ha `analisi`, marcato col modello,
con l'ora e con l'esito del controllo sui numeri.

Gira via `claude -p` (verificato con env -i che risponda nell'ambiente nudo
di cron), una chiamata al giorno sul giorno CHIUSO, tolte le tool.

Tre guardie, una per ogni modo in cui una prosa generata rovina un registro:
- NUMERO INVENTATO: numeri_non_supportati() estrae ogni cifra dall'analisi e
  verifica che compaia in cio' che il modello ha ricevuto. Oltre tre numeri
  liberi l'analisi e' RIFIUTATA e la pagina resta senza. E' un controllo
  debole per costruzione, e lo dichiara: prende l'invenzione, non il
  ragionamento sbagliato.
- COMMENTO DI SE': senza_analisi() toglie dalla pagina la sezione dell'agente
  prima di dargliela. Al primo giro reale il modello aveva letto la propria
  uscita precedente e prodotto un paragrafo sull'avviso che si era preso il
  giorno prima — un ciclo di retroazione che in poche settimane avrebbe
  riempito il giornale di meta-commento, e che nessun controllo automatico
  puo' distinguere da prosa valida.
- ANALISI DI IERI SPACCIATA PER OGGI: se il modello non risponde, la pagina
  resta VUOTA e il perche' viene registrato (stato + motivo). Il silenzio non
  diventa continuita'.

Corretto anche un falso positivo mio: il tripwire validava sulla sola pagina
mentre il prompt include anche il blocco storico, quindi bocciava un'equity
vera. Una guardia piu' stretta del contratto produce allarmi che si impara a
ignorare.

Ogni guardia ha un test in entrambe le direzioni. 695 test passano.
Strategia, pesi, config INVARIATI. Nessun ordine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 17:46:29 +00:00
Adriano Dal Pastro 1803e0ac9f giornale: lettura ragionata a regole dichiarate e tracciabili
Non prosa libera: dodici regole, ognuna con un id stampato accanto alla riga
che ha prodotto. Combinano solo numeri gia' presenti nella pagina, tacciono
sul non misurato e non prevedono niente. Il campo `nota` resta l'unico posto
dove puo' finire un giudizio umano.

Le regole: stato del libro e PERCHE' e' flat (componente per componente),
disaccordo fra orizzonti del trend contro esposizione TP01, incoerenza
(trend su ma libro fuori), leva contro il tetto, P&L del giorno, costo che
supera il movimento, concentrazione del cumulato, drawdown dal picco,
implicita contro realizzata col gate IV-rank di VRP01, giornata oltre 2
deviazioni, giri mancanti e feed vecchio, e la taglia del campione.

Ogni regola ha DUE test: uno che la accende e uno che la tiene spenta. Una
regola che si accende sempre non sta leggendo niente, una che non si accende
mai e' indistinguibile da una rotta.

Tre difetti corretti prima di pubblicare, tutti trovati scrivendo i test:
- il tetto di leva era RIDICHIARATO (0.5 cablato) invece che letto da
  config/live.json — quinta occorrenza dello schema che il progetto paga da
  luglio: un sorvegliante che ridichiara il proprio bersaglio continua a
  passare il giorno che il bersaglio cambia. Ora deriva, e se il config non
  si legge lo dice invece di inventare un tetto.
- l'IV-rank era il percentile a UN ANNO etichettato col nome del gate di
  VRP01, che usa un percentile ESPANDENTE. Due statistiche diverse, e oggi
  danno il verdetto OPPOSTO: 0.52 (sopra la soglia, "il sleeve venderebbe")
  contro 0.18 (sotto, sleeve fermo). Il valore giusto combacia con quanto
  gia' misurato il 30/07: 0/8 settimane passano il gate.
- la concentrazione si accendeva su $2,08 di cumulato: vera e inutile. Ora
  ha una soglia di rilevanza, o e' una riga che insegna a saltare la sezione.

62 voci rigenerate. Strategia, pesi, config INVARIATI. 675 test passano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 13:36:05 +00:00
Adriano Dal Pastro 10c373075c libro di bordo: DB dei trade allineato col tempo + giornale giornaliero
I trade erano salvati, ma non allineati col tempo: book_execute.py scriveva
ts_utc = pd.Timestamp(r['last_data']), cioe' la data della BARRA DI SEGNALE.
19 righe su 19 a 00:00:00, e un trade (ETH 0.04 @ 1869.74) registrato SEI
GIORNI prima di essere eseguito — fill vero 2026-07-14T14:00, scritto 08/07.
L'ora vera esisteva solo in logs/cron_book.log, che e' gitignored, fuori dal
backup e ruotabile: la cronologia reale del libro live viveva in un file che
una rotazione avrebbe cancellato senza che nessuno se ne accorgesse.

- src/live/tradesdb.py: parser del cron log (ora vera + contesto del segnale),
  FIFO con fee pro-quota, riconciliazione a tre fonti, sqlite in data/live/
  (dentro il perimetro del backup). Le tre fonti si INCROCIANO e non si
  sovrascrivono: reconcile() riporta le divergenze e non ripara niente da solo.
  Il venue e' autorevole ma TRONCA (1 trade su BTC, 0 su ETH): dichiarato.
- scripts/live/trades_db.py: --sync (idempotente, in cron_book ogni ora),
  --report, --reconcile.
- src/live/journal.py + scripts/live/journal.py: una voce al giorno in
  docs/journal/YYYY-MM-DD.md — mercato (ritorni, RV30, TSMOM sugli orizzonti
  di produzione, DVOL con eta'), libro (TP01/SKH01, target, posizione, leva),
  P&L (equity del venue come autorita', scomposizione locale), salute.
  NIENTE narrativa automatica: il campo `nota` e' l'unico posto per il testo
  libero ed e' dell'operatore, mai riscritto da un ricalcolo.
- book_execute.py: ts_utc = ora vera del fill, bar_ts = barra. Test di
  regressione sulla sorgente: se qualcuno rimette last_data, il test lo dice.
- 62 voci di giornale ricostruite dall'arming a oggi.

Tre difetti trovati dai test mentre scrivevo, non a occhio: il renderer cadeva
in KeyError se mancava il blocco mercato (un giornale che non si scrive non e'
un giornale); "24 giri attesi" su un giorno IN CORSO produceva un allarme a
ogni esecuzione; e libro e P&L leggevano due istanti diversi, quindi la stessa
pagina mostrava due equity.

Strategia, pesi, config INVARIATI. Nessun ordine. 659 test passano.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 13:13:02 +00:00
Adriano Dal Pastro 0cd0747e95 CLAUDE.md: bullet della sesta ondata (§58-69) + tre correzioni inline
0 candidati su 69 filoni cumulativi. Il finding di prim'ordine e' §58:
l'obiettivo del progetto ha DUE definizioni operative in uso (flusso e
ricchezza sostenibile) che danno 33,9% contro 0,33% sulla stessa domanda, e
per cinque ondate i due corpi di lavoro sono stati confrontati come se
parlassero della stessa cosa.

Tre marcatori inline dove l'ondata contraddice numeri gia' scritti, perche'
questa memoria non deve contraddirsi da sola:
- il vincitore MISTO del 25/07 e' superato da MISTO-A (§60)
- il gate XSR01 del 23/10 legge un monitor tarato sul pavimento del venue
  sbagliato (§67); soglie NON toccate, decisione dell'operatore
- la ragione per raccogliere la catena USDC e' caduta: le due superfici sono
  la stessa superficie a strike appaiati (§64)

Registrata anche la provenienza anomala dei verdetti (riesecuzione degli
script, non messaggi degli agenti) e la previsione verificabile che la 70a
ondata dara' la stessa risposta.

Libro, pesi, cron, config INVARIATI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 12:51:58 +00:00
Adriano Dal Pastro 8c0b5f97ee registro: chiusi §58-69 — dodici verdetti, 0 candidati, e due appoggi tolti a decisioni gia' prese
I dodici filoni della sesta ondata erano rimasti `_in corso_`: la sessione si e'
chiusa dopo che gli agenti avevano scritto gli script e prima che i verdetti
fossero consolidati, e i loro messaggi finali sono persi. I numeri qui NON
vengono da quei messaggi: vengono dalla riesecuzione dei dodici script
(07:38-08:06 UTC, sequenziale, log in logs/r0823b/ che e' gitignored).
E' il motivo per cui l'ondata non e' andata persa: ogni script calcola il
proprio verdetto a runtime.

Cosa tocca decisioni gia' prese:
- §67 il gate pre-registrato XSR01 del 23/10 legge un monitor tarato sul
  pavimento del venue sbagliato (C* $15-20k, non ~$3k)
- §64 la raccomandazione di §51 (raccogliere la catena USDC) non e'
  giustificata dalla ragione che porta: le due superfici sono la stessa
- §60 la politica MISTO scelta il 25/07 non e' piu' l'ottimo (oggi MISTO-A)
- §63 domanda fiscale NUOVA, diversa da quella aperta il 07/08

Il risultato piu' grande e' di §58: l'obiettivo del progetto ha DUE definizioni
operative in uso che danno 33,9% contro 0,33% sulla stessa domanda, e non era
mai stato detto quale si stesse ottimizzando.

r0823b_quasi_passati.py (§68) terminava con IndexError: Griglia.combo()
indicizzava con self.idx (2720 giorni) un sottoinsieme di 958 righe. Corretto
col parametro idx esplicito piu' un controllo di lunghezza; la
rinormalizzazione e' riga per riga, quindi i valori sono quelli dell'intento
dell'autore. La correzione e' del coordinatore, non dell'autore, ed e'
dichiarata nel registro.

Libro, pesi, cron, config INVARIATI. Nessun ordine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 12:40:30 +00:00
Adriano Dal Pastro cdec81c5bc registro: aperti §58-69 — sei filoni sulla conversione del libro in 50 EUR/g, cinque sullo spazio-strategie non toccato, uno scettico 2026-08-23 04:24:59 +00:00
Adriano Dal Pastro e48de7fcc7 CLAUDE.md: rimando al diario di chiusura 2026-08-23 04:17:25 +00:00
Adriano Dal Pastro 273a43ad6a diario 23/08: ondate 7-8 e critico di chiusura — 17 filoni, 0 candidati, 3 numeri di testa riscritti e 5 errori miei 2026-08-23 04:17:12 +00:00
Adriano Dal Pastro ab4590c326 CLAUDE.md: bullet della quinta ondata (§46-57) — 0 candidati su 57 filoni, PREVDAY girava senza gate, 1,50x bocciato, e la somma di tutti i lead vale +0,036 EUR/giorno 2026-08-23 04:12:06 +00:00
Adriano Dal Pastro 80ca982f64 CLAUDE.md: correzioni del critico — il muro e' una mediana con banda esplosiva, «N/N ancore» vale ~2 osservazioni, il 1,50x e' bocciato, il soffitto ~1,3 e' refutato due volte, i bonifici fanno il 61% non il 73% 2026-08-23 04:10:34 +00:00