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>
This commit is contained in:
Adriano Dal Pastro
2026-08-28 12:54:08 +00:00
parent 21fe289383
commit 418f523be7
5 changed files with 316 additions and 29 deletions
+46 -19
View File
@@ -101,19 +101,50 @@ def griglia_piena():
return G
def test_la_banda_proposta_e_quella_scelta_al_buio(griglia_piena):
"""Il gate (A), nella forma decidibile (2026-08-07).
# ⚠️ 2026-08-28 — SECONDO CRITERIO RITIRATO, e per la stessa ragione del primo.
# `test_la_banda_proposta_e_quella_scelta_al_buio` asseriva che la banda scelta sui soli dati
# pre-2015 fosse la proposta. Ha smesso di passare senza che nessuno toccasse il codice: al buio
# esce il 60%, con margine 0.0074 — sotto il pavimento di 0.01 che il test stesso si era dato.
# Misurato in `r0828_gtaa_band_phase.py`: NON e' un fatto sulla banda, e' un fatto sul criterio.
# · IB serve una finestra ROTOLANTE di 30 anni e SPY e' al muro: la sua prima barra avanza di
# un giorno di borsa ogni notte. Il pre-2015 — che il progetto tratta come congelato — perde
# il giorno piu' vecchio ogni notte.
# · `gtaa._gated_returns` ribilancia su `i % every == 0`, cioe' sulla POSIZIONE nell'array:
# se la prima barra scivola, si ri-fasa ogni decisione di trent'anni. La fase canonica cambia
# da sola.
# · Esito: su 10 notti consecutive la scelta al buio e' 25% / 40% / 60%, e il margine sta sotto
# il pavimento in 4 notti su 10. A dato FISSO, muovendo la sola fase, il verdetto cambia lo
# stesso (25% su 3 fasi, 60% su 2).
# Come il 07/08 si congela il MOTIVO e non l'esito. La riparazione (ancorare la fase al calendario)
# e la decisione su GTAA01 sono rinviate alla soglia di $15k di book — sotto quella soglia lo
# sleeve non e' deployabile e la decisione non ha conseguenze (`journal.SOGLIE_CAPITALE`).
La proposta del 27/07 e' una BANDA: la cadenza settimanale e' gia' `REBAL_EVERY=5` in
produzione e non era in discussione. Quindi la domanda sulla provenienza della scelta e'
«a cadenza di produzione, quale banda si sceglie guardando SOLO il pre-2015?».
"""
def test_il_gate_A_non_ha_RISOLUZIONE_ed_e_per_questo_che_e_stato_RITIRATO(griglia_piena):
"""Congela il MOTIVO del secondo ritiro: il criterio decide su un margine piu' piccolo del
rumore che lo scuote. Non asserisce QUALE cella vinca — quella si muove da sola ogni notte,
ed e' esattamente il punto."""
G = griglia_piena
riga = G[G["every"] == BG.PROPOSTA[0]]
blind = riga.sort_values("sh_in", ascending=False).iloc[0]
assert blind["frac"] == BG.PROPOSTA[1], (
f"al buio si sceglierebbe la banda {blind['frac']:.0%}, non {BG.PROPOSTA[1]:.0%}: "
"la validazione del 27/07 andrebbe rifatta su quella cella")
ordinata = riga.sort_values("sh_in", ascending=False)
margine = float(ordinata["sh_in"].iloc[0] - ordinata["sh_in"].iloc[1])
spread = float(riga["sh_in"].max() - riga["sh_in"].min())
# il margine su cui il criterio decideva e' una FRAZIONE dello spread della griglia:
# a quella scala la scelta non e' una misura, e' l'ordine in cui il rumore si e' posato.
assert margine < 0.25 * spread, (
f"il margine ({margine:.4f}) e' tornato grande rispetto allo spread di griglia "
f"({spread:.4f}): se il rumore si fosse ridotto, il gate (A) andrebbe RIABILITATO "
"invece di restare ritirato — ed e' un fatto da guardare, non da ignorare")
def test_la_fase_di_ribilanciamento_e_ancora_ancorata_alla_POSIZIONE(griglia_piena):
"""La guardia sulla CAUSA. Se un giorno `_gated_returns` ancorasse la fase al calendario,
questo test si rompe e va riletto tutto: il gate (A) potrebbe tornare decidibile."""
import inspect
src = inspect.getsource(BG.gtaa_returns.__globals__["_gated_returns"])
assert "i % every" in src, (
"la fase non e' piu' ancorata alla posizione nell'array: la ragione del ritiro del "
"gate (A) e' venuta meno, rileggere r0828_gtaa_band_phase.py")
def test_chi_guardasse_l_hold_out_sceglierebbe_una_banda_DIVERSA(griglia_piena):
@@ -128,15 +159,11 @@ def test_chi_guardasse_l_hold_out_sceglierebbe_una_banda_DIVERSA(griglia_piena):
"potenza e non va citato come validazione")
def test_il_margine_del_blind_non_e_un_arrotondamento(griglia_piena):
"""La ragione per cui questo criterio ha sostituito il confronto fra ranghi: decide su
~0.015 di Sharpe invece che su ~0.001. Se il margine scendesse sotto un centesimo, anche
questo criterio smetterebbe di essere una misura e andrebbe ripensato a sua volta."""
G = griglia_piena
riga = G[G["every"] == BG.PROPOSTA[0]]
blind = riga.sort_values("sh_in", ascending=False).iloc[0]
secondo = riga[riga["frac"] != blind["frac"]]["sh_in"].max()
assert blind["sh_in"] - secondo >= 0.01
# `test_il_margine_del_blind_non_e_un_arrotondamento` (2026-08-07) chiedeva margine >= 0.01 e
# diceva, testualmente: «Se il margine scendesse sotto un centesimo, anche questo criterio
# smetterebbe di essere una misura e andrebbe ripensato a sua volta». Il 28/08 e' sceso a 0.0074.
# Il test aveva ragione e si e' auto-ritirato: la sua condizione e' ora dentro il test sul MOTIVO
# qui sopra, dove misura il margine CONTRO lo spread di griglia invece che contro un assoluto.
def test_il_confronto_fra_ranghi_e_una_moneta_ed_e_per_questo_che_e_stato_RITIRATO(griglia_piena):