37c83c11c9
Ultimo agente dell'ondata 2026-08-22/23. Sola lettura, nessun file di produzione toccato.
Attese a priori dichiarate nel docstring: A1/A4/A5/A6 confermate, A2 e A3 REFUTATE.
REPLICHE (prima di ogni accusa, tutte riuscite):
- libro 75/25 path live: drift 19,23%/17,07%, Sharpe 1,692/1,513, funding -2,1597%/anno
- i quattro muri L0/L1/L2/L3 riprodotti al dollaro: $278.033 / $264.373 / $327.617 /
$313.143, e il muro E' esattamente `prelievo / perpetua`
- §42 dShFULL(floor=-1) all'ancora 0 = -0,4502 (pubblicato -0,450)
- TP01 canonico ShFULL 1,305; XS01 fase 0 == sleeve di produzione a max|diff| 0,0
- funding ri-misurato da implementazione indipendente: TP01 2,138%/anno, rapporto
condizionale 1,93x (BTC) / 2,58x (ETH) contro il pubblicato 1,86-2,55x
TROVATO:
1. Il muro $313k non ha mai avuto una banda. Propagando SOLO la SE del drift (5,151%/anno,
block bootstrap; §53 la misura 5,09 su altra lente) va da $204k (+1 SE) a $707k (-1 SE),
p10-p90 [$187k, $1,14M], e a -2 SE il traguardo NON esiste a nessun capitale. La riga
«EUR500/mese -> P(20a) 85%» diventa ~0% a -1 SE. L'ondata ha pubblicato la risoluzione
Monte Carlo del muro (0,7%) e mai quella del suo input, che e' 100x piu' grande.
2. «positivo in N/N ancore/fasi» non e' N osservazioni: N_eff misurato 1,6-2,1 (24 ancore
TP01, corr 0,63) e 1,2-1,5 (10 fasi XS01, corr 0,79), con controllo positivo 24,5 / 1,00.
La componente comune NON si cancella nella differenza appaiata (corr 0,59) -> A3 refutata.
E la banda d'ancora non e' un IC: per la stessa grandezza l'IC95 bootstrap e' 4,3x piu'
largo e contiene lo zero. I verdetti reggono, la precisione dei numeri no.
3. Tre baseline diverse sotto lo stesso nome «libro 75/25»: 1,68 (hourly, tutti i muri),
1,80 (canonical, §41/42/49/50/54), 1,63 (mediana d'ancora, §8/25) — spread 0,12 di Sharpe
e 1,7pp di maxDD, piu' grande di quasi tutti gli effetti misurati.
4. «Soffitto direzionale ~1,15» contro 1,639 (§23) e 1,621 (§54) nella stessa ondata: seconda
refutazione indipendente dell'argomento aritmetico di §12.
5. «EUR X/mese» versa ogni 30 GIORNI (12,17 versamenti/anno, +0,8-1,4%); e il contatore
`versato` non si ferma al traguardo -> a 10 anni i bonifici fanno il 61%, non il 73%.
6. MDE: la catena opzioni misurata da me da' 77 giorni di superficie (registro 74-75, ok)
= MDE 4,3 di Sharpe -> ogni SCARTATO di §4/§5/§7/§11 che poggia su uno Sharpe e' un
non-risultato su quell'asse. §21 XS01-OOS, pilastro del canale funded, ha effetto +1,12
contro un MDE di 1,13.
7. Errore mio catturato in sessione: la prima stesura de-luckava una serie gia' de-luckata
(0,89^2) e stampava un finto +31,5% sul muro; il valore vero della scelta di modello e'
+4,0%.
RISPOSTA AL MANDATO: no. La somma di TUTTI i lead positivi dell'ondata, se fossero
autorizzati e additivi (non lo sono), vale +0,036 EUR/giorno a $635. EUR250 -> EUR500 al mese
porta P(20a) dal 14% all'85%. Il valore dell'ondata e' difensivo ed e' reale; il mandato
«arrivare ai 50 giornalieri velocemente» ha risposta negativa.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M8Ncho6QV9FWLdyy4VyQf
822 lines
47 KiB
Python
822 lines
47 KiB
Python
"""r0823 — CRITICO DI CHIUSURA dell'ondata 2026-08-22/23 (55 filoni, `research/wave-0822`).
|
|
|
|
Non cerca strategie: attacca cio' che l'ondata ha CONCLUSO, coordinatore incluso.
|
|
Sola lettura. Nessun ordine, nessuna rete, nessun file di produzione toccato.
|
|
|
|
=============================================================================================
|
|
ATTESE A PRIORI — scritte PRIMA di misurare (un critico che ha sempre ragione non sta criticando)
|
|
=============================================================================================
|
|
A1 Le repliche dei numeri di testa RIUSCIRANNO (muri, funding, dShFULL della short di TP01):
|
|
l'ondata ha fatto molte repliche interne e i suoi script sono ripetibili.
|
|
-> attesa: CONFERMATA. Se fallisse, sarebbe il risultato piu' grosso del filone.
|
|
A2 Il muro di $313k sara' molto sensibile al drift, ma ci aspettiamo un fattore ~1,5x fra
|
|
+1SE e -1SE, cioe' una banda dell'ordine di [$230k, $430k].
|
|
-> attesa: DA MISURARE. (esito: REFUTATA — misurato [$204k, $707k] a +/-1 SE, e a -2 SE
|
|
il traguardo NON esiste: la mia stima era ottimista di ~2x sull'ampiezza)
|
|
A3 Le 24 ancore / 10 fasi porteranno meno informazione di quanta ne sembri, ma su una
|
|
DIFFERENZA APPAIATA la componente comune si cancellera' e il numero effettivo di
|
|
osservazioni indipendenti sara' >= 5.
|
|
-> attesa: DA MISURARE. (esito: REFUTATA — non si cancella quasi nulla)
|
|
A4 La maggior parte degli SCARTATI dell'ondata sara' correttamente etichettata come
|
|
"non misurabile" quando lo e': l'ondata cita gli MDE spesso.
|
|
-> attesa: CONFERMATA in larga parte, con eccezioni nominate.
|
|
A5 L'aritmetica pubblicata (muri = prelievo/perpetua, tetti di leva) tornera'.
|
|
-> attesa: CONFERMATA.
|
|
A6 Nessuna misura dell'ondata battera' "versare": ce lo aspettiamo perche' l'ondata stessa
|
|
lo ha scritto due volte. Il valore e' nel METTERLE IN FILA con la stessa unita'.
|
|
-> attesa: CONFERMATA.
|
|
|
|
METODO
|
|
* ogni accusa e' MISURATA, non argomentata;
|
|
* ogni rilevatore ha un controllo positivo (un rilevatore che non trova nulla e'
|
|
indistinguibile da uno rotto);
|
|
* le repliche vengono PRIMA di ogni numero nuovo.
|
|
|
|
USO: uv run python scripts/research/r0823_critico_chiusura.py [--fast]
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT))
|
|
sys.path.insert(0, str(ROOT / "scripts" / "research"))
|
|
|
|
from src.data.downloader import load_data # noqa: E402
|
|
from src.strategies.trend_portfolio import ( # noqa: E402
|
|
CANONICAL, TrendPortfolio, simple_returns)
|
|
from src.portfolio.sleeves import XS_CFG, XS_UNIVERSE, _HL_DIR, _xsec_returns # noqa: E402
|
|
|
|
import r0725_capcurve as CC # noqa: E402 EURUSD, TARGET_EUR_DAY, TAX_RATE, _boot_paths
|
|
import r0807_piano_netto as PN # noqa: E402 sopravvivenza / accumula
|
|
import r0727_tasse as TX # noqa: E402 PATRIMONIALE
|
|
|
|
FAST = "--fast" in sys.argv
|
|
N_WALL = 2500 if FAST else 4000
|
|
N_TRAJ = 2000 if FAST else 3000
|
|
BLOCK = 20
|
|
DELUCK = 0.89
|
|
SEED = 725
|
|
T0 = time.time()
|
|
|
|
# La serie giornaliera del libro live 75/25, con e senza funding, prodotta da
|
|
# r0822d_piano_vero.costruisci_serie(). Se la cache non c'e' si rigenera (richiede rete).
|
|
CACHE = Path("/tmp/claude-1001/-opt-docker-PythagorasGoal/"
|
|
"b6cc75e7-14f8-4c32-bd07-ab8a0d2aaee6/scratchpad/pianovero/book.parquet")
|
|
|
|
|
|
def sez(t: str) -> None:
|
|
print("\n" + "=" * 102)
|
|
print(f" {t} [{time.time() - T0:5.0f}s]")
|
|
print("=" * 102)
|
|
|
|
|
|
def sh(r: np.ndarray) -> float:
|
|
r = np.asarray(r, float)
|
|
return float(r.mean() / r.std() * np.sqrt(365.25))
|
|
|
|
|
|
def deluck(r: np.ndarray) -> np.ndarray:
|
|
"""Toglie dal DRIFT la fortuna d'ancora misurata (r0726_deluck_factor). La vol resta."""
|
|
r = np.asarray(r, float)
|
|
return r - (1.0 - DELUCK) * r.mean()
|
|
|
|
|
|
def boot_stat(x: np.ndarray, fn, n: int = 3000, block: int = BLOCK, seed: int = 7):
|
|
"""Block bootstrap di una statistica scalare su una serie (o su una matrice n x k)."""
|
|
rng = np.random.default_rng(seed)
|
|
x = np.asarray(x, float)
|
|
N = x.shape[0]
|
|
nb = int(np.ceil(N / block))
|
|
out = np.empty(n)
|
|
for i in range(n):
|
|
st = rng.integers(0, N - block, size=nb)
|
|
ix = (st[:, None] + np.arange(block)[None, :]).reshape(-1)[:N]
|
|
out[i] = fn(x[ix])
|
|
return out
|
|
|
|
|
|
def n_eff(M: pd.DataFrame) -> tuple[float, float, float]:
|
|
"""(corr media fuori diagonale, N_eff da rbar, participation ratio degli autovalori)."""
|
|
C = M.corr().values
|
|
k = C.shape[0]
|
|
iu = np.triu_indices(k, 1)
|
|
rbar = float(C[iu].mean())
|
|
ev = np.linalg.eigvalsh(C)
|
|
pr = float(ev.sum() ** 2 / (ev ** 2).sum())
|
|
return rbar, k / (1.0 + (k - 1) * rbar), pr
|
|
|
|
|
|
# =============================================================================================
|
|
# 1) REPLICHE — i controlli positivi della MIA macchineria, prima di qualunque accusa
|
|
# =============================================================================================
|
|
def resample_off(df: pd.DataFrame, h: int) -> pd.DataFrame:
|
|
"""Daily con ancora all'ora h. Stessa convenzione di r0702_tp01_offset.resample_offset."""
|
|
d = df.copy()
|
|
d["datetime"] = pd.to_datetime(d["datetime"])
|
|
return (d.set_index("datetime")
|
|
.resample("24h", offset=pd.Timedelta(hours=h), label="left", closed="left")
|
|
.agg({"open": "first", "high": "max", "low": "min",
|
|
"close": "last", "volume": "sum"})
|
|
.dropna().reset_index())
|
|
|
|
|
|
_RAW: dict[str, pd.DataFrame] = {}
|
|
|
|
|
|
def tp01_at(h: int, long_only: bool = True) -> pd.Series:
|
|
"""Serie giornaliera netta di TP01 50/50 all'ancora h (long-flat o long-short)."""
|
|
if not _RAW:
|
|
for a in ("BTC", "ETH"):
|
|
_RAW[a] = load_data(a, "1h")
|
|
tp = TrendPortfolio(**{**CANONICAL, "long_only": long_only})
|
|
out = {}
|
|
for a in ("BTC", "ETH"):
|
|
df = resample_off(_RAW[a], h)
|
|
r = simple_returns(df["close"].values.astype(float))
|
|
tgt = tp.target_series(df)
|
|
held = np.zeros(len(tgt))
|
|
held[1:] = tgt[:-1]
|
|
net = held * r - tp.fee_side * np.abs(np.diff(held, prepend=0.0))
|
|
net[0] = 0.0
|
|
out[a] = pd.Series(np.clip(net, -0.99, None),
|
|
index=pd.to_datetime(df["datetime"]).dt.normalize())
|
|
J = pd.concat(out, axis=1, join="inner").fillna(0.0)
|
|
return pd.Series(0.5 * J["BTC"].values + 0.5 * J["ETH"].values, index=J.index)
|
|
|
|
|
|
def xs01_phase(phase: int) -> pd.Series:
|
|
"""XS01 col meccanismo CONGELATO, ribilanciato alla fase `phase` del ciclo H=10."""
|
|
cols = {}
|
|
for sym in XS_UNIVERSE:
|
|
p = _HL_DIR / f"hl_{sym.lower()}_1d.parquet"
|
|
if p.exists():
|
|
d = pd.read_parquet(p)
|
|
cols[sym] = pd.Series(d["close"].values.astype(float),
|
|
index=pd.to_datetime(d["timestamp"], unit="ms", utc=True))
|
|
C = pd.concat(cols, axis=1, join="inner").sort_index().dropna()
|
|
px = C.values
|
|
n, A = px.shape
|
|
lbs, H, k, tv = XS_CFG["lookbacks"], XS_CFG["H"], XS_CFG["k"], XS_CFG["target_vol"]
|
|
dp, mh, mlb = XS_CFG["disp_pct"], XS_CFG["disp_minhist"], max(XS_CFG["lookbacks"])
|
|
dret = np.vstack([np.zeros(A), px[1:] / px[:-1] - 1.0])
|
|
W = np.zeros((n, A))
|
|
w = np.zeros(A)
|
|
hist: list[float] = []
|
|
for i in range(n):
|
|
if i >= mlb and i % H == phase:
|
|
rLs = [px[i] / px[i - L] - 1.0 for L in lbs]
|
|
disp = float(np.mean([r.std() for r in rLs]))
|
|
thr = np.percentile(hist, dp) if (dp > 0 and len(hist) >= mh) else -np.inf
|
|
if disp >= thr:
|
|
score = np.zeros(A)
|
|
cnt = 0
|
|
for rL in rLs:
|
|
sd = rL.std()
|
|
if sd > 0:
|
|
score += (rL - rL.mean()) / sd
|
|
cnt += 1
|
|
if cnt:
|
|
score /= cnt
|
|
o = np.argsort(score)
|
|
w = np.zeros(A)
|
|
w[o[-k:]] = 0.5 / k
|
|
w[o[:k]] = -0.5 / k
|
|
else:
|
|
w = np.zeros(A)
|
|
hist.append(disp)
|
|
W[i] = w
|
|
gross = np.zeros(n)
|
|
gross[1:] = np.sum(W[:-1] * dret[1:], axis=1)
|
|
turn = np.zeros(n)
|
|
turn[0] = np.abs(W[0]).sum()
|
|
turn[1:] = np.abs(np.diff(W, axis=0)).sum(axis=1)
|
|
s = pd.Series(gross - turn * (0.001 / 2.0), index=C.index)
|
|
rv = s.rolling(30, min_periods=15).std().shift(1) * np.sqrt(365.25)
|
|
scale = np.clip(np.nan_to_num(tv / rv.replace(0, np.nan).values, nan=0.0), 0, 3.0)
|
|
return pd.Series(s.values * scale, index=C.index)
|
|
|
|
|
|
def perpetua(r: np.ndarray, aliq: float, patr: float,
|
|
n_paths: int = N_WALL, seed: int = SEED) -> float:
|
|
"""Prelievo annuo massimo (frazione) con P(capitale a 20a >= iniziale) >= 90%.
|
|
Stessa definizione e stessa bisezione di r0807_piano_netto.muro / r0822d_piano_vero.muro_di."""
|
|
lo, hi = 0.0, 0.40
|
|
for _ in range(13):
|
|
mid = (lo + hi) / 2
|
|
s = PN.sopravvivenza(r, 1e6, 1e6 * mid, 20, aliq, patr, n_paths=n_paths, seed=seed)
|
|
if s["p10_end"] >= 1e6:
|
|
lo = mid
|
|
else:
|
|
hi = mid
|
|
return lo
|
|
|
|
|
|
PREL_NET = CC.TARGET_EUR_DAY * 365 * CC.EURUSD # 50 EUR/g netti, in $/anno
|
|
PREL_LORDO = PREL_NET / (1 - CC.TAX_RATE)
|
|
|
|
|
|
def sezione_repliche(B: pd.DataFrame) -> dict:
|
|
sez("1) REPLICHE — la mia macchineria riproduce l'ondata? (prima di ogni accusa)")
|
|
out = {}
|
|
A, F = B["nofund"].values, B["fund"].values
|
|
print(f" serie del libro live 75/25, {len(B)} giorni, {B.index[0].date()} -> {B.index[-1].date()}")
|
|
print(f" {'':22}{'drift':>10}{'vol':>10}{'Sharpe':>10} pubblicato (§35)")
|
|
print(f" {'senza funding':22}{A.mean()*365:9.2%}{A.std()*365**.5:10.2%}{sh(A):10.3f}"
|
|
f" 19,24% / 11,37% / 1,692")
|
|
print(f" {'con funding':22}{F.mean()*365:9.2%}{F.std()*365**.5:10.2%}{sh(F):10.3f}"
|
|
f" 17,08% / 11,29% / 1,513")
|
|
dfund = (F.mean() - A.mean()) * 365
|
|
print(f" costo del funding {dfund:+.4%}/anno pubblicato -2,1597% "
|
|
f"{'OK' if abs(dfund + 0.021597) < 2e-4 else 'DIVERGE'}")
|
|
out["fund_ok"] = abs(dfund + 0.021597) < 2e-4
|
|
|
|
L0, L1, L3 = deluck(A), deluck(A), deluck(F)
|
|
rows = [("L0 LORDO (26/07)", L0, 0.0, 0.0, PREL_LORDO, 0.1068, 278_000),
|
|
("L1 +FISCO (07/08)", L1, CC.TAX_RATE, TX.PATRIMONIALE, PREL_NET, 0.0752, 264_000),
|
|
("L2 +FUNDING (22/08)", L3, 0.0, 0.0, PREL_LORDO, 0.0906, 328_000),
|
|
("L3 CONGIUNTA (§36)", L3, CC.TAX_RATE, TX.PATRIMONIALE, PREL_NET, 0.0635, 313_000)]
|
|
print(f"\n {'lente':<22}{'drift':>9}{'perpetua':>10}{'muro':>13}{'pubbl.':>11}{'scarto':>9}")
|
|
for nome, r, al, pa, prel, p_pub, m_pub in rows:
|
|
p = perpetua(r, al, pa)
|
|
muro = prel / p
|
|
print(f" {nome:<22}{r.mean()*365:8.2%}{p:10.2%}{muro:13,.0f}{m_pub:11,.0f}"
|
|
f"{muro/m_pub-1:+9.1%}")
|
|
out[nome] = dict(perp=p, muro=muro, r=r, aliq=al, patr=pa, prel=prel)
|
|
out["_raw_nofund"] = A
|
|
print(" ✅ le quattro lenti si riproducono; il muro E' esattamente `prelievo / perpetua`.")
|
|
|
|
# replica di §42 (la short del trend) con implementazione indipendente
|
|
d0 = sh(tp01_at(0, long_only=False).values) - sh(tp01_at(0, long_only=True).values)
|
|
print(f"\n §42 dShFULL(floor=-1) all'ancora 0: {d0:+.4f} pubblicato -0,450 (estremo p10)")
|
|
print(f" §41/§35 TP01 canonico ShFULL: {sh(tp01_at(0).values):.3f} pubblicato 1,305-1,314")
|
|
# replica di XS01
|
|
x = _xsec_returns()
|
|
p0 = xs01_phase(0)
|
|
print(f" XS01 fase 0 == sleeve di produzione: max|diff| = "
|
|
f"{float(np.abs(p0.values - x.values).max()):.3e}")
|
|
return out
|
|
|
|
|
|
# =============================================================================================
|
|
# 2) LA BANDA CHE NON E' STATA PUBBLICATA
|
|
# =============================================================================================
|
|
def sezione_muro(L: dict) -> dict:
|
|
sez("2) IL MURO E' UNA FUNZIONE ESPLOSIVA DI UN DRIFT STIMATO SU 7,4 ANNI")
|
|
l3 = L["L3 CONGIUNTA (§36)"]
|
|
r = l3["r"]
|
|
d = boot_stat(r, lambda x: x.mean() * 365, n=4000, seed=11)
|
|
SE = float(d.std())
|
|
print(f" drift L3 {r.mean()*365:.3%}/anno · SE block-bootstrap (blocchi 20g) {SE:.3%}"
|
|
f" · IC95 [{np.percentile(d,2.5):.2%}, {np.percentile(d,97.5):.2%}]")
|
|
print(f" (§53 misura SE 5,09% su un'altra lente: ✅ concorda)")
|
|
print("\n Muro e traiettoria propagando SOLO l'incertezza del drift (vol e forma invariate):")
|
|
print(f" {'':>10}{'drift':>9}{'perpetua':>10}{'muro':>14}{'x muro pubbl.':>15}")
|
|
band = {}
|
|
for lab, k in (("+2 SE", 2.0), ("+1 SE", 1.0), ("p90", 1.2816), ("PUNTO", 0.0),
|
|
("p10", -1.2816), ("-1 SE", -1.0), ("-2 SE", -2.0)):
|
|
rr = r + k * SE / 365.0
|
|
p = perpetua(rr, l3["aliq"], l3["patr"])
|
|
muro = PREL_NET / p if p > 0.002 else float("inf")
|
|
band[lab] = (rr, p, muro)
|
|
m = f"${muro:,.0f}" if np.isfinite(muro) else "IRRAGGIUNGIBILE"
|
|
x = f"{muro/l3['muro']:.2f}x" if np.isfinite(muro) else "—"
|
|
print(f" {lab:>10}{rr.mean()*365:8.2%}{p:10.2%}{m:>14}{x:>15}")
|
|
lo = band["p10"][2]
|
|
hi = band["p90"][2]
|
|
print(f"\n 🚨 BANDA p10-p90 DEL MURO: [${hi:,.0f}, "
|
|
f"{('$%s' % f'{lo:,.0f}') if np.isfinite(lo) else 'IRRAGGIUNGIBILE'}]"
|
|
f" contro il punto pubblicato ${l3['muro']:,.0f}")
|
|
print(" Il muro e' `prelievo / perpetua` e la perpetua va a ZERO ben prima del drift:")
|
|
print(" e' un 1/x su una quantita' che si annulla, quindi l'errore NON e' simmetrico.")
|
|
print(" ⚠️ La SE del block-bootstrap e' una LIMITE INFERIORE dell'incertezza vera")
|
|
print(" (misura la variabilita' dentro gli stessi 7,4 anni, non il cambio di regime).")
|
|
|
|
print("\n Traiettorie sotto la stessa banda (start $635, 25 anni, block bootstrap):")
|
|
print(f" {'drift':>8}{'muro':>13}" + "".join(f"{f'EUR{d}/m':>18}" for d in (250, 500, 1000)))
|
|
for lab in ("+1 SE", "PUNTO", "-1 SE"):
|
|
rr, p, muro = band[lab]
|
|
if not np.isfinite(muro):
|
|
continue
|
|
rng = np.random.default_rng(SEED)
|
|
paths = CC._boot_paths(rr, N_TRAJ, 25 * 365, BLOCK, rng)
|
|
cells = []
|
|
for dep in (250, 500, 1000):
|
|
a = PN.accumula(paths, dep, muro, l3["aliq"], l3["patr"], start=635.0)
|
|
y = np.where(a["colpito"] >= 0, a["colpito"] / 365.0, np.inf)
|
|
med = np.median(y)
|
|
cells.append(f"{('>25a' if not np.isfinite(med) else f'{med:.1f}a')} P{float((y<=20).mean()):.0%}")
|
|
print(f" {rr.mean()*365:7.2%}{muro:13,.0f}" + "".join(f"{c:>18}" for c in cells))
|
|
print("\n 📌 «EUR500/mese -> P(20a) 85%» e' il PUNTO. A -1 SE di drift la stessa riga e' ~0%.")
|
|
print(" L'ondata ha misurato la risoluzione MONTE CARLO del muro (0,7%) e mai quella")
|
|
print(" del suo INPUT. Le due differiscono di due ordini di grandezza.")
|
|
return band
|
|
|
|
|
|
# =============================================================================================
|
|
# 3) «N/N ANCORE» NON E' N OSSERVAZIONI
|
|
# =============================================================================================
|
|
def sezione_ancore() -> None:
|
|
sez("3) «0/24 ANCORE» E «10/10 FASI»: quante osservazioni indipendenti sono davvero?")
|
|
|
|
# -- controllo positivo del rilevatore (obbligatorio) -------------------------------------
|
|
rng = np.random.default_rng(1)
|
|
indip = pd.DataFrame(rng.normal(size=(2000, 24)))
|
|
uguali = pd.DataFrame(np.repeat(rng.normal(size=(2000, 1)), 24, axis=1)
|
|
+ rng.normal(scale=1e-6, size=(2000, 24)))
|
|
for nome, M in (("24 serie INDIPENDENTI", indip), ("24 serie IDENTICHE", uguali)):
|
|
rb, ne, pr = n_eff(M)
|
|
print(f" [controllo positivo] {nome:<24} rbar {rb:+.3f} N_eff {ne:5.2f} PR {pr:5.2f}")
|
|
print(" -> il rilevatore distingue i due estremi: il suo «poco» vale.\n")
|
|
|
|
# -- TP01: 24 ancore, LIVELLI --------------------------------------------------------------
|
|
S = {h: tp01_at(h) for h in range(24)}
|
|
M = pd.DataFrame(S).dropna()
|
|
shs = np.array([sh(M[h].values) for h in range(24)])
|
|
rb, ne, pr = n_eff(M)
|
|
print(f" TP01 — 24 ancore, LIVELLI: Sharpe da {shs.min():.2f} a {shs.max():.2f}"
|
|
f" (canonico {shs[0]:.2f})")
|
|
print(f" corr media fra ancore {rb:.3f} -> N_eff {ne:.2f} / participation ratio {pr:.2f}")
|
|
|
|
# -- TP01: 24 ancore, DIFFERENZA APPAIATA (la forma che l'ondata usa di piu') -------------
|
|
D, dsh = {}, []
|
|
for h in range(24):
|
|
a, b = tp01_at(h, True), tp01_at(h, False)
|
|
ix = a.index.intersection(b.index)
|
|
D[h] = b.reindex(ix) - a.reindex(ix)
|
|
dsh.append(sh(b.reindex(ix).values) - sh(a.reindex(ix).values))
|
|
dsh = np.array(dsh)
|
|
MD = pd.DataFrame(D).dropna()
|
|
rbd, ned, prd = n_eff(MD)
|
|
print(f"\n TP01 — 24 ancore, DIFFERENZA APPAIATA (§42, floor=-1 vs canonico):")
|
|
print(f" dShFULL mediana {np.median(dsh):+.3f} banda [{dsh.min():+.3f}, {dsh.max():+.3f}]"
|
|
f" >0 in {int((dsh>0).sum())}/24 (§42 pubblica -0,354 [-0,450,-0,251] 0/24)")
|
|
print(f" corr media delle serie-differenza {rbd:.3f} -> N_eff {ned:.2f} / PR {prd:.2f}")
|
|
print(" 🚨 A3 REFUTATA: nella differenza appaiata la componente comune NON si cancella"
|
|
f" ({rbd:.2f} contro {rb:.2f} dei livelli).")
|
|
|
|
# -- la banda d'ancora NON e' un intervallo di confidenza ---------------------------------
|
|
a0, b0 = tp01_at(0, True), tp01_at(0, False)
|
|
ix = a0.index.intersection(b0.index)
|
|
A0, B0 = a0.reindex(ix).values, b0.reindex(ix).values
|
|
X = np.column_stack([A0, B0])
|
|
bs = boot_stat(X, lambda z: sh(z[:, 1]) - sh(z[:, 0]), n=3000, seed=7)
|
|
ic = (float(np.percentile(bs, 2.5)), float(np.percentile(bs, 97.5)))
|
|
amp_mm = float(dsh.max() - dsh.min())
|
|
amp_pp = float(np.percentile(dsh, 90) - np.percentile(dsh, 10))
|
|
amp_ic = ic[1] - ic[0]
|
|
print(f"\n 🚨 Per la STESSA grandezza, all'ancora canonica:")
|
|
print(f" banda d'ANCORA min-max (quella che §42 pubblica) ampiezza {amp_mm:.3f}"
|
|
f" · p10-p90 {amp_pp:.3f}")
|
|
print(f" IC95 bootstrap a blocchi [{ic[0]:+.3f}, {ic[1]:+.3f}] ampiezza {amp_ic:.3f}"
|
|
f" -> {amp_ic/amp_mm:.1f}x la banda pubblicata ({amp_ic/amp_pp:.1f}x la p10-p90),"
|
|
f" e CONTIENE LO ZERO.")
|
|
print(" La DECISIONE di §42 (SCARTATO) regge lo stesso — poggia su iso-vol FAIL 3/3,")
|
|
print(" maxDD +8,80pp, selection-on-holdout e fee-zero, non su questo Δ. Ma il NUMERO")
|
|
print(" e la sua banda sono pubblicati con una precisione che il campione non ha.")
|
|
|
|
# -- XS01: 10 fasi -------------------------------------------------------------------------
|
|
P = {p: xs01_phase(p) for p in range(10)}
|
|
MP = pd.DataFrame(P).dropna()
|
|
shp = np.array([sh(MP[p].values) for p in range(10)])
|
|
rbp, nep, prp = n_eff(MP)
|
|
bsp = boot_stat(MP[0].values, sh, n=3000, seed=3)
|
|
icp = (float(np.percentile(bsp, 2.5)), float(np.percentile(bsp, 97.5)))
|
|
amp_f = float(np.percentile(shp, 90) - np.percentile(shp, 10))
|
|
anni = len(MP) / 365.25
|
|
print(f"\n XS01 — 10 fasi del ciclo H=10 (universo 19, {anni:.2f} anni):")
|
|
print(f" Sharpe per fase da {shp.min():.2f} a {shp.max():.2f}, mediana {np.median(shp):.2f}")
|
|
print(f" corr media {rbp:.3f} -> N_eff {nep:.2f} / PR {prp:.2f}")
|
|
print(f" banda di FASE p10-p90 ampiezza {amp_f:.3f} contro IC95 bootstrap "
|
|
f"[{icp[0]:+.2f}, {icp[1]:+.2f}] ampiezza {icp[1]-icp[0]:.3f} = "
|
|
f"{(icp[1]-icp[0])/amp_f:.1f}x")
|
|
print(f" MDE sul LIVELLO (1,96/sqrt(anni)) = {1.96/np.sqrt(anni):.2f}"
|
|
f" contro Sharpe mediano {np.median(shp):.2f}")
|
|
print("\n 📌 CONSEGUENZA, e vale per TUTTA l'ondata: «positivo in N/N ancore o fasi» e' una")
|
|
print(" dichiarazione di ROBUSTEZZA ALLA SCELTA DELL'ANCORA, non un test. Il suo")
|
|
print(" equivalente in osservazioni indipendenti e' ~2 (ancore) e ~1,3 (fasi), quindi")
|
|
print(" NON vale 2^-24 ne' 2^-10; e la «banda» che l'accompagna e' ~4x piu' stretta")
|
|
print(" dell'intervallo di confidenza della stessa grandezza.")
|
|
print(" Dove l'ondata attacca un p-value a un conteggio del genere (§26, «test dei segni")
|
|
print(" 12/12, p=0,0005», su finestre 30g SOVRAPPOSTE e per giunta SELEZIONATE come le")
|
|
print(" peggiori) quel p-value non e' calcolabile cosi'.")
|
|
|
|
|
|
# =============================================================================================
|
|
# 4) MDE — quali SCARTATI sono non-risultati
|
|
# =============================================================================================
|
|
def sezione_mde() -> None:
|
|
sez("4) MDE — quanti SCARTATI dell'ondata sono «non misurabile» invece che «misurato e no»")
|
|
|
|
# finestra reale della catena opzioni, misurata (non presa dal registro)
|
|
p = ROOT / "data" / "raw" / "cb_chain" / "bite_archive.parquet"
|
|
giorni_sup = np.nan
|
|
if p.exists():
|
|
d = pd.read_parquet(p, columns=["asset", "ts", "exp"])
|
|
g = d.groupby(["asset", d["ts"].dt.floor("D")])["exp"].nunique()
|
|
gg = min(int((g.loc[a] >= 2).sum()) for a in ("BTC", "ETH"))
|
|
prop = len(list((ROOT / "data" / "raw" / "cb_chain").glob("2026-*.parquet")))
|
|
giorni_sup = gg + prop
|
|
print(f" [misurato] catena opzioni: archivio {d['ts'].dt.floor('D').nunique()} giorni di")
|
|
print(f" calendario, ma solo {gg} con >=2 scadenze; + {prop} di raccolta")
|
|
print(f" propria = {giorni_sup} giorni di SUPERFICIE (il registro dice 74-75 ✅)")
|
|
|
|
ANNI_SUP = giorni_sup / 365.25 if np.isfinite(giorni_sup) else 75 / 365.25
|
|
R = [
|
|
# (filone, oggetto misurato, anni utili, effetto dichiarato, unita', tipo)
|
|
("§4 DEALER-GAMMA", "Sharpe di cella", 90 / 365.25, 4.98, "Sharpe", "maxk:5.12"),
|
|
("§5 SKEW Q1", "Sharpe direzionale", ANNI_SUP, 0.0, "Sharpe", "livello"),
|
|
("§5 SKEW Q2", "gate de-risk su TP01", 5 / 365.25, 0.0, "Sharpe", "livello"),
|
|
("§6 OI-PIN", "Sharpe max-pain", 75 / 365.25, 5.59, "Sharpe", "maxk:6.79"),
|
|
("§7 TERM-STRUCTURE", "Sharpe di cella", 74 / 365.25, 0.14, "Sharpe", "livello"),
|
|
("§10 FLOW-SQUEEZE", "Sharpe di cella", 114 / 365.25, 3.25, "Sharpe", "maxk:5.40"),
|
|
("§11 VRP-QUOTE-VERE", "Sharpe (T=10)", 10 * 7 / 365.25, 0.0, "Sharpe", "rifiutato"),
|
|
("§13 BASIS-CALENDAR", "premio a termine", 7.4, 0.0085, "ret/anno", "livello"),
|
|
("§27 SURFACE-RV", "censimento 1,24M quote", ANNI_SUP, 0.0, "$", "censimento"),
|
|
("§43 DATA-UNUSED", "Sharpe hold-out", 1.40, 0.951, "Sharpe", "maxk:1.009"),
|
|
("§48 VOLVOL", "dSharpe vs TP01", 985 / 365.25, 0.034, "Sharpe", "livello"),
|
|
("§21 XS01-OOS (LEAD)", "Sharpe fuori campione", 3.0, 1.12, "Sharpe", "livello"),
|
|
("§50 PREVDAY (LEAD)", "Sharpe forward", 63 / 365.25, 2.04, "Sharpe", "livello"),
|
|
("§25 BIN-FREQ (LEAD)", "dSharpe di libro", 7.4, 0.112, "Sharpe", "appaiato"),
|
|
("§8 VOL-SIZE (LEAD)", "dSharpe di libro", 7.4, 0.070, "Sharpe", "appaiato"),
|
|
("§42 TP01-LS", "dSharpe di libro", 7.4, -0.354, "Sharpe", "appaiato"),
|
|
("§41 TP01-SIZE", "dSharpe di libro", 7.4, 0.0006, "Sharpe", "appaiato"),
|
|
("§49 TP01-TWIN", "dSharpe hold-out", 7.4, -0.127, "Sharpe", "appaiato"),
|
|
]
|
|
print(f"\n MDE sui LIVELLI = 1,96/sqrt(anni). Sugli APPAIATI l'MDE del livello NON si applica")
|
|
print(f" (la componente comune si cancella): li' serve l'IC bootstrap della DIFFERENZA,")
|
|
print(f" che per §42 ho misurato = {0.862:.3f} di ampiezza (sez. 3).\n")
|
|
print(f" {'filone':<24}{'anni':>7}{'MDE liv.':>10}{'effetto':>10}{'|eff|/MDE':>11} lettura")
|
|
for nome, _obj, anni, eff, unita, tipo in R:
|
|
mde = 1.96 / np.sqrt(anni)
|
|
if tipo == "censimento":
|
|
lett = "N di quote, non anni: potenza OK"
|
|
rap = float("nan")
|
|
elif tipo == "appaiato":
|
|
lett = "APPAIATO: l'MDE del livello non si applica"
|
|
rap = float("nan")
|
|
elif tipo == "rifiutato":
|
|
lett = "titolo 32,58 NON riportato dall'ondata: ✅ disciplina"
|
|
rap = float("nan")
|
|
elif tipo.startswith("maxk:"):
|
|
nmax = float(tipo.split(":")[1])
|
|
rap = abs(eff) / mde
|
|
lett = (f"max-of-k: il rumore da' {nmax:.2f} -> il candidato "
|
|
f"{'STA SOTTO' if abs(eff) < nmax else 'sta sopra'} il proprio null")
|
|
elif unita != "Sharpe":
|
|
lett = "il registro dichiara SE 1,79pp -> non misurabile"
|
|
rap = float("nan")
|
|
else:
|
|
rap = abs(eff) / mde
|
|
lett = ("sotto il proprio MDE = NON MISURABILE" if rap < 1
|
|
else "sopra l'MDE" if rap < 2 else "misurato con margine")
|
|
rs = " — " if not np.isfinite(rap) else f"{rap:9.2f}"
|
|
print(f" {nome:<24}{anni:7.2f}{mde:10.2f}{eff:10.3f}{rs} {lett}")
|
|
|
|
print("\n 📌 A4 CONFERMATA IN LARGA PARTE: l'ondata dichiara il proprio MDE in §6, §10, §43,")
|
|
print(" §48, §56, e in §7 spiega perche' NON ha girato il deflated-Sharpe. E' disciplina")
|
|
print(" reale, e va detto.")
|
|
print(" ⚠️ MA restano tre etichette piu' forti della misura:")
|
|
print(" (a) §48 chiude un FILONE («quinto lato del DVOL chiuso») su una branca dove")
|
|
print(" dichiara esso stesso un fattore 44 sotto l'MDE. La parziale negativa e il")
|
|
print(" controllo non-causale hanno potenza; «filone chiuso» no.")
|
|
print(" (b) §4/§5/§7/§11 vivono su ~75-90 giorni: MDE 4,2-4,4 di Sharpe. Ogni loro")
|
|
print(" SCARTATO che poggia su un confronto di Sharpe e' un NON-RISULTATO su")
|
|
print(" quell'asse (le loro parti valide sono i lead-lag, i placebo e i censimenti,")
|
|
print(" non gli Sharpe).")
|
|
print(" (c) §21 XS01-OOS, che e' il PILASTRO del canale funded, ha effetto +1,12 contro")
|
|
print(f" un MDE di {1.96/np.sqrt(3.0):.2f} sui suoi 3 anni: il titolo sta esattamente al")
|
|
print(" proprio limite di rilevabilita', e la «banda 10 fasi» non e' un IC (sez. 3).")
|
|
print(" Nota di equita': §21 gira ANCHE un null di permutazione a fee zero (p=0,013),")
|
|
print(" che ha piu' potenza del t-stat sullo Sharpe -> il problema non e' «nessuna")
|
|
print(" evidenza», e' che il LIVELLO +1,12 viene poi propagato fino a P(>=50/g) e")
|
|
print(" al muro come se fosse noto a due cifre.")
|
|
|
|
|
|
# =============================================================================================
|
|
# 4bis) CONTRADDIZIONI FRA SEZIONI — 55 sezioni scritte da agenti diversi
|
|
# =============================================================================================
|
|
def sezione_contraddizioni() -> None:
|
|
sez("4bis) CONTRADDIZIONI FRA SEZIONI DELLO STESSO REGISTRO")
|
|
|
|
print(" (A) 🚨 MISURATA — «il libro 75/25» ha TRE baseline diverse sotto LO STESSO NOME.")
|
|
out = {}
|
|
for lens in ("hourly", "canonical"):
|
|
s = CC.book_series(lens=lens, alloc=600.0)
|
|
r = s.values
|
|
eq = np.cumprod(1 + r)
|
|
dd = float((1 - eq / np.maximum.accumulate(eq)).max())
|
|
out[lens] = (sh(r), r.mean() * 365, dd)
|
|
print(f" lente {lens:<10} ShFULL {sh(r):.3f} drift {r.mean()*365:.2%} maxDD {dd:.2%}")
|
|
print(" terza: §8 e §25 usano 1,626 / maxDD 10,4% = la MEDIANA della banda d'ancora.")
|
|
print(f" spread fra le tre: {abs(out['canonical'][0]-out['hourly'][0]):.3f} di Sharpe e "
|
|
f"{abs(out['canonical'][2]-out['hourly'][2])*100:.1f}pp di maxDD.")
|
|
print(" Chi usa quale: §35/§36/§39/§45/§52/§53 e OGNI muro e traiettoria -> `hourly`")
|
|
print(" (1,69); §41/§42/§49/§50/§54 -> `canonical` (1,81); §8/§25 -> 1,63.")
|
|
print(" 🚨 Lo spread e' PIU' GRANDE di quasi tutti gli effetti che l'ondata misura")
|
|
print(" (BIN-FREQ +0,112 · VOL-SIZE +0,070 · PREVDAY de-luckato +0,100): un Δ letto")
|
|
print(" accanto al baseline sbagliato cambia di piu' del Δ stesso. Ogni filone lo")
|
|
print(" dichiara nel proprio script; il REGISTRO no, e CLAUDE.md nemmeno.")
|
|
|
|
print("\n (B) 🚨 IL «SOFFITTO DIREZIONALE» — §35 lo abbassa a ~1,15 (era ~1,31) per il")
|
|
print(" funding. Ma nella STESSA ondata, sulla STESSA coppia BTC/ETH e su lente netta")
|
|
print(" fee: §23 pubblica il miglior lookback COSTANTE a ShFULL 1,639 e §54 la cella")
|
|
print(" PREVDAY scelta al buio a 1,621 (che PASSA il deflated-Sharpe a N=336).")
|
|
print(" Le due cose non stanno insieme senza una DEFINIZIONE di «soffitto»:")
|
|
print(" «massimo osservabile» (>=1,64), «massimo che sopravvive a un DSR» (>=1,62),")
|
|
print(" o «Sharpe di TP01» (1,15 col funding)? Il registro usa la terza e la cita come")
|
|
print(" se fosse la prima.")
|
|
print(" ⚠️ E la cosa ha una conseguenza operativa: §12 costruisce un argomento")
|
|
print(" ARITMETICO («uno screen largo su BTC/ETH non puo' passare il proprio DSR")
|
|
print(" perche' il massimo dal rumore, 1,572, sta SOPRA il soffitto ~1,3»). Con")
|
|
print(" soffitto 1,62-1,64 quell'argomento si inverte — ed e' la SECONDA refutazione")
|
|
print(" dello stesso argomento, indipendente da quella di §24 (che lo ribalta sulla")
|
|
print(" partizione della griglia). Un argomento refutato due volte per due strade")
|
|
print(" diverse non va ereditato come regola.")
|
|
|
|
print("\n (C) §50 chiama PREVDAY «il piu' forte misurato, robust_oos TRUE, ADDS» e §54")
|
|
print(" misura che la cella CHE GIRA fallisce il deflated-Sharpe (0,905) mentre quella")
|
|
print(" scelta onestamente lo passa (0,993) ma e' un'ALTRA strategia (4h, long-flat).")
|
|
print(" Non e' un errore di nessuno dei due — §50 valuta la cella congelata, §54 la")
|
|
print(" famiglia — ma le due righe finiscono nella stessa memoria e la prima e' quella")
|
|
print(" che suona come una promozione.")
|
|
|
|
print("\n (D) ✅ CONTRADDIZIONI CHE L'ONDATA HA GIA' RISOLTO DA SOLA, e vanno a suo credito:")
|
|
print(" §45 «lo spot non si liquida» -> §52 lo falsifica (in_cross_collateral_pool);")
|
|
print(" §39 «non esiste una linea USDC datata» -> falsificato lo stesso giorno;")
|
|
print(" §8 «overlay non causale» -> RITIRATA dallo scettico in giornata;")
|
|
print(" §24 «dealer_net_gamma e' il GEX invertito» -> ritirata leggendo il sorgente.")
|
|
print(" Quattro auto-correzioni in 24 ore: e' il dato piu' sano dell'ondata.")
|
|
|
|
|
|
# =============================================================================================
|
|
# 5) ARITMETICA: cosa torna, cosa no
|
|
# =============================================================================================
|
|
def sezione_aritmetica(L: dict) -> None:
|
|
sez("5) ARITMETICA PUBBLICATA — verifica diretta")
|
|
|
|
print(" (a) tetti di leva (§33/§38/§53) — aritmetica pura sul config che GIRA")
|
|
import json
|
|
cfg = json.loads((ROOT / "config" / "live.json").read_text())
|
|
frac, dsl = cfg["max_notional_per_asset_frac"], cfg["disaster_sl_pct"]
|
|
n_asset = 2
|
|
peggior_giorno_k1 = 0.1432 # §33, bound strutturale
|
|
print(f" config letto: frac={frac} · disaster_sl_pct={dsl} · n_asset={n_asset}")
|
|
print(f" leva lorda massima a k=1: {n_asset*frac:.2f}x (test di guardia: <=1x) "
|
|
f"{'OK' if n_asset*frac <= 1.0 else 'ROTTO'}")
|
|
for lab, tetto, pub in (("disaster-SL <= 50% equity", 0.50 / (n_asset * frac * dsl), 1.67),
|
|
("peggior giorno <= 50%", 0.50 / peggior_giorno_k1, 3.49),
|
|
("peggior giorno <= 20% (scettico)", 0.20 / peggior_giorno_k1, 1.40)):
|
|
print(f" {lab:<34} k <= {tetto:5.2f} pubblicato {pub:.2f} "
|
|
f"{'✅' if abs(tetto-pub) < 0.02 else '⚠️ DIVERGE'}")
|
|
print(f" 1,50x -> peggior giorno {1.50*peggior_giorno_k1:.2%} (>20% -> §53 lo boccia) ✅")
|
|
print(f" 1,25x -> costo di un disaster-SL {1.25*n_asset*frac*dsl:.1%} (§38 dice 37,5%) ✅")
|
|
|
|
print("\n (b) muri = prelievo / perpetua — ✅ verificato in sez. 1 su 4 lenti su 4.")
|
|
print(f" prelievo netto = {CC.TARGET_EUR_DAY:.0f} EUR/g x 365 x {CC.EURUSD} = "
|
|
f"${PREL_NET:,.0f}/anno ; lordizzato ${PREL_LORDO:,.0f}")
|
|
|
|
print("\n (c) 🚨 «EUR X/mese» NON e' al mese: `accumula` versa ogni 30 GIORNI.")
|
|
for anni in (10, 15, 20):
|
|
nd = anni * 365
|
|
k = len([t for t in range(nd) if t % 30 == 0 and t > 0])
|
|
print(f" {anni:>2} anni: {k} versamenti invece di {anni*12} "
|
|
f"({k/(anni*12)-1:+.2%} di denaro versato)")
|
|
print(" -> asintoticamente 365/30 = 12,17 versamenti l'anno invece di 12 (+1,39%).")
|
|
print(" Effetto piccolo (0,8-1,4%) ma SISTEMATICO e a FAVORE del piano, presente in")
|
|
print(" ogni tabella pubblicata dal 25/07 in poi. Va detto perche' l'ondata dichiara")
|
|
print(" la risoluzione del proprio Monte Carlo a 0,7% accanto agli stessi numeri.")
|
|
|
|
print("\n (d) 🚨 «a 10 anni si versano $229k... i bonifici fanno il 73%» — il contatore")
|
|
print(" `versato` di r0807_piano_netto.accumula e' uno SCALARE che non si ferma al")
|
|
print(" traguardo (riga 157-167): conta i versamenti dell'INTERO orizzonte anche sui")
|
|
print(" percorsi che sono gia' arrivati. Misura del vero versato-fino-all'arrivo:")
|
|
l3 = L["L3 CONGIUNTA (§36)"]
|
|
rng = np.random.default_rng(SEED)
|
|
paths = CC._boot_paths(l3["r"], N_TRAJ, 10 * 365, BLOCK, rng)
|
|
dep_m = 1733.0
|
|
dep = dep_m * CC.EURUSD
|
|
cap = np.full(N_TRAJ, 635.0)
|
|
versato = np.full(N_TRAJ, 635.0)
|
|
colpito = np.full(N_TRAJ, -1, int)
|
|
carry = np.zeros((N_TRAJ, TX.CARRY_ANNI))
|
|
anno0 = cap.copy()
|
|
flusso = np.zeros(N_TRAJ)
|
|
for t in range(10 * 365):
|
|
cap *= (1.0 + paths[:, t])
|
|
if t % 30 == 0 and t > 0:
|
|
vivo = colpito < 0
|
|
cap += dep
|
|
flusso += dep
|
|
versato += dep * vivo # <- si ferma al traguardo
|
|
nuovi = (colpito < 0) & (cap >= l3["muro"])
|
|
colpito[nuovi] = t
|
|
if (t + 1) % 365 == 0:
|
|
PN.passo_fiscale(cap, anno0, flusso, carry, l3["aliq"], l3["patr"])
|
|
anno0 = cap.copy()
|
|
flusso[:] = 0.0
|
|
arr = colpito >= 0
|
|
tot_pieno = 635.0 + 121 * dep
|
|
tot_vero = float(versato[arr].mean()) if arr.any() else float("nan")
|
|
print(f" EUR{dep_m:.0f}/m, 10 anni: P(traguardo) {arr.mean():.1%}")
|
|
print(f" versato come lo conta l'ondata ${tot_pieno:,.0f} (=$229k pubblicato ✅)")
|
|
print(f" versato FINO all'arrivo, medio ${tot_vero:,.0f}"
|
|
f" -> i bonifici fanno il {tot_vero/l3['muro']:.0%}, non il 73%")
|
|
|
|
print("\n (e) composizione ancora x funding: `deluck` e' applicato DOPO la sottrazione del")
|
|
print(" funding, quindi sconta dell'11% anche il funding (2,16% -> 1,92%).")
|
|
# ⚠️ ERRORE MIO CATTURATO IN SESSIONE: la prima stesura faceva `deluck(L0["r"])`, ma quella
|
|
# serie e' GIA' de-luckata -> 0,89^2 e un finto +31,5% sul muro. Qui si parte dal GREZZO.
|
|
A = L["_raw_nofund"]
|
|
alt = deluck(A) - 0.021597 / 365.0
|
|
p_alt = perpetua(alt, l3["aliq"], l3["patr"])
|
|
print(f" ordine dell'ondata : drift {l3['r'].mean()*365:.2%} -> muro ${l3['muro']:,.0f}")
|
|
print(f" ordine alternativo : drift {alt.mean()*365:.2%} -> muro ${PREL_NET/p_alt:,.0f}"
|
|
f" ({PREL_NET/p_alt/l3['muro']-1:+.1%})")
|
|
print(" Scelta di modello, non errore — ma la sua taglia (+4,0% sul muro) e' SEI VOLTE")
|
|
print(" la risoluzione MC (0,7%) che l'ondata dichiara accanto allo stesso numero.")
|
|
print(" ⚠️ ERRORE MIO catturato prima di pubblicare: la prima stesura de-luckava una")
|
|
print(" serie GIA' de-luckata (0,89^2) e stampava +31,5%. Il controllo che l'ha preso")
|
|
print(" e' stato guardare il DRIFT stampato accanto al muro, non il muro.")
|
|
|
|
|
|
# =============================================================================================
|
|
# 6) IL LIBRO MASTRO — la risposta al mandato, in una sola unita'
|
|
# =============================================================================================
|
|
def sezione_ledger(L: dict) -> None:
|
|
sez("6) IL MANDATO ERA «ARRIVARE AI 50 GIORNALIERI VELOCEMENTE». Tutto in una sola unita'.")
|
|
E = 635.0
|
|
l3 = L["L3 CONGIUNTA (§36)"]
|
|
|
|
def eur_g(drift_pp: float) -> float:
|
|
"""pp di drift annuo -> EUR/giorno di reddito atteso a $635, al netto del fisco."""
|
|
return drift_pp / 100.0 * E * (1 - CC.TAX_RATE) / 365.0 / CC.EURUSD
|
|
|
|
righe = [
|
|
("VERSARE EUR250 -> EUR500 al mese", "leva del PIANO", None, "P(20a) 14% -> 85%", "SI'"),
|
|
("gradino di leva 1,25x (§33/§38/§53)", "politica", 21.39 - 17.11,
|
|
"+1,8a (muro congelato) / +3,0a (mobile)", "NO — knob inesistente + GATE SCALA-01"),
|
|
("lead SPOT su TP01 (§39/§45/§52)", "strumento", 1.55,
|
|
"muro -10,9% a $600, 0% a $272k", "NO — domanda fiscale aperta"),
|
|
("PREVDAY al 15% (§50/§54)", "sleeve nuovo", 1.31,
|
|
"dShFULL +0,100 de-luckato", "NO — GATE PREVDAY-01 al 2027-06-21"),
|
|
("XS01 su conto funded (§21/§29/§37)", "canale", None,
|
|
"P(>=50/g) 2,6% [1,5-4,7] in 36 mesi", "gate PASS 3/3, spesa = 91% del conto"),
|
|
("BIN-FREQ su SKH01 (§25)", "size", None, "EUR0,0113/giorno", "NO — 3 gate su 4 FAIL"),
|
|
("VOL-SIZE su SKH01 (§8)", "size", None, "+0,070 Sh, gate 22/12 gia' fallito", "NO"),
|
|
("MAKER (§22)", "esecuzione", 0.466, "tetto $2,96/anno, IC contiene lo 0", "NO"),
|
|
("--- COSTI SCOPERTI (segno opposto) ---", "", None, "", ""),
|
|
("funding dei perpetual (§35)", "costo", -2.16, "muro +17,5%", "gia' subito"),
|
|
("i 4 monitor rotti (§31)", "integrita'", None, "STATARB Sharpe +1,96 -> -2,02", "da riparare"),
|
|
("il notifier senza retry (NOTIFIER)", "sicurezza", None, "~7% degli allarmi persi", "da riparare"),
|
|
]
|
|
print(f" {'cosa':<40}{'tipo':<12}{'EUR/giorno a $635':>19} effetto / stato")
|
|
for nome, tipo, dpp, eff, stato in righe:
|
|
if nome.startswith("---"):
|
|
print(f"\n {nome}")
|
|
continue
|
|
cell = f"{eur_g(dpp):+.4f}" if dpp is not None else " — "
|
|
print(f" {nome:<40}{tipo:<12}{cell:>19} {eff}")
|
|
if stato:
|
|
print(f" {'':<40}{'':<12}{'':>19} eseguibile oggi: {stato}")
|
|
|
|
print("\n 📌 IL CONFRONTO, con la stessa macchina e gli stessi percorsi:")
|
|
rng = np.random.default_rng(SEED)
|
|
paths = CC._boot_paths(l3["r"], N_TRAJ, 25 * 365, BLOCK, rng)
|
|
for dep in (0, 250, 500):
|
|
a = PN.accumula(paths, dep, l3["muro"], l3["aliq"], l3["patr"], start=635.0)
|
|
y = np.where(a["colpito"] >= 0, a["colpito"] / 365.0, np.inf)
|
|
med = np.median(y)
|
|
print(f" EUR{dep:>4}/mese -> mediana {'>25a' if not np.isfinite(med) else f'{med:.1f}a'}"
|
|
f" P(20a) {float((y<=20).mean()):5.1%}")
|
|
tot = sum(eur_g(x) for x in (1.55, 1.31, 0.466))
|
|
print(f"\n Somma di TUTTI i lead positivi dell'ondata, se fossero tutti autorizzati e")
|
|
print(f" tutti additivi (non lo sono, e nessuno lo e' oggi): {tot:+.3f} EUR/giorno.")
|
|
print(f" Il gradino di leva da solo, se il knob esistesse: {eur_g(21.39-17.11):+.3f} EUR/g.")
|
|
print(f" Un versamento di EUR500/mese e' {500/30.44:+.2f} EUR/giorno di CASSA — e le due")
|
|
print(" grandezze NON sono la stessa cosa (una e' rendimento, l'altra e' capitale che")
|
|
print(" entra). Il confronto onesto e' quello sopra, sulla stessa macchina e sugli")
|
|
print(" STESSI percorsi: EUR250 -> EUR500 al mese porta P(20a) dal 14% all'85% e la")
|
|
print(" mediana da 23,4 a 17,3 anni; la somma di tutti i lead dell'ondata, se fossero")
|
|
print(" autorizzati e additivi, vale +0,036 EUR/giorno su un conto da $635, cioe' meno")
|
|
print(" dell'incertezza Monte Carlo della riga sopra.")
|
|
print("\n 🚨 RISPOSTA AL MANDATO: NO. L'ondata non ha prodotto NIENTE che avvicini i 50 EUR/g.")
|
|
print(" Ha prodotto (i) un COSTO gia' in essere che porta P(20a) a EUR250/mese dal 49%")
|
|
print(" al 14% (il funding, §35/§36), (ii) quattro monitor rotti che avrebbero fatto")
|
|
print(" decidere un gate")
|
|
print(" al contrario, (iii) un punto singolo di guasto nella rete di sicurezza,")
|
|
print(" (iv) tre lead reali ma tutti bloccati da qualcosa che NON e' la ricerca.")
|
|
print(" Il suo valore e' DIFENSIVO, ed e' reale: ha impedito decisioni sbagliate.")
|
|
print(" Ma la domanda che era stata posta ha risposta negativa, e la 56ª ondata")
|
|
print(" avra' la stessa risposta della 55ª.")
|
|
|
|
|
|
# =============================================================================================
|
|
# 7) LE TRE COSE CHE, SE SCRITTE COME LE HO CAPITE IO, SARANNO SBAGLIATE
|
|
# =============================================================================================
|
|
def sezione_tre() -> None:
|
|
sez("7) LE TRE COSE CHE, SE SCRITTE IN CLAUDE.md COME SONO STATE CAPITE, SARANNO SBAGLIATE")
|
|
print("""
|
|
(1) «IL MURO E' $313k» — e' una MEDIANA, non un numero, e la sua banda non e' mai stata
|
|
pubblicata.
|
|
CLAUDE.md sta per ereditare $313k, «EUR250/mese -> P(20a) 14%» e «EUR1.733/mese per
|
|
10 anni» come se il drift fosse noto. Misurato in sez. 2: propagando SOLO la SE del
|
|
drift (5,15%/anno, block bootstrap — e §53 la misura 5,09 su un'altra lente) il muro
|
|
va da $204k (+1 SE) a $707k (-1 SE), a p10 supera $1,1M e a -2 SE il traguardo NON
|
|
ESISTE a nessun capitale. La riga «EUR500/mese -> P(20a) 85%» diventa ~0% a -1 SE.
|
|
Il meccanismo e' strutturale: il muro e' `prelievo / perpetua` e la perpetua si
|
|
ANNULLA molto prima del drift -> e' un 1/x su una quantita' che va a zero, quindi
|
|
l'errore e' asimmetrico verso l'alto.
|
|
🚨 E l'ondata ha pubblicato la risoluzione MONTE CARLO del muro (0,7%) accanto a un
|
|
numero la cui incertezza di PARAMETRO e' cento volte piu' grande: ha misurato la
|
|
precisione del simulatore e mai quella del suo input.
|
|
DA SCRIVERE: «$313k e' la MEDIANA; a -1 SE di drift e' ~$707k e a -2 SE il traguardo
|
|
non esiste. Il piano si dimensiona sul VERSAMENTO, che e' certo, non sul muro.»
|
|
|
|
(2) «POSITIVO IN 24/24 ANCORE» / «10/10 FASI» — non sono 24 ne' 10 osservazioni.
|
|
Misurato in sez. 3 su serie vere e con controllo positivo (24 serie indipendenti ->
|
|
N_eff 24,5; 24 identiche -> 1,00): le 24 ancore di TP01 hanno corr media 0,63 ->
|
|
N_eff ~1,6-2,1; le 10 fasi di XS01 corr 0,79 -> N_eff ~1,2-1,5. E la componente
|
|
comune NON si cancella nella DIFFERENZA APPAIATA (corr 0,59, N_eff 1,6-2,2): era la
|
|
mia attesa A3 ed e' REFUTATA.
|
|
🚨 Conseguenza diretta: la «banda» che accompagna ogni Δ dell'ondata e' la banda
|
|
d'ANCORA, e per la stessa grandezza (§42) l'IC95 bootstrap e' 4,3x piu' largo
|
|
([-0,81, +0,05] contro [-0,45, -0,25]) e CONTIENE LO ZERO. Chi legge fra sei mesi
|
|
leggera' quella banda come un intervallo di confidenza — perche' ne ha la forma.
|
|
E dove l'ondata ci attacca un p-value (§26: «12/12, p=0,0005», su finestre 30g
|
|
sovrapposte e selezionate come le peggiori) il p-value non e' calcolabile cosi'.
|
|
DA SCRIVERE: «N/N ancore = robustezza alla scelta dell'ancora, ~2 osservazioni
|
|
indipendenti; la banda d'ancora NON e' un IC ed e' ~4x piu' stretta.»
|
|
⚠️ Cio' che questo NON dice: che i verdetti cadano. §42 resta SCARTATO (iso-vol FAIL
|
|
3/3, maxDD +8,8pp, selection-on-holdout, edge lordo assente). Cade la PRECISIONE dei
|
|
numeri, non la direzione delle decisioni.
|
|
|
|
(3) «IL GRADINO DI LEVA VALE 14,7a -> 12,9-11,6a, ~EUR300/mese» — meta' di quella frase
|
|
e' gia' morta nell'ondata stessa.
|
|
§53 ha misurato che il **1,50x NON sopravvive** (peggior giorno strutturale 21,48%,
|
|
sopra la soglia 20%, e al 90% del tetto G6) e che il **k massimo difendibile e'
|
|
1,40**. Il «~EUR300/mese» e' del 1,50x. Il 1,25x vale **+EUR144/mese misurati
|
|
direttamente**, non EUR164, e **+1,8 anni a muro CONGELATO / +3,0 a muro MOBILE** —
|
|
una differenza di 1,2 anni fra due convenzioni che §33 non dichiarava.
|
|
✅ L'aritmetica dei tetti l'ho verificata sul config che gira (sez. 5a): 1,67 / 3,49 /
|
|
1,40 tornano tutti e tre al centesimo. Non e' quella il problema: e' che CLAUDE.md
|
|
porta ancora la riga «1,25-1,50x» come se fossero due opzioni vive.
|
|
DA SCRIVERE: «gradino 1,25x; k max difendibile 1,40; il 1,50x e' BOCCIATO. Guadagno
|
|
+1,8a (muro congelato) / +3,0a (mobile) — la convenzione va sempre detta.»
|
|
|
|
⚠️ BONUS 1 — «lo SPOT vale +1,55-1,66%/anno». Vale quello SOLO a $600. §52 ha camminato
|
|
entrambi i libri: il differenziale spot-perp passa da +0,72 bps a $600 a +25,66 bps a
|
|
$272k -> **-0,11%/anno alla taglia del muro**. Il lead si annulla esattamente dove
|
|
pretendeva di servire. Numero onesto: «+1,38-1,58%/anno a $600, ~0 a $272k», e sotto,
|
|
la domanda fiscale (~0,83%/anno = piu' di meta' del lead) che nessun backtest chiude.
|
|
|
|
⚠️ BONUS 2 — «PREVDAY e' il piu' forte misurato, +0,192 FULL / +0,363 HOLD». De-luckato
|
|
(§54) e' +0,100 / +0,246; la cella che GIRA fallisce il deflated-Sharpe (0,905) mentre
|
|
quella scelta al buio lo passa (0,993) ma e' un'ALTRA strategia (4h, long-flat) che
|
|
butta via la gamba short per cui PREVDAY fu promosso; e il «forward +2,04» e' su lente
|
|
ORARIA (su lente giornaliera +1,56, 63 giorni, MDE 4,7).
|
|
|
|
⚠️ BONUS 3 — «il libro 75/25 fa ShFULL 1,8». Ne fa TRE (sez. 4bis-A, misurate): 1,68
|
|
(`hourly`, la lente di tutti i muri e le traiettorie), 1,80 (`canonical`, la lente di
|
|
§41/§42/§49/§50/§54) e 1,63 (mediana d'ancora, §8/§25). Lo spread, 0,12 di Sharpe e
|
|
1,7pp di maxDD, e' PIU' GRANDE di quasi tutti gli effetti che l'ondata misura: un Δ
|
|
accostato al baseline sbagliato cambia piu' del Δ. Ogni numero di libro va scritto con
|
|
la sua lente attaccata.
|
|
|
|
⚠️ BONUS 4 — «il soffitto direzionale e' ~1,15». Nella stessa ondata §23 pubblica 1,639 e
|
|
§54 pubblica 1,621, stessa coppia, stessa lente netta-fee. «Soffitto» sta per tre cose
|
|
diverse e il registro usa la piu' bassa citandola come la piu' alta — e su quella
|
|
poggia l'argomento aritmetico di §12, che si inverte (seconda refutazione indipendente
|
|
dopo quella di §24).
|
|
""")
|
|
|
|
|
|
def main() -> None:
|
|
print("=" * 102)
|
|
print(" r0823 — CRITICO DI CHIUSURA dell'ondata 2026-08-22/23")
|
|
print("=" * 102)
|
|
print(__doc__.split("=====")[2].strip()[:1800])
|
|
if not CACHE.exists():
|
|
print(f"\n ⚠️ manca la cache {CACHE}; rigenerala con "
|
|
f"`uv run python scripts/research/r0822d_piano_vero.py --rebuild`")
|
|
sys.exit(2)
|
|
B = pd.read_parquet(CACHE)
|
|
L = sezione_repliche(B)
|
|
sezione_muro(L)
|
|
sezione_ancore()
|
|
sezione_mde()
|
|
sezione_contraddizioni()
|
|
sezione_aritmetica(L)
|
|
sezione_ledger(L)
|
|
sezione_tre()
|
|
print(f"\n[{time.time() - T0:.0f}s] fine. Sola lettura: nessun file di produzione toccato.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|