research(wave-0822): MAKER scartato (il segno dipende da < contro <=) + CRITICO — la cucitura dell'ondata, non i filoni

This commit is contained in:
Adriano Dal Pastro
2026-08-22 20:51:47 +00:00
parent 103dd7bce5
commit 0f2e195674
4 changed files with 271 additions and 18 deletions
+132 -2
View File
@@ -693,9 +693,9 @@ stessi hanno nominato senza poterli eseguire**. Stesso contratto di consegna, st
| # | filone | domanda che decide | verdetto |
|---|---|---|---|
| 21 | XS01-OOS | il vantaggio del PROP-ALLOC poggia sul drift di XS01 misurato sulla sua finestra di scoperta: regge fuori? | _in corso_ |
| 22 | MAKER | l'esecuzione passiva e' una fonte di ritorno, al netto del costo di non essere eseguiti? | _in corso_ |
| 22 | MAKER | l'esecuzione passiva e' una fonte di ritorno, al netto del costo di non essere eseguiti? | **SCARTATO** — il segno dipende da `<` contro `<=` |
| 23 | BOCPD | un rilevatore di cambio di regime vero batte il miglior lookback COSTANTE? | **SCARTATO** — filone chiuso definitivamente |
| 24 | CRITICO | cosa NON e' stato misurato, e quale singola misura mancante vale di piu' | _in corso_ |
| 24 | CRITICO | cosa NON e' stato misurato, e quale singola misura mancante vale di piu' | **3 correzioni all'ondata**, 1 regola mia ritirata |
| 25 | BIN-FREQ | il binario di frequenza su SKH01 e' un candidato o un sottoprodotto? | _in corso_ |
| 26 | TP01-SINISTRO | quanto pesa TP01 se l'obiettivo include un crash che nel campione non c'e'? | _in corso_ |
| 27 | SURFACE-RV | la superficie e' internamente incoerente, e l'incoerenza vale piu' del costo di attraversarla? | _in corso_ |
@@ -759,3 +759,133 @@ mostra che la sua serie e quella del lookback costante coincidono a **max|Δ| =
n=2719** — non *somiglia a*, **lo e'**.
**VERDETTO: SCARTATO. IL FILONE ORIZZONTE-ADATTIVO E' CHIUSO DEFINITIVAMENTE.**
---
## 22 — MAKER (esecuzione passiva come fonte di ritorno)
`scripts/research/r0822b_maker.py` (19 s, sola lettura). **42 celle dichiarate**, nessuna riduzione.
📌 **Osservazione strutturale che riapriva la domanda:** il netting su strumento unico — il motivo per
cui T1 resto' non implementata il 26/07 — **non si applica qui**. Quello uccide i *bracket per-sleeve*
(un limit al livello di SKH chiuderebbe quota TP01); l'ordine **netto** di ribilanciamento e' uno
solo, quindi passivizzarlo non ha conflitti fra sleeve. La domanda era davvero aperta.
**(1) Il differenziale, limite superiore** (tutto maker, zero non-fill): dSharpe **+0,0333**,
dCAGR +0,466 pp → **$2,96/anno a $635**, $23,28 a $5.000, $1.203 al muro di $258k.
✅ Replica indipendente della curva del 26/07: **+0,0167 Sh/bps e +0,233 pp/bps** contro i pubblicati
0,017 / 0,23.
📌 **(2) Il costo del non-fill, ed e' qui che muore: il parametro che decide non e' l'orizzonte, e'
cosa si chiama "riempito".**
| N (min) | TOCCO `low <= P` (limite superiore) | ATTRAVERSAMENTO `low < P` (minimo difendibile) |
|---|---|---|
| 5 | fill 93,2% · resta **+0,31** bps (15,5%) | fill 86,2% · resta **0,47** bps (**23,6%**) |
| 60 | 98,6% · +0,34 (17,1%) | 95,9% · **0,45** (22,4%) |
| 120 | 98,9% · +0,67 (33,7%) | 96,9% · 0,38 (19,0%) |
**Fra le due colonne cambia una sola disuguaglianza stretta**: se la barra che apre esattamente al
nostro prezzo, e da li' se ne va, conta come fill. **Non conta** — a quel prezzo non e' stato
scambiato niente dopo l'arrivo dell'ordine, e un passivo sta *dietro* a tutta la coda. Griglia fine:
il salto e' **tutto al primo passo** (3,16 → 3,95 bps a penetrazione sub-tick) e **non esiste un q
positivo di pareggio**. Lente model-free: il fill *richiesto* per pareggiare e' **88-98%**, quello
ottenuto e' sotto in **25 celle su 25**.
**Gate:** appaiato **per ORDINE** (ogni ordine compare una volta in entrambe le politiche, riempito o
no — allineare sui riempiti avrebbe tenuto solo i casi in cui non e' successo niente); **IC95
bootstrap contiene lo zero in 10 celle su 10** al tocco e a q=0, interamente negativo da q≥1;
**placebo a ore casuali girato** → reale ≈ placebo e **incoerente fra i due asset** (BTC 6,8 vs 3,1
bps; ETH 4,1 vs 4,7) ⇒ la selezione avversa **non** e' "il libro trada nei momenti brutti", e'
**strutturale all'esecuzione passiva** e non si aggira scegliendo momenti migliori. Null del
de-levering **non pertinente e dichiarato** (nessun claim di DD; il maxDD **cambia segno** fra le
lenti = non e' un effetto).
📌 **La firma della troncatura, vista dall'altra parte.** Il passivo **vince sul 92-98% degli ordini e
perde sulla media**: mediana dell'avversa **2,0 bps** (favorevole), media **+4,3**, peggiore **+948**,
e i **5 ordini peggiori su 1535 fanno il 42% del danno**. E' la forma speculare del profit-take di
VRP01 (30/07). **Una politica che vince quasi sempre e perde sulla media si giudica sulla media.**
⚠️ **Rischio operativo quantificato:** a N=60 restano aperti al giro successivo il **4,6-7,8% degli
ordini = 9-15 volte l'anno** in cui l'esecutore deve cancellare-e-rimpiazzare su un conto vero. Oggi
`rebalance_signed` manda market e finisce: **nessun ordine sopravvive al giro** → si comprerebbe un
modo nuovo di rompersi (il libro ha gia' pagato quel prezzo con `fresh_5m`) per un beneficio il cui
IC95 contiene lo zero.
⚠️ **Numero del brief non riprodotto:** l'agente ricostruisce **191 ordini/anno di libro** a $635
contro i "35-44/anno per asset" del brief; il nastro vero da' 18 ordini in 45 giorni = **146/anno**.
La conclusione non dipende da questo (il punto 1 usa il turnover modellato, che replica la curva
pubblicata al terzo decimale), **ma il numero del brief va ri-verificato.**
**VERDETTO: SCARTATO.** +0,033 Sharpe nel caso impossibile, contro ±0,20 di banda d'ancora del libro.
**Smentitore dichiarato:** una misura di **profondita' del book** sui perpetual USDC (che l'OHLC non
contiene e che il progetto non raccoglie — `cb_chain` e' opzioni). Se a taglie di $5-80 la coda al
miglior livello si consumasse senza che il prezzo debba attraversare, il segno si ribalta. **E'
misurabile in avanti**: registrare `book_depth` al momento di ogni ordine e poi il volume scambiato
al livello.
---
## 24 — CRITICO (critico di completezza dell'ondata)
`scripts/research/r0822b_critic.md` (48 KB, markdown — non uno script). Ha letto brief, registro,
diario e i sorgenti degli agenti.
📌 **La tesi, e regge:** *il metodo dei singoli filoni non e' il problema dell'ondata, la CUCITURA lo
e'.* I difetti gravi stanno nei punti dove **nessun agente era responsabile**.
🚨 **(a) `dealer_net_gamma` NON e' "il GEX col segno invertito" — la regola l'ho pubblicata io in
CLAUDE.md ed e' FALSA.** ✅ **Verificata da me aprendo la fonte**, che gira su questa stessa VPS:
`/opt/docker/cerbero-mcp/src/cerbero_mcp/common/options.py:11-14` **dichiara la convenzione**
(*"i dealer sono SHORT calls (le vendono al retail) e LONG puts"*) e `dealer_gamma_profile:138-140`
la implementa (`call_dealer_gamma -= contrib` / `put_dealer_gamma += contrib`). Non e' un segno
invertito per errore: e' un'**assunzione di posizionamento dichiarata**, diversa da quella del GEX
standard. Il default `top_n_strikes=50` spiega anche il coefficiente 0,7 e l'offset che il filone
DEALER-GAMMA attribuiva a "non-portabilita'". **Il verdetto SCARTATO regge; cade la regola**, che le
prossime ondate avrebbero ereditato al contrario.
🚨 **(b) Il deflated-Sharpe e' stato misurato ai suoi DUE estremi degeneri lo stesso giorno, da due
agenti che non si citano — e tre gate pre-registrati ci poggiano sopra** (XSR01 23/10, DVOLSPREAD
24/10, 22/12). `altlib.deflated_sharpe` calcola `sr0 = sd(Sharpe dei trial) × mult(N)`: dipende dalla
**varianza** della griglia, non solo da N. Da un lato VOL-SIZE dichiara il proprio DSR **VACUO**
(1,000 anche per il baseline); dall'altro ORTHO-SCREEN pubblica *"sr0 = 1,572 ⇒ uno screen largo su
BTC/ETH non puo' passare il proprio gate per aritmetica"* — ma quell'1,572 implica sd≈0,58, e **le
stesse 168 celle dichiarate come 7 famiglie da 24 danno 1,15, sotto il soffitto ~1,3**: il verdetto
"impossibile per aritmetica" **si ribalta senza toccare un dato**, e la cura che suggerisce
(dichiarare famiglie piu' piccole) e' esattamente la manovra che il progetto ha proibito il 30/07.
**Convergenza indipendente:** il filone BOCPD, che non ha parlato col critico, ha misurato lo
stesso difetto dall'altro capo (DSR 0,998 PASS dentro la famiglia omogenea → **0,555 FAIL** con
l'sr0 di screen). **Due agenti, due strade, stessa conclusione: il gate non ha una regione utile in
mezzo.**
🚨 **(c) Il filone ALT-OPTIONS non e' nel registro** — ✅ verificato: **zero occorrenze**, ne' riga ne'
sezione, benche' due altri filoni lo citino e il mio brief per SURFACE-RV mandasse a leggerlo. Il
diario lo liquida come *"alt-options (alt)"*, ma la sua conclusione riguarda **ETH_USDC, che non e'
un alt**: `f_venue` 0,980 e **max-loss $16,62/lotto**. Se regge, e' la **quarta** soglia pubblicata
falsificata (il diario ne annuncia tre) e sposta VRP01 da *"servirebbe il 61% di un conto da $3.000"*
a *"entra in un conto da ~$140"*. ⚠️ **Cio' che NON cambia: la regola "niente short-vol da modello in
deploy" non era una regola di eseguibilita'** — VRP01 resta fuori dal libro per il `f` modellato e
per il gate IV-rank, non per la taglia del lotto.
📌 **(d) La misura di maggior valore mai fatta, secondo il critico: il peggior giorno che il libro
puo' avere, MISURATO invece che assunto.** Il gradino di leva 1,00→1,50x vale **14,7a → 11,6a** al
capitale-rendita (~€300/mese di versamenti equivalenti, a costo zero) ed e' bloccato da **un unico
parametro scelto a mano** ("un giorno 10%/anno porta k* a 2x"). Controllo di cinque minuti: sui 10
peggiori giorni di BTC/ETH in 7,4 anni — **incluso il 41,5%/45,7% del 12 marzo 2020** — il libro ha
fatto **+0,97 · +0,72 · 0,00 · 1,98 · 2,24 · +0,23%**, e il suo peggior giorno assoluto (**3,38%**)
**non e' un giorno di crash**. Il 10% e' plausibilmente una **coda da buy&hold importata in un libro
difensivo**.
📌 **(e) La risposta onesta al mandato, che gli era stato chiesto di dare se vera: nessuna misura di
ricerca batte "versare".** 3,1 anni di ricerca valgono meno dei 5 anni che vale €250/mese in piu'.
E la verifica che costa meno di tutte **non e' ricerca**: leggere il listino di due prop firm.
L'intero risultato di testa dell'ondata (+0,400 di J) poggia sull'assunto — scritto in un **commento
a riga 100** — che una firm crypto listi i 19 alt Hyperliquid con short abilitato. **E' la ripetizione
esatta dell'errore GTAA01/PRIIPs**, per cui il progetto ha gia' scritto la regola: *la negoziabilita'
sul conto REALE va verificata quando lo sleeve entra in RICERCA.*
**Altre contraddizioni fra agenti segnalate:** lo Sharpe di XSR01 compare con **quattro** lenti (non
tre); il muro di XS01 con **tre** numeri; la leva riceve guida **opposta** da GROWTH-POLICY e
PROP-ALLOC; il peso di SKH01 e' **respinto da un agente e raddoppiato da un altro**. Piu' 6 modalita'
non esplorate e 6 punti di autocritica — incluso che i **20 MB del dataset futures 2018-2026 (l'unico
con la coda 2022) vivono solo in uno scratchpad di sessione**.
+8 -1
View File
@@ -486,9 +486,16 @@ def main() -> None:
print(f" e' la scelta CONSERVATIVA e resta quella dichiarata.")
print(f" dispersione dei trial: sd(Sharpe FULL) = {float(np.std(all_sr, ddof=1)):.3f} sulle")
print(f" {len(ALLC)} celle, {float(np.std(pos_sr, ddof=1)):.3f} sulle {len(POS)} di segno +1.")
print(f" -> il DSR qui NON e' vacuo (il baseline lo fallisce dove il candidato lo passa):")
print(f" -> il DSR qui NON e' vacuo (il baseline lo FALLISCE dove il candidato lo passa):")
print(f" la famiglia contiene celle davvero diverse fra loro, al contrario della famiglia")
print(f" VOL-SIZE dove erano tutte perturbazioni della stessa size continua.")
print(f" ❌ QUESTO REFUTA LA MIA IPOTESI (b), registrata nel docstring PRIMA di misurare")
print(f" ('il DSR sara' vacuo come su VOL-SIZE'). La ragione per cui mi sbagliavo e'")
print(f" strutturale e vale come regola: un DSR e' vacuo quando i trial si somigliano")
print(f" (var_tr -> 0 => sr0 -> 0 => DSR ~ 1 per chiunque). Una famiglia BINARIA contiene")
print(f" celle che scartano insiemi di trade MOLTO diversi — compreso il segno inverso —")
print(f" quindi la dispersione dei trial e' reale e il test riacquista potenza. Non e' il")
print(f" binario a essere piu' solido della formula: e' la FAMIGLIA a essere piu' larga.")
print("\n (c) MARGINAL vs TP01 — sulla gamba modificata e sulla gamba base")
for lab, s in (("BASE (size fissa)", base_leg[can]), (nmc, LEG[nmc][can]),
+57 -1
View File
@@ -369,7 +369,9 @@ def test_calendario(q: pd.DataFrame, dte_min: float, ogni: int = 4) -> dict:
iv_need = np.sqrt(np.maximum(x["w"].to_numpy(), 0) / np.maximum(nxt_T, 1e-9)) * 100.0
amp_pt = np.where(ok, iv_need - nxt_iv, np.nan)
res = {"i_n": int(ok.sum()), "i_viol": int(viol_i.sum()),
room = amp_pt[ok] # <0 = margine, >0 = violazione
res = {"room_med_pt": float(np.nanmedian(room)), "room_p5_pt": float(np.nanpercentile(room, 5)),
"i_n": int(ok.sum()), "i_viol": int(viol_i.sum()),
"i_quota": float(viol_i.sum() / max(1, ok.sum())),
"i_amp_med_pt": float(np.nanmedian(amp_pt[viol_i])) if viol_i.any() else np.nan,
"i_amp_p95_pt": float(np.nanpercentile(amp_pt[viol_i], 95)) if viol_i.any() else np.nan}
@@ -471,6 +473,37 @@ def persistenza(bf: pd.DataFrame, viol_col: str) -> dict:
return {"n": int(m.sum()), "resta": float(nxt[m].mean()) if m.any() else np.nan}
def controfattuale_usdc(bf: pd.DataFrame, asset: str, rel_usdc: float) -> dict:
"""SE la famiglia USDC quotasse la STESSA superficie col SUO spread, sarebbe eseguibile?
Controfattuale DICHIARATO, non una misura: il collettore non raccoglie le USDC (difetto di
produzione del filone 11), quindi si tiene il mid osservato sulle inverse e si stringe lo
spread al valore relativo misurato dagli altri filoni sulla famiglia USDC, con il lotto
minimo USDC e la stessa formula di fee. Assunzione dichiarata: stessa griglia di tick
(una griglia piu' grossa peggiorerebbe il risultato, quindi questo e' un LIMITE SUPERIORE).
"""
x = bf[(bf["asset"] == asset)].dropna(subset=["mid", "mid_p", "mid_n"]).copy()
x = x[np.isclose(x["lam"], 0.5, atol=0.02)]
lot = MIN_LOT_USDC[asset]
out = {}
for nome, rel in (("inverse osservato", None), (f"{asset}_USDC controfattuale", rel_usdc)):
if rel is None:
b, a_p, a_n = x["bid"], x["ask_p"], x["ask_n"]
l = MIN_LOT[asset]
else:
b = x["mid"] * (1 - rel / 2)
a_p = x["mid_p"] * (1 + rel / 2)
a_n = x["mid_n"] * (1 + rel / 2)
l = lot
cred = (b.to_numpy() * 2 * l - a_p.to_numpy() * l - a_n.to_numpy() * l)
f = (fee_coin(b.to_numpy(), 2 * l) + fee_coin(a_p.to_numpy(), l) + fee_coin(a_n.to_numpy(), l))
netto = (cred - f) * x["spot_feed"].to_numpy()
out[nome] = {"n": int(len(x)), "pos": int(np.nansum(netto > 0)),
"max": float(np.nanmax(netto)), "p999": float(np.nanpercentile(netto, 99.9)),
"lotto_usd": float(np.nanmedian(x["spot_feed"]) * l)}
return out
# --------------------------------------------------------------------------- controlli positivi
def _finto(rows) -> pd.DataFrame:
@@ -657,6 +690,12 @@ def main() -> None:
print(f" (ii) log-moneyness FISSO, con interpolazione (1 snapshot ogni {c['ii_ogni']}): "
f"{c['ii_viol']:,}/{c['ii_n']:,} = {c['ii_quota']:.3%} · ampiezza mediana {c['ii_amp_med_pt']:.3f} pt-vol")
print(f" -> contributo dell'INTERPOLATORE = {c['ii_quota'] - c['i_quota']:+.3%} di quota di violazione")
if "i_val_usd_med" in c:
print(f" valore mediano della violazione (i) al lotto minimo ${c['i_val_usd_med']:.2f} "
f"contro un costo di 2 gambe (spread + fee) di ${c['i_costo_usd_med']:.2f}")
print(f" margine di monotonia sull'intera superficie: la iv lunga sta {-c['room_med_pt']:.2f} pt-vol "
f"SOPRA il minimo che la non-arbitraggio richiede (p5 {-c['room_p5_pt']:.2f}) "
f"-> la superficie non e' nemmeno VICINA al bordo")
print("\n" + "=" * 100)
print("5. TICK E PERSISTENZA — le due difese contro 'la mia incoerenza e' un artefatto'")
@@ -674,6 +713,23 @@ def main() -> None:
f"(mediana {np.median(nt):.0f} tick) · resta in violazione allo snapshot dopo "
f"{p.get('resta', float('nan')):.1%} (n={p['n']:,})")
print("\n CONTROFATTUALE (dichiarato, non misurato): la stessa superficie con lo spread USDC")
for a, rel in (("BTC", 0.082), ("ETH", 0.026)):
if a not in set(bf["asset"]):
continue
cf = controfattuale_usdc(bf, a, rel)
for nome, r in cf.items():
print(f" {a} {nome:<28}: lotto ${r['lotto_usd']:,.0f} · farfalle a credito netto>0 "
f"{r['pos']:,}/{r['n']:,} · migliore ${r['max']:.2f} · p99.9 ${r['p999']:.2f}")
print("\n QUANTO MANCA per essere eseguibile (near-miss, triple equispaziate):")
for a in sorted(bf["asset"].unique()):
x = bf[(bf["asset"] == a) & np.isclose(bf["lam"], 0.5, atol=0.02)]
c = x["cost_exec"].to_numpy() * 2 * MIN_LOT[a] * x["spot_feed"].to_numpy() # >0 = costo
print(f" {a}: costo della farfalla eseguibile — migliore ${np.nanmin(c):.2f} · "
f"p0.1 ${np.nanpercentile(c, 0.1):.2f} · mediana ${np.nanmedian(c):.2f} "
f"(negativo = credito riskless)")
print("\n" + "=" * 100)
print("6. IL RESIDUO SI RICOMPONE? (l'ipotesi del filone, misurata invece che assunta)")
print("=" * 100)
+74 -14
View File
@@ -444,13 +444,19 @@ def main() -> None: # noqa: C901
wins_sk += d > c
print(f" {str(IDX[t].date()):>12} {win[t]:>9.1%} {a:>11.1%} {b:>11.1%} "
f"{c:>10.1%} {d:>11.1%} {('si' if b > a else 'no'):>9}")
pre = [t for t in w12 if IDX[t] < pd.Timestamp(RECENT_START, tz="UTC")]
wins_pre = sum(1 for t in pre
if float(np.expm1(lr_opt[t:t + EPI_LEN].sum()))
> float(np.expm1(lr_live[t:t + EPI_LEN].sum())))
print(f"\n OPT batte LIVE in **{wins}/12** finestre -> test dei segni "
f"p = {binom_two_sided(wins, 12):.4f}")
print(f" SKH01 puro batte TP01 puro in **{wins_sk}/12** -> p = "
f"{binom_two_sided(wins_sk, 12):.4f}")
print(" ⚠️ 5 di queste 12 finestre stanno nel 2024+, cioe' DENTRO la finestra su cui")
print(" SKH01 e' stato tarato e su cui PROP-ALLOC ha ottimizzato: la potenza sale ma")
print(" l'indipendenza scende. Il test va letto come **una diagnostica, non una prova**.")
print(f" ⚠️ {12-len(pre)} di queste 12 finestre stanno nel 2024+, cioe' DENTRO la finestra")
print(" su cui SKH01 e' stato tarato e su cui PROP-ALLOC ha ottimizzato: la potenza sale")
print(" ma l'indipendenza scende. **Sul solo sotto-campione pre-2024**, che e' quello")
print(f" indipendente: OPT batte LIVE in **{wins_pre}/{len(pre)}** -> p = "
f"{binom_two_sided(wins_pre, len(pre)):.4f}. E' questo il numero da citare.")
tick("§2 conto assicurazione")
@@ -583,11 +589,15 @@ def main() -> None: # noqa: C901
bw_c = max(s2, key=lambda w: s2[w][2])
print(f"\n argmax della colonna 'peggiore': leva-da-2024+ -> TP01 {bw_a:.3f} | "
f"leva comune 0.50x -> TP01 {bw_c:.3f}")
print(" Lettura: se la sopravvivenza al crash SALISSE col peso di TP01, l'assicurazione")
print(" servirebbe. **A leva comune non sale**: la curva e' piatta-decrescente. Il difensivo")
print(" non compra sopravvivenza su questa barriera, perche' cio' che la barriera punisce e'")
print(" la PERDITA nel crash, e nel crash TP01 perde (prende la prima gamba giu' e poi va")
print(" flat) mentre SKH01 si gira short e GUADAGNA.")
print(" ⚠️ LE DUE COLONNE DICONO COSE DIVERSE, E LA SECONDA E' A CAMPANA: a leva COMUNE la")
print(f" sopravvivenza al crash SALE col peso di TP01 fino a {bw_c:.3f} ("
f"{s2[0.0][2]:.1%} a TP01=0 -> {s2[bw_c][2]:.1%}) e poi ricade.")
print(" **Quindi TP01 protegge davvero: a pari leva, il libro con piu' difensivo sopravvive")
print(" di piu' al crash.** Il punto e' che quella protezione si compra anche abbassando la")
print(" leva — ed e' esattamente cio' che misura §5. Alla leva che ciascun libro sceglierebbe")
print(" (prima colonna) il vantaggio sparisce, perche' il libro senza TP01 la sceglie piu'")
print(" bassa. E' la firma del **null del de-levering**, qui in veste di 'protezione dal")
print(" crash' invece che di 'meno drawdown'.")
tick("§4 S2 replay")
@@ -637,9 +647,16 @@ def main() -> None: # noqa: C901
ret, _, _, _, _ = replay22(w, lo)
_, _, _, why, _ = replay22(w, hi)
print(f" {w:>7.3f} {lo:>23.2f}x {ret:>20.1%} {why:>25}")
print("\n ⚠️ La leva di rottura e' MONOTONA DECRESCENTE nel peso di TP01 solo se la")
print(" protezione fosse reale. Si legga la colonna: se il libro con piu' TP01 rompe PRIMA,")
print(" l'assicurazione non sta assicurando la cosa giusta.")
print("\n 📌 La colonna 'leva max viva' CRESCE col peso di TP01 (fino a TP01=0.875; a TP01=1")
print(" ricade perche' li' a mordere non e' piu' il giorno singolo ma la perdita CUMULATA).")
print(" **L'assicurazione e' reale e si vede: piu' TP01 = piu' leva sopportabile nel 2022.**")
print(" E accanto c'e' il prezzo: alla PROPRIA leva massima il libro senza TP01 porta a casa")
print(" il +23.3% e quello a TP01 pieno il -5.9%. TP01 compra capacita' di leva, e la")
print(" capacita' di leva non si converte in rendimento perche' cio' che TP01 toglie e'")
print(" proprio il rendimento. E' il null del de-levering scritto in una riga sola.")
print(" ⚠️ Cambia anche il VINCOLO che morde: sotto TP01 0.50 e' la regola a UN GIORNO,")
print(" sopra e' il max-loss cumulato. Due libri diversi muoiono di due morti diverse, e una")
print(" sola delle due lenti (l'accoppiata) vede la prima.")
tick("§4 replay 2022")
@@ -725,8 +742,10 @@ def main() -> None: # noqa: C901
print(f" {0.5*wxs30[t_xw]:.1%} al libro. La domanda non e' se XS01 sopravvive a cio' che ha")
print(" gia' visto, e' se il suo comportamento nel crash somiglia a cio' che ha gia' visto —")
print(" e su questo il campione non ha NIENTE da dire.")
W3 = [(0.75, 0.25, 0.00), (0.375, 0.625, 0.00), (0.25, 0.25, 0.50), (0.125, 0.125, 0.75),
(0.50, 0.25, 0.25)]
# ⚠ le ultime tre righe hanno XS01 FISSO al 50%: senza quel controllo si confonderebbe
# "piu' TP01" con "meno XS01", che e' un'altra domanda.
W3 = [(0.75, 0.25, 0.00), (0.375, 0.625, 0.00), (0.50, 0.25, 0.25),
(0.125, 0.375, 0.50), (0.25, 0.25, 0.50), (0.375, 0.125, 0.50)]
com = xs.index.intersection(IDX[i_rec:])
xs_al = xs.reindex(com)
print(f"\n {'TP/SKH/XS':>16} {'ipotesi XS':>12} {'leva':>6} {'J normale':>10} "
@@ -832,7 +851,9 @@ def main() -> None: # noqa: C901
n_act = int((np.abs(R) > 1e-12).sum())
n_los = int((R[np.abs(R) > 1e-12] < 0).sum())
f = A.implausible_sharpe(d, n_trades=n_act, n_losing_trades=n_los)
print(f" implausible_sharpe {lab:>11}: {f}")
print(f" implausible_sharpe {lab:>11}: implausible={f['implausible']} "
f"(Sharpe {f['sharpe']:.2f}, maxDD {f['maxdd']:.1%}, quota barre in perdita "
f"{f['loss_frac']:.1%}, Calmar {f['calmar']:.2f}) {f['reasons']}")
except Exception as exc: # pragma: no cover
print(f" implausible_sharpe: NON GIRATO ({exc})")
print(" marginal_vs_tp01 / study_family_honest / deflated_sharpe : **NON GIRATI, e non")
@@ -864,6 +885,45 @@ def main() -> None: # noqa: C901
am = max(tab, key=lambda w: tab[w][key][1]["J"])
print(f" {lab:>26} {am:>14.3f} {tab[am][key][1]['J']:>10.3f} "
f"{tab[0.75][key][1]['J']:>10.3f} {tab[0.375][key][1]['J']:>11.3f}")
print("\n ESISTE UN PESO DI COMPROMESSO? Il criterio dichiarato: (a) dentro il 5% del")
print(" massimo di J sulla finestra 2024+ (la 'regione robusta' del funded) E (b) dentro il")
print(" 5% del massimo di J sulla finestra 2019+, che il sinistro ce l'ha dentro.")
jr_max = max(tab[w]["rec"][1]["J"] for w in W_GRID)
jf_max = max(tab[w]["full"][1]["J"] for w in W_GRID)
js_max = max(tab[w]["sin"][1]["J"] for w in W_GRID)
print(f"\n {'w TP01':>7} {'J 2024+':>9} {'entro 5%':>9} {'J 2019+':>9} {'entro 5%':>9} "
f"{'J solo-sin':>11} {'entro 5%':>9} {'compromesso':>13}")
ok_both = []
for w in W_GRID:
a, b, c = (tab[w]["rec"][1]["J"], tab[w]["full"][1]["J"], tab[w]["sin"][1]["J"])
oa, ob, oc = a >= 0.95 * jr_max, b >= 0.95 * jf_max, c >= 0.95 * js_max
if oa and ob:
ok_both.append(w)
print(f" {w:>7.3f} {a:>9.3f} {('si' if oa else 'no'):>9} {b:>9.3f} "
f"{('si' if ob else 'no'):>9} {c:>11.3f} {('si' if oc else 'no'):>9} "
f"{('SI' if (oa and ob) else '-'):>13}")
print(f"\n -> pesi che soddisfano (a) E (b): {ok_both if ok_both else 'NESSUNO'}")
print(f" il libro live 75/25 e' {'dentro' if 0.75 in ok_both else 'FUORI'} da questa regione.")
print("\n LA RISPOSTA, IN QUATTRO RIGHE")
print(" 1) La premessa del caveat e' sbagliata nella FORMA: il 2024+ un crash ce l'ha (b&h")
print(" -60% di drawdown, -39.6% in 20 giorni). Manca la TAGLIA, ~2x sulla coda veloce.")
print(" 2) Il compromesso ESISTE e non e' un compromesso: lo stesso peso (TP01 ~0.375) e'")
print(" l'argmax sulla finestra con il 2022 dentro E su quella senza. Il caveat di")
print(" PROP-ALLOC e' onesto come cautela e **falsificato come previsione**.")
print(" 3) TP01 protegge davvero (a pari leva sopravvive di piu' al crash, e alza la leva")
print(" sopportabile nel 2022 da 0.93x a 2.20x) ma la stessa protezione si compra piu' a")
print(" buon mercato ABBASSANDO LA LEVA: a iso-sopravvivenza il payout e' massimo a")
print(" TP01 0.125-0.250 e cala monotonamente da li'. **7ª occorrenza del null del")
print(" de-levering**, in una veste nuova: 'protezione dal crash' invece di 'meno DD'.")
print(" 4) Il rischio vero dell'ottimo di PROP-ALLOC NON e' TP01 sotto-pesato: e' XS01 al")
print(" 50% con un comportamento nel crash che il campione non contiene. Un solo giorno")
print(" a -8% su XS01 dimezza la sopravvivenza; con TP01 al 50% ne serve uno a -12.3%.")
print(" **Se TP01 vale qualcosa su un conto funded, vale come zavorra contro l'ignoto di")
print(" XS01, non come assicurazione contro il crash di BTC/ETH — che SKH01 fa meglio.**")
print("\n ⚠️ COSA MI SMENTIREBBE: un crash in cui SKH01 NON si gira short in tempo (gap")
print(" notturno oltre lo stop, o venue fermo). Il campione ne ha quattro e in tutti e")
print(" quattro SKH01 ha girato. Basterebbe un episodio in cui SKH01 perde quanto il")
print(" sottostante per rovesciare §2 e §5 — e con n=4 quell'episodio non e' improbabile.")
print("\n" + "=" * 106)
print(f" fatto in {time.time()-t0:.0f}s | valutazioni: {N_EVAL}")
print("=" * 106)