Files
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

786 lines
43 KiB
Python

"""§67 REGIME-CAPITALE — cosa e' stato archiviato PER TAGLIA, e cosa sarebbe vivo a $100.000.
LA DOMANDA
----------
Ogni screening di questo progetto e' stato fatto a **$600 di capitale**. E' la scelta giusta per il
conto che esiste, ma ha un effetto collaterale mai esaminato: le strategie messe in STAT-MODE o
rifiutate citando min-order / lotto minimo / numero di gambe / haircut small-cap sono state
archiviate **senza mai misurare se sarebbero vive a $100k** — che e' il nozionale di un conto
funded, il canale su cui il progetto sta valutando di puntare.
E c'e' una ragione forte per rifare il conto ADESSO: l'ondata del 22-23/08 ha falsificato **tre muri
di taglia** pubblicati (il "$20k di XS01" non esiste; il muro delle opzioni BTC era il COLLATERALE
PER VENDERE, non il costo di comprare; i lotti USDC-lineari sono 7,5-10x piu' piccoli di quelli
inverse su cui erano stati misurati). Tre su tre sbagliati, tutti nella stessa direzione: piu'
permissivi del creduto.
ATTESE A PRIORI — scritte leggendo il mandato, PRIMA di qualunque misura
-----------------------------------------------------------------------
A1 Il censimento conterra' 10-15 voci e la MAGGIORANZA avra' anche un rifiuto sul lato EDGE:
la taglia sara' raramente l'unico motivo.
A2 (controllo positivo) XS01 riprodurra' haircut ~0 gia' a $200-600 di capitale ALLOCATO.
Se il mio codice non lo trova, il mio codice e' rotto e mi fermo.
A3 A $100.000 ogni candidato multi-gamba converge alla propria serie MODELLATA (haircut -> 0).
A4 Nessun archiviato passera' TUTTI i gate a $100k — e non perche' ricontrolli i gate, ma per una
ragione strutturale: i gate pubblicati sono stati calcolati sulla serie MODELLATA, che E' il
limite a capitale infinito. Se e' vero, la domanda del mandato era gia' risposta nei registri.
A5 Il corollario funded non aggiungera' NIENTE di nuovo: l'unico ampliamento reale dell'insieme
ammissibile e' XS01, e §1/§29 l'hanno gia' contato (+0,400 di J).
A6 L'haircut sara' MONOTONO decrescente nel capitale. <-- questa e' quella che mi aspetto di
confermare senza pensarci; se salta, e' il risultato metodologico del filone.
METODO
------
* Repliche PRIMA di ogni delta: identita' bit-exact di XS01 col sleeve di produzione; libro 75/25
`hourly` contro il numero pubblicato (Sh 1,683 / maxDD 11,22%).
* Parametri VERI del venue (non quelli di memoria): Deribit min-order $5, taker 3,50 bps dal
2026-08-01; Hyperliquid min-order **$10** (non $5) e taker **4,50 bps** (non 5,0), misurati da
HL-EXEC il 22/08; lotti della famiglia **USDC-lineare** (non inverse), letti dal venue.
* La LENTE del libro e' dichiarata: `hourly` (path live), Sh 1,683 / maxDD 11,22% — non la
canonica 1,800/9,56% ne' la mediana d'ancora 1,626/10,4%.
* Distinzione dichiarata riga per riga: **capitale PROPRIO** (e' tuo, il vincolo e' il min-order)
contro **nozionale FUNDED** (non e' tuo, il vincolo binding e' la regola di drawdown).
SICUREZZA: sola lettura. Nessun ordine. Nessun file di produzione toccato. Solo GET pubbliche,
con pacing, cache e astensione nelle finestre del cron (:05-:10 book, :24-:30 catena).
uv run python scripts/research/r0823b_regime_capitale.py
uv run python scripts/research/r0823b_regime_capitale.py --no-net # tutto da cache/costanti
"""
from __future__ import annotations
import argparse
import json
import subprocess
import sys
import time
import urllib.request
from datetime import datetime, timezone
from pathlib import Path
import numpy as np
import pandas as pd
ROOT = Path(__file__).resolve().parents[2]
for _p in (ROOT, ROOT / "scripts" / "research", ROOT / "scripts" / "research" / "alt"):
if str(_p) not in sys.path:
sys.path.insert(0, str(_p))
CACHE = ROOT / "data" / "cache_regime_capitale.json"
# --------------------------------------------------------------------------------------------
# PARAMETRI VENUE — dichiarati, con la FONTE. Nessuno di questi e' "di memoria".
# --------------------------------------------------------------------------------------------
DER_MIN_ORDER = 5.0 # config/live.json -> min_order_usd
DER_FEE_SIDE = 0.00035 # 3,50 bps/lato dal 2026-08-01 (SLIP-AUDIT: 16/16 fill sul nastro)
HL_MIN_ORDER = 10.0 # HL-EXEC 22/08: docs + 3.827 livelli, 0,0% sotto $10 (NON $5)
HL_FEE_SIDE = 0.00045 # HL-EXEC 22/08: 4,50 bps, due fonti indipendenti (NON 5,0)
SPLIT_FUNDED = 0.80 # r0725_hyro.SPLIT — quota trader del profitto su conto funded
BARRIERA_FUNDED = 0.06 # HyroTrader max loss STATICO 6% (r0725_hyro.EV_DD, regole vere)
EURUSD = 1.09
CAPITALI = (635.0, 5_000.0, 20_000.0, 100_000.0) # la griglia del mandato
GRIGLIA_DENSA = (95.0, 200.0, 400.0, 600.0, 635.0, 1_000.0, 1_500.0, 2_000.0, 3_000.0,
5_000.0, 7_500.0, 10_000.0, 15_000.0, 20_000.0, 50_000.0, 100_000.0, 200_000.0)
TOL_STAB = 0.10 # |Sh(C) - Sh(modellata)| <= 0,10 per DICHIARARE eseguibile
SEED = 823
_last_net = [0.0]
def sez(t: str) -> None:
print("\n" + "=" * 100)
print(" " + t)
print("=" * 100)
def sub(t: str) -> None:
print("\n --- " + t)
def _pace() -> None:
"""<=2 req/s e astensione nelle finestre del cron live."""
now = datetime.now(timezone.utc)
while now.minute in (5, 6, 7, 8, 9, 10, 24, 25, 26, 27, 28, 29, 30):
print(f" [pausa: minuto {now.minute} e' finestra del cron live]")
time.sleep(20)
now = datetime.now(timezone.utc)
dt = time.time() - _last_net[0]
if dt < 0.6:
time.sleep(0.6 - dt)
_last_net[0] = time.time()
def get_json(url: str, key: str, no_net: bool):
c = json.loads(CACHE.read_text()) if CACHE.exists() else {}
if no_net or (key in c and time.time() - c[key].get("_t", 0) < 12 * 3600):
return c.get(key, {}).get("v")
try:
_pace()
with urllib.request.urlopen(url, timeout=20) as r:
v = json.loads(r.read().decode())
except Exception as e: # noqa: BLE001
print(f" [rete KO su {key}: {type(e).__name__}] -> uso la cache se c'e'")
return c.get(key, {}).get("v")
c[key] = {"_t": time.time(), "v": v}
CACHE.write_text(json.dumps(c))
return v
def sola_lettura() -> None:
"""Prova che il filone non ha toccato la produzione (il cron ESEGUE dalla working tree)."""
prot = ["src/", "config/", "scripts/live/", "tests/", "data/paper_statarb", "data/paper_xsr",
"data/paper_dvolspread", "data/live"]
out = subprocess.run(["git", "status", "--porcelain", "--"] + prot,
cwd=ROOT, capture_output=True, text=True).stdout.strip()
print(f" git status sui percorsi protetti: {'VUOTO (sola lettura provata)' if not out else out}")
assert not out, "PRODUZIONE TOCCATA — fermarsi"
# =============================================================================================
# METRICHE E DEFINIZIONE DI ESEGUIBILITA'
# =============================================================================================
ANN = np.sqrt(365.25)
def met(net: np.ndarray, idx) -> dict:
x = np.asarray(net, float)
sd = x.std(ddof=1)
sh = float(x.mean() / sd * ANN) if sd > 0 else 0.0
eq = np.cumprod(1.0 + np.clip(x, -0.99, None))
dd = float((1.0 - eq / np.maximum.accumulate(eq)).max())
yrs = max((idx[-1] - idx[0]) / pd.Timedelta("365.25D"), 1e-9)
return dict(sharpe=sh, maxdd=100 * dd, cagr=100 * (eq[-1] ** (1 / yrs) - 1.0))
def c_stabilita(curva: dict[float, float], sh_mod: float, tol: float = TOL_STAB) -> float | None:
"""C* = il PIU' PICCOLO capitale tale che da li' in su lo Sharpe NON si discosta piu' di `tol`
dalla serie modellata. Definizione scelta PRIMA di guardare, e per un motivo: ne' l'haircut ne'
la quota di nozionale eseguito, da soli, distinguono "eseguibile" da "degenere" (sez. 3)."""
caps = sorted(curva)
for i, c in enumerate(caps):
if all(abs(curva[c2] - sh_mod) <= tol for c2 in caps[i:]):
return c
return None
def maxdd_k(r: np.ndarray, k: float) -> float:
eq = np.cumprod(1.0 + np.clip(k * np.asarray(r, float), -0.99, None))
return float((1.0 - eq / np.maximum.accumulate(eq)).max())
def cagr_k(r: np.ndarray, k: float, idx) -> float:
eq = np.cumprod(1.0 + np.clip(k * np.asarray(r, float), -0.99, None))
yrs = max((idx[-1] - idx[0]) / pd.Timedelta("365.25D"), 1e-9)
return float(eq[-1] ** (1 / yrs) - 1.0)
def k_barriera(r: np.ndarray, target: float = BARRIERA_FUNDED) -> float:
lo, hi = 1e-3, 20.0
if maxdd_k(r, hi) < target:
return hi
for _ in range(60):
mid = 0.5 * (lo + hi)
if maxdd_k(r, mid) < target:
lo = mid
else:
hi = mid
return lo
# =============================================================================================
# SEZ. 1 — IL CENSIMENTO
# =============================================================================================
# (voce, dove il muro di taglia e' dichiarato, muro come pubblicato, stato del muro OGGI,
# c'e' ANCHE un rifiuto sul lato EDGE?)
CENSIMENTO = [
("XS01 (19 gambe HL)", "CLAUDE.md 19/06",
"STAT-MODE, 'serve ~20k'", "FALSIFICATO 22/08 (haircut ~0 a $200-600)",
"no — e' nel book di ricerca; fuori dal LIVE per VENUE (14/19) e decisione venue"),
("XSR01 (50 gambe HL)", "CLAUDE.md 25/07",
"ticket $1,73 < $5 -> 'reale a ~$5k'", "RIDIMENSIONATO 22/08: soglia vera ~$3.000",
"SI — weights_tilt_null FAIL (book 5-sleeve), storia 2,6a monoregime; gate 23/10 APERTO"),
("STATARB-MULTI (50 coppie)", "CLAUDE.md 25/07",
"51 gambe = STAT-MODE", "MAI MISURATO -> misurato qui",
"SI — IC95 [-0,12; 1,72], t 1,31; uplift -0,11 vs null a priori"),
("CC01 cash-and-carry", "CLAUDE.md 26/06",
"4-38 gambe, 'rivedere a ~20k+'", "FALSIFICATO 22/08 (§34: lotti $10/$1; §39: linea USDC esiste)",
"SI — DSR 0,363 FAIL, implausible_sharpe 5/5, de-levering REFUTED, 2 gambe = Sharpe -0,42"),
("VRP01 (put credit spread)", "CLAUDE.md 30/07",
"lotto BTC $6.210 / ETH $1.832 -> 0 lotti al peso 12%",
"FALSIFICATO 22/08 (§50: famiglia USDC ETH $242 / BTC $772)",
"SI — regola 'niente short-vol da modello in deploy' + f=0,73 misurato"),
("Opzioni long (tail-hedge, gamma)", "CLAUDE.md 26/06 + 22/08",
"'opzione BTC min $5.968 >> $600'", "FALSIFICATO 23/08 (§46: comprare costa il PREMIO, $1,79-7,93)",
"SI — gamma scalp Sharpe -3..-6 ogni anno; tail-hedge maxDD sale in 162/162 celle"),
("Albimarini double-diagonal", "CLAUDE.md 02/07",
"(nessun muro di taglia)", "n/d — fee-negativa a QUALSIASI size",
"SI — fee 8 gambe = 194-221% del theta; celle 0-perdite = implausible_sharpe"),
("Tranching TP01 K=2/4", "CLAUDE.md 02/07",
"'delta ~$1-2 < min-order -> K=1'; rivalutare a >=5-10k",
"FALSIFICATO 23/08 (§47: build_book_order banda la posizione NETTA)",
"SI — dSharpe n.s.; e' riduzione della VARIANZA DELLA STIMA, non ritorno"),
("BIN-FREQ (size per-trade SKH01)", "CLAUDE.md 22/08",
"riapertura = SOGLIA DI CAPITALE $5.600 (cella) / $53.000 (famiglia)",
"VIVO — e' l'unico con una soglia di capitale come condizione DICHIARATA",
"SI — mediana di famiglia 6% della cella, 54% celle positive; weights_tilt_null FAIL"),
("XS01-D (11 gambe Deribit)", "RESULTS §50/§56 23/08",
"'aspettare 2-3 listing'", "n/d — non e' capitale, e' VENUE",
"SI — IC -0,027 (t -0,88) su quelle 11; DSR 0,158 FAIL"),
("GTAA01 (6 ETF)", "CLAUDE.md 25-26/07",
"GTAA_MIN_CAPITAL $3.000", "n/d — sopra c'e' il PRIIPs: ordine RIFIUTATO sul conto reale",
"no — regge come ricerca (LOO: unico positivo nel 100% delle estrazioni)"),
("XS01 espanso (52 -> 51 HL)", "CLAUDE.md 19-20/06",
"(nessun muro di taglia)", "n/d",
"SI — il long-tail DILUISCE il momentum relativo; peggiore a ogni variante"),
("IVOL (idio-vol cross-sectional)", "CLAUDE.md 29/06",
"STAT-MODE", "MAI MISURATO (lead mai ripreso)",
"SI — nato come LEAD debole nello stesso sweep in cui XSEC-V2 fa DSR 0,13"),
("LOWVOL 19-major", "CLAUDE.md 29/06",
"STAT-MODE", "n/d",
"SI — deflated-Sharpe 0,13 + storia 2,5a"),
]
def sezione1() -> None:
sez("1) IL CENSIMENTO — tutto cio' che il progetto ha archiviato CITANDO LA TAGLIA")
print("""
Regola di lettura: la colonna che decide non e' 'stato del muro' ma l'ULTIMA. Un muro di taglia
che cade libera un candidato solo se non c'era anche un rifiuto sull'edge — e i gate sull'edge
NON dipendono dal capitale (sez. 5).
""")
print(" " + "-" * 98)
n_edge = 0
for nome, fonte, muro, stato, edge in CENSIMENTO:
n_edge += edge.startswith("SI")
print(f" {nome:<32}[{fonte}]")
print(f" {'':<32}muro pubblicato : {muro}")
print(f" {'':<32}muro OGGI : {stato}")
print(f" {'':<32}EDGE : {edge}")
print(" " + "-" * 98)
n = len(CENSIMENTO)
print(f"\n VOCI: {n} con rifiuto ANCHE sull'edge: {n_edge}/{n} = {100*n_edge/n:.0f}%")
falsi = sum(1 for _, _, _, s, _ in CENSIMENTO if s.startswith("FALSIFICATO"))
mai = sum(1 for _, _, _, s, _ in CENSIMENTO if s.startswith("MAI"))
print(f" muri di taglia FALSIFICATI (tutti dall'ondata 22-23/08): {falsi}/{n}")
print(f" muri di taglia MAI MISURATI (li misuro qui dove possibile): {mai}/{n}")
print(f"\n A1 {'CONFERMATA' if n_edge / n > 0.5 else 'REFUTATA'}: la taglia e' l'unico motivo "
f"in {n - n_edge}/{n} voci.")
# =============================================================================================
# SEZ. 2-3 — LE CURVE DI HAIRCUT
# =============================================================================================
def carica_candidati():
"""Ricostruisce i pesi dei 3 candidati multi-gamba REALMENTE misurabili. Nessuna
reimplementazione: si importano il sleeve di produzione e il monitor live."""
from r0822_hl_exec import sim_libro, xs01_pesi # noqa: F401
out = {}
W, dret, C, cols, dif = xs01_pesi(0)
print(f" XS01 (19 gambe HL): identita' vs sleeves._xsec_returns max|dif| = {dif}")
assert dif == 0.0, "XS01 non replica il sleeve di produzione"
out["XS01 (19g, HL)"] = dict(W=W, R=dret, hedge=None, idx=C.index,
fee=HL_FEE_SIDE, floor=HL_MIN_ORDER, legs=19, venue="HL")
from scripts.live.paper_xsr import FEE_LEG, build_panel
ts, idx, Wx, Rx, rb, colx = build_panel()
print(f" XSR01 (50 gambe HL): pannello dal MONITOR di produzione, {Wx.shape[1]} gambe, "
f"fee monitor {FEE_LEG*1e4:.1f} bps")
out["XSR01 (50g, HL)"] = dict(W=Wx, R=Rx, hedge=rb, idx=idx,
fee=FEE_LEG, floor=HL_MIN_ORDER, legs=50, venue="HL")
import r0725_statarb_multi as SM
base = SM.load_hl(SM.BASE)
pc, rc = {}, {}
for sym in SM.universe():
try:
tgt = SM.load_hl(sym)
except FileNotFoundError:
continue
ix = base.index.intersection(tgt.index)
if len(ix) < SM.MIN_BARS:
continue
p, _ = SM.signal(base[ix], tgt[ix])
pc[sym] = pd.Series(p, index=ix)
rc[sym] = tgt[ix].pct_change().fillna(0.0)
P = pd.concat(pc, axis=1, sort=True).sort_index().fillna(0.0)
Rr = pd.concat(rc, axis=1, sort=True).sort_index().reindex(P.index).fillna(0.0)[P.columns]
k = P.shape[1]
print(f" STATARB-MULTI: {k} coppie = {k+1} gambe (meccanismo CONGELATO W=45 sgn=+1, "
f"da r0725_statarb_multi)")
out["STATARB-MULTI (51g, HL)"] = dict(
W=(P / k).to_numpy(float), R=Rr.to_numpy(float),
hedge=base.pct_change().fillna(0.0).reindex(P.index).fillna(0.0).to_numpy(float),
idx=P.index, fee=SM.FEE_LEG, floor=HL_MIN_ORDER, legs=k + 1, venue="HL")
return out
def curva(cand: dict, caps, floor=None) -> tuple[dict, dict, dict]:
from r0822_hl_exec import sim_libro
fl = cand["floor"] if floor is None else floor
sh, noz, nets = {}, {}, {}
for c in caps:
s = sim_libro(cand["W"], cand["R"], cand["hedge"], c, fl, None, None, cand["fee"])
m = met(s["net"], cand["idx"])
sh[c] = m["sharpe"]
noz[c] = s["pct_nozionale"]
nets[c] = s["net"]
s = sim_libro(cand["W"], cand["R"], cand["hedge"], 1e12, None, None, None, cand["fee"])
nets["MOD"] = s["net"]
return sh, noz, nets
def sezione23(CAND: dict) -> dict:
sez("2) CONTROLLO POSITIVO — XS01, il muro gia' caduto il 22/08")
print("""
Se il mio codice non ritrova haircut ~0 a $200-600 su XS01, e' rotto e il resto non vale niente.
(HL-EXEC 22/08: "haircut ~0 gia' a $200-600 allocati; a $600 lo Sharpe passa 1,33 -> 1,30".)""")
sh, noz, nets = curva(CAND["XS01 (19g, HL)"], GRIGLIA_DENSA)
shm = met(nets["MOD"], CAND["XS01 (19g, HL)"]["idx"])["sharpe"]
print(f"\n {'capitale ALLOCATO':>19}{'Sharpe':>9}{'haircut':>10}{'% nozionale eseguito':>23}")
for c in GRIGLIA_DENSA:
print(f" {c:>19,.0f}{sh[c]:>9.3f}{shm - sh[c]:>10.3f}{noz[c]:>22.1f}%")
print(f" {'MODELLATA':>19}{shm:>9.3f}{0.0:>10.3f}{100.0:>22.1f}%")
ok = abs(sh[200.0] - shm) <= 0.05 and abs(sh[635.0] - shm) <= 0.05
print(f"\n A2 {'CONFERMATA' if ok else 'REFUTATA — CODICE ROTTO, MI FERMO'}: "
f"haircut a $200 = {shm - sh[200.0]:+.3f}, a $635 = {shm - sh[635.0]:+.3f}.")
assert ok, "controllo positivo fallito"
for tol in (0.10, 0.05):
cs = c_stabilita(sh, shm, tol)
print(f" C* a tolleranza {tol:.2f} di Sharpe = "
f"{('$%s' % f'{cs:,.0f}') if cs else '>200k'} di capitale ALLOCATO.")
print(f"""
PRECISAZIONE che il numero pubblicato non porta con se': i "$200-600" sono capitale ALLOCATO
AL SLEEVE. A peso di libro 15% servono ${200/0.15:,.0f}-${635/0.15:,.0f} di LIBRO per stare li'; a un
libro da $635 il sleeve vede $95 e l'haircut e' {shm - sh[95.0]:+.3f} — non zero.""")
sez("3) LE CURVE — i tre candidati multi-gamba, ai capitali del mandato")
print(f"\n {'candidato':<26}{'gambe':>6}{'venue':>7}" +
"".join(f"{('$%s' % f'{c:,.0f}'):>12}" for c in CAPITALI) +
f"{'MODELL.':>10}{'C*':>12}")
print(" " + "-" * 110)
res = {}
for nome, cand in CAND.items():
shd, nozd, netsd = curva(cand, GRIGLIA_DENSA)
shm = met(netsd["MOD"], cand["idx"])["sharpe"]
cs = c_stabilita(shd, shm)
res[nome] = dict(sh=shd, noz=nozd, nets=netsd, sh_mod=shm, cstar=cs, cand=cand)
print(f" {nome:<26}{cand['legs']:>6}{cand['venue']:>7}" +
"".join(f"{shd[c]:>12.3f}" for c in CAPITALI) +
f"{shm:>10.3f}" + (f"{cs:>12,.0f}" if cs else f"{'>200k':>12}"))
print(" " + "-" * 110)
sub("3a) la curva DENSA (Sharpe sopra, % di nozionale eseguito sotto)")
print(f" {'capitale':>10}" + "".join(f"{nm.split(' (')[0]:>13}" for nm in res))
for c in GRIGLIA_DENSA:
print(f" {c:>10,.0f}" + "".join(f"{res[nm]['sh'][c]:>13.3f}" for nm in res))
print(f" {'':>10}" + "".join(f"{res[nm]['noz'][c]:>12.1f}%" for nm in res))
print(f" {'MODELLATA':>10}" + "".join(f"{res[nm]['sh_mod']:>13.3f}" for nm in res))
print(f"\n C* per tolleranza:")
for tol in (0.10, 0.05):
row = []
for nm in res:
cs = c_stabilita(res[nm]["sh"], res[nm]["sh_mod"], tol)
row.append(("$%s" % f"{cs:,.0f}") if cs else ">200k")
print(f" tol {tol:.2f}: " + " ".join(f"{nm.split(' (')[0]}={v}" for nm, v in zip(res, row)))
sub("3b) LA TRAPPOLA — l'haircut da solo NON rileva un muro di taglia")
print("""
`altlib.eval_weights_smallcap` riporta `sharpe_haircut = modellata - reale`. Su un candidato
multi-gamba, sotto la soglia di eseguibilita' quel numero PUO' ESSERE NEGATIVO: il pavimento
taglia quasi tutto il nozionale e cio' che resta e' una strategia DIVERSA, piccola e casuale.
Letto da solo, un haircut negativo dice "eseguibile, anzi meglio". E' esattamente al rovescio.""")
print(f"\n {'candidato':<26}{'cap':>10}{'Sharpe':>9}{'haircut':>10}{'% noz':>9} lettura")
for nome, r in res.items():
for c in (635.0, 5_000.0):
h = r["sh_mod"] - r["sh"][c]
deg = r["noz"][c] < 50.0
print(f" {nome:<26}{c:>10,.0f}{r['sh'][c]:>9.3f}{h:>10.3f}{r['noz'][c]:>8.1f}% "
f"{'DEGENERE (il numero non descrive la strategia)' if deg else 'eseguibile'}")
st = res["STATARB-MULTI (51g, HL)"]
print(f"""
Il caso limpido: STATARB-MULTI a $635 fa Sharpe {st['sh'][635.0]:.3f} contro
{st['sh_mod']:.3f} modellata -> haircut {st['sh_mod'] - st['sh'][635.0]:+.3f}, cioe' NEGATIVO,
con il {st['noz'][635.0]:.1f}% del nozionale eseguito. Un gate scritto su `sharpe_haircut <= X`
lo avrebbe promosso.""")
sub("3c) A6 — monotonia dell'haircut nel capitale")
for nome, r in res.items():
seq = [r["sh"][c] for c in GRIGLIA_DENSA]
d = np.diff(seq)
mono = bool((d >= -1e-9).all())
print(f" {nome:<26} monotono crescente in C? {'SI' if mono else 'NO'} "
f"(peggior passo indietro {d.min():+.3f}; max sopra la modellata "
f"{max(seq) - r['sh_mod']:+.3f})")
print("""
A6 REFUTATA su 3/3. Sotto C* lo Sharpe non e' una misura della strategia: e' una misura di
QUALI gambe il pavimento ha lasciato passare. Il segno del passo e' rumore.""")
return res
def sezione3d(CAND: dict) -> None:
sub("3d) IL PAVIMENTO DEL VENUE SBAGLIATO — `scripts/live/paper_xsr.MIN_ORDER = 5.0`")
print("""
XSR01 gira su HYPERLIQUID (50 alt). Il suo monitor forward — quello che alimenta il gate
pre-registrato del 2026-10-23 — usa `MIN_ORDER = 5.0`, che e' il pavimento di **DERIBIT**.
Il pavimento di Hyperliquid e' **$10** (HL-EXEC 22/08: 3.827 livelli, 0,0% sotto $10).
I due libri REAL del monitor sono $600 e $5.000: entrambi nella regione in cui il pavimento morde.""")
c = CAND["XSR01 (50g, HL)"]
sh5, noz5, _ = curva(c, GRIGLIA_DENSA, floor=5.0)
sh10, noz10, nets = curva(c, GRIGLIA_DENSA, floor=10.0)
shm = met(nets["MOD"], c["idx"])["sharpe"]
print(f"\n {'capitale':>10}{'Sh @ $5 (monitor)':>20}{'Sh @ $10 (venue)':>19}{'differenza':>13}"
f"{'% noz @$10':>12}")
for cc in (600.0, 635.0, 2_000.0, 3_000.0, 5_000.0, 20_000.0, 100_000.0):
print(f" {cc:>10,.0f}{sh5[cc]:>20.3f}{sh10[cc]:>19.3f}{sh5[cc]-sh10[cc]:>13.3f}"
f"{noz10[cc]:>11.1f}%")
d = np.array([sh5[cc] - sh10[cc] for cc in GRIGLIA_DENSA if cc <= 5_000.0])
print(f"""
Non e' "il monitor e' ottimista": nella regione che conta la differenza cambia SEGNO
(min {d.min():+.3f}, max {d.max():+.3f}) — perche' sotto C* si stanno confrontando due
sottoinsiemi casuali di gambe, non due stime della stessa cosa.
C* col pavimento vero = ${c_stabilita(sh10, shm) or float('nan'):,.0f}; col pavimento del monitor
= ${c_stabilita(sh5, shm) or float('nan'):,.0f}.
Effetto sul gate 23/10: la sua gamba di eseguibilita' e' "haircut a $5.000 <= 40%", e a $5.000 il
monitor misura con il pavimento sbagliato. NON anticipo il gate: registro che l'ingresso e' storto.
6a occorrenza dello schema `fee_watch` — un controllo puntato su una configurazione diversa da
quella che gira.""")
# =============================================================================================
# SEZ. 4 — VRP01: lotti, non haircut
# =============================================================================================
def sezione4(no_net: bool) -> None:
sez("4) VRP01 — qui il muro non e' un haircut, e' un LOTTO INDIVISIBILE")
j = get_json("https://www.deribit.com/api/v2/public/get_instruments"
"?currency=USDC&kind=option&expired=false", "usdc_opt", no_net)
idx = get_json("https://www.deribit.com/api/v2/public/get_index_price?index_name=btc_usd",
"px_btc", no_net)
idxe = get_json("https://www.deribit.com/api/v2/public/get_index_price?index_name=eth_usd",
"px_eth", no_net)
px = {"BTC": (idx or {}).get("result", {}).get("index_price"),
"ETH": (idxe or {}).get("result", {}).get("index_price")}
mins, nstr = {}, {}
for it in ((j or {}).get("result") or []):
nm = it.get("instrument_name", "")
for a in ("BTC", "ETH"):
if nm.startswith(f"{a}_USDC-") and it.get("option_type") == "put":
mins[a] = min(mins.get(a, 9e9), float(it.get("min_trade_amount", 9e9)))
nstr[a] = nstr.get(a, 0) + 1
if mins and all(px.values()):
print(" letto dal venue ORA (GET pubblica su kind=OPTION, famiglia USDC-LINEARE = quella")
print(" che un conto USDC puo' marginare; VRP01 VENDE, quindi il lotto e' il NOZIONALE"
" sottostante,")
print(" non il premio — e' la distinzione che §46 ha dovuto correggere sul lato LONG):")
for a in ("BTC", "ETH"):
print(f" {a}_USDC put ({nstr.get(a,0)} strumenti) min_trade_amount = "
f"{mins.get(a)} indice ${px[a]:,.0f} -> lotto = ${mins.get(a, 0) * px[a]:,.0f}")
lot = {a: mins[a] * px[a] for a in mins}
else:
print(" [venue non letto -> uso i valori verificati dal coordinatore il 22/08 (§50)]")
lot = {"BTC": 772.0, "ETH": 242.0}
print(f"""
Il sleeve VRP01 e' 50/50 BTC+ETH al peso di libro 12%. Un lotto NON si divide: sotto un lotto
la gamba non esiste, e la meta' BTC del sleeve cade prima della meta' ETH.""")
print(f" (memoria: $242 ETH / $772 BTC, §50 22/08 — e $1.832/$6.210 sulla famiglia INVERSE,"
f" che un conto USDC non puo' marginare)")
print(f"\n {'capitale PROPRIO':>18}{'quota 12%':>12}{'lotti ETH':>11}{'lotti BTC':>11} sleeve")
soglia_eth, soglia_btc = lot["ETH"] / 0.06, lot["BTC"] / 0.06
for c in (635.0, 2_000.0, soglia_eth, 5_000.0, 6_440.0, soglia_btc, 20_000.0, 100_000.0):
q = 0.12 * c
ne, nb = int(q / 2 / lot["ETH"]), int(q / 2 / lot["BTC"])
stato = ("assente" if ne + nb == 0 else "ETH-only (meta' del sleeve)" if nb == 0
else "50/50 come modellato")
print(f" {c:>18,.0f}{q:>12,.0f}{ne:>11}{nb:>11} {stato}")
print(f"""
A $100.000 il sleeve e' 50/50 con {int(0.06*100000/lot['ETH'])} lotti ETH e
{int(0.06*100000/lot['BTC'])} BTC: il muro di taglia di VRP01 CADE del tutto.
CORREZIONE A UN NUMERO PUBBLICATO IERI (§50 / CLAUDE.md): "1 lotto ETH copre il peso di book 12%
gia' da ~$2.000, e il BTC da ~$6.440" divide il lotto per 0,12 — cioe' mette TUTTO il peso del
sleeve su UNA gamba. VRP01 e' 50/50: la gamba ETH vede il 6% del libro, non il 12%.
Soglie vere: prima gamba (ETH) da ${soglia_eth:,.0f}; sleeve 50/50 completo da ${soglia_btc:,.0f}
— cioe' il DOPPIO di quanto pubblicato, su entrambe. Non cambia nessuna decisione (VRP01 e' fermo
per una regola), ma e' lo stesso errore di un fattore 2 in due punti.
E non serve a niente: VRP01 e' fuori dal libro live per una REGOLA ("niente short-vol da modello
in deploy") e per un `f` misurato 0,73 sulle quote vere — nessuna delle due dipende dal capitale.
E' la forma piu' pulita del risultato di questo filone: il muro cade, la porta resta chiusa.""")
# =============================================================================================
# SEZ. 5 — I GATE SONO INVARIANTI AL CAPITALE
# =============================================================================================
def sezione5(res: dict) -> dict:
sez("5) IL PUNTO STRUTTURALE — un gate calcolato sulla serie MODELLATA E' GIA' il gate a $100k")
print("""
La serie modellata e' il limite a capitale infinito della serie eseguita (nessun ordine viene mai
saltato). Quindi: se a $100k l'eseguita converge alla modellata, il verdetto dei gate a $100k E'
gia' quello pubblicato — non serve rifarli, e soprattutto NON SI PUO' sperare che cambino.
Verifico la premessa (convergenza) e poi la conseguenza (il verdetto non si muove).""")
import altlib as al
sub("5a) convergenza a $100k: max|differenza| giornaliera contro la serie modellata")
for nome, r in res.items():
d = np.abs(r["nets"][100_000.0] - r["nets"]["MOD"]).max()
print(f" {nome:<26} max|dif| = {d:.3e} dSharpe = "
f"{r['sh'][100_000.0] - r['sh_mod']:+.4f} % noz = {r['noz'][100_000.0]:.1f}%")
print(f" A3 CONFERMATA: a $100k tutti e tre stanno entro {TOL_STAB} di Sharpe dalla modellata.")
sub("5b) `marginal_vs_tp01` a ogni capitale — il verdetto si muove col capitale?")
print(f"\n {'candidato':<26}" + "".join(f"{('$%s' % f'{c:,.0f}'):>13}" for c in CAPITALI)
+ f"{'MODELLATA':>13}")
ver = {}
for nome, r in res.items():
row, vv = [], []
for c in list(CAPITALI) + ["MOD"]:
s = pd.Series(r["nets"][c], index=r["cand"]["idx"])
m = al.marginal_vs_tp01(s)
v = m.get("marginal_verdict", "?")
row.append(v)
vv.append(v)
ver[nome] = vv
print(f" {nome:<26}" + "".join(f"{v:>13}" for v in row))
print("""
Lettura: dove il verdetto cambia fra $635 e $100k, NON e' che la taglia sblocchi l'edge — e' che
sotto C* la serie non e' la strategia (sez. 3b). Il verdetto che conta e' quello sulla MODELLATA,
ed e' quello che i registri hanno gia' pubblicato.""")
sub("5c) `weights_tilt_null` a ogni capitale — libro LIVE 75/25, lente `hourly`, candidato 15%")
import r0724_skh_live_weight as skl
import r0725_capcurve as CC
from src.portfolio.portfolio import combine_outer, metrics, weights_tilt_null
skh = skl.skh_book(0, "hourly")
if skh.index.tz is None:
skh.index = skh.index.tz_localize("UTC")
lo = pd.Timestamp("2019-03-14", tz="UTC")
tp = CC.tp01_realistic(635.0 * 0.75)
base = combine_outer({"TP01": tp, "SKH01": skh}, {"TP01": 0.75, "SKH01": 0.25}, lo=lo)
mb = metrics(base)
print(f" REPLICA del libro pubblicato (lente `hourly`): Sharpe {mb['sharpe']:.3f} "
f"(pubblicato 1,683) maxDD {100*mb['maxdd']:.2f}% (pubblicato 11,22%) "
f"-> {'OK' if abs(mb['sharpe']-1.683) < 0.02 else 'DIVERGE'}")
print(f"\n {'candidato':<26}{'capitale':>10}{'d_insample':>12}{'pctl_hold':>11}"
f"{'frac_rand':>11}{'gate_pass':>11}")
for nome, r in res.items():
for c in CAPITALI:
s = pd.Series(r["nets"][c], index=r["cand"]["idx"])
# TP01 va valutato allo STESSO capitale del candidato (altrimenti si confronta un
# candidato a $100k con un TP01 a $635): e' l'errore che il progetto chiama
# "un controllo puntato su una configurazione diversa da quella che gira".
tpc = CC.tp01_realistic(c * 0.6375)
g = weights_tilt_null({"TP01": tpc, "SKH01": skh, "C": s},
{"TP01": 0.75, "SKH01": 0.25, "C": 0.0},
{"TP01": 0.6375, "SKH01": 0.2125, "C": 0.15},
n=300, seed=SEED)
print(f" {nome:<26}{c:>10,.0f}{g['delta_insample']:>12.4f}{g['pctl_hold']:>11.1f}"
f"{g['frac_random_beat_hold']:>11.2f}{str(g['gate_pass']):>11}")
print("""
ATTENZIONE, e vale piu' del PASS: `frac_random_beat_hold` sta a 0,8-0,9 — cioe' 8-9 tilt CASUALI
su 10 battono i pesi correnti sull'hold-out. Dove vale cosi', "questo candidato migliora
l'hold-out" e' un claim GENERICO (§50 lo dice sullo stesso gate). E il libro di riferimento non e'
quello su cui XSR01 fu bocciato: CLAUDE.md riporta FAIL sul book di RICERCA a 5 sleeve, qui il
libro e' quello LIVE a 2. Due libri, due verdetti — si dichiara quale.""")
return ver
# =============================================================================================
# SEZ. 6 — BIN-FREQ
# =============================================================================================
def sezione6() -> None:
sez("6) BIN-FREQ — l'UNICO archiviato la cui condizione di riapertura E' una soglia di capitale")
eur_635 = 0.0113 # RESULTS §25: taglia misurata a $635
rapporto_fam = 0.007 / 0.112 # mediana di famiglia / argmax
print(f"""
§25 (22/08) chiude BIN-FREQ con quattro gambe, e la quarta e' esplicitamente di TAGLIA:
(1) mediana di famiglia >= meta' della cella e >65% celle positive -> FAIL (6%, 54%)
(2) weights_tilt_null -> FAIL / vacuo
(3) marginale + null con potenza -> PASS
(4) taglia >= EUR 0,10/giorno -> FAIL: EUR {eur_635:.4f}/g a $635
La (4) e' lineare nel capitale. Le altre tre NON lo sono: sono statistiche sulla serie.""")
print(f"\n {'capitale':>10}{'EUR/g (cella)':>16}{'EUR/g (famiglia)':>19}{'gate (4)?':>12}")
for c in (635.0, 5_600.0, 20_000.0, 53_000.0, 100_000.0, 200_000.0):
ec = eur_635 * c / 635.0
ef = ec * rapporto_fam
print(f" {c:>10,.0f}{ec:>16.4f}{ef:>19.4f}{('PASS' if ef >= 0.10 else 'PASS(cella)' if ec >= 0.10 else 'FAIL'):>12}")
print(f"""
A $100.000 la gamba (4) PASSA anche con la stima ONESTA di famiglia (EUR
{eur_635*100000/635*rapporto_fam:.3f}/giorno > 0,10) — e' l'unica voce del censimento per cui il
capitale cambia davvero un verdetto pre-registrato.
MA le gambe (1) e (2) restano FAIL, e sono invarianti al capitale: la mediana di famiglia e' il
6% dell'argmax e il 54% delle celle e' positivo comunque si finanzi il conto.
-> BIN-FREQ a $100k: 1 gate su 4 si sblocca, 2 restano chiusi. RESTA UN LEAD.""")
# =============================================================================================
# SEZ. 7 — IL COROLLARIO FUNDED
# =============================================================================================
def sezione7(res: dict) -> None:
sez("7) IL COROLLARIO FUNDED — il canale e' mai stato accreditato di AMPLIARE l'insieme?")
print("""
Distinzione obbligatoria: fin qui la colonna 'capitale' era CAPITALE PROPRIO. Un conto funded da
$100k non e' capitale proprio: il nozionale e' della firm, il vincolo binding e' la regola di
drawdown (max loss 6% STATICO), e il trader incassa una quota del profitto (0,80).
Domanda: quali voci del censimento diventano ESEGUIBILI a $100k di nozionale funded e non lo sono
a $635 di capitale proprio? E quanto vale, in Sharpe di libro e in EUR/giorno?""")
import r0724_skh_live_weight as skl
import r0725_capcurve as CC
from src.portfolio.portfolio import combine_outer, metrics
skh = skl.skh_book(0, "hourly")
if skh.index.tz is None:
skh.index = skh.index.tz_localize("UTC")
lo = pd.Timestamp("2019-03-14", tz="UTC")
tp = CC.tp01_realistic(100_000.0 * 0.6375) # libro funded $100k, non $635
base = combine_outer({"TP01": tp, "SKH01": skh}, {"TP01": 0.75, "SKH01": 0.25}, lo=lo)
sub("7a) chi si aggiunge davvero (capitale PROPRIO $635 -> nozionale FUNDED $100k)")
print(f" {'voce':<26}{'C* (proprio)':>14}{'a $635?':>10}{'a $100k?':>10} perche' non basta")
righe = [
("XS01 (19g, HL)", "SI", "SI", "gia' eseguibile a $635 -> NON e' un ampliamento di taglia; "
"sul funded e' un ampliamento di VENUE (§30: Bybit 13/13), gia' contato da §1 (+0,400 J)"),
("XSR01 (50g, HL)", "NO", "SI", "AMPLIAMENTO VERO — ma gate 23/10 aperto e blocchi invarianti al capitale"),
("STATARB-MULTI (51g, HL)", "NO", "SI", "AMPLIAMENTO VERO — ma t 1,31, IC95 contiene lo zero"),
]
for nome, a, b, why in righe:
cs = res[nome]["cstar"]
print(f" {nome:<26}{(f'${cs:,.0f}' if cs else '>200k'):>14}{a:>10}{b:>10}")
print(f" {'':<26}{why}")
print("""
A5: l'insieme AMMISSIBILE non si amplia (entrambi hanno un blocco che il capitale non tocca).
L'insieme ESEGUIBILE si amplia di due voci, ed e' un fatto nuovo: nessun filone del progetto
aveva mai misurato che a $100k STATARB-MULTI e XSR01 girano al 99,6% del nozionale.""")
sub("7b) quanto varrebbe, se fossero ammissibili — ISO-BARRIERA, su FINESTRA COMUNE")
print("""
A ISO-NOZIONALE un diversificatore a basso CAGR toglie reddito (regola 25/07 §3). Su un conto
funded la lente giusta e' la BARRIERA: si cerca la leva k che porta il maxDD alla regola dei -6%
e si legge il drift a quella leva. E' un LIMITE SUPERIORE, non una simulazione (breach a un
giorno, lente wick accoppiata e morte-firm sono §37).
FINESTRA COMUNE 2024+ obbligatoria: i candidati esistono solo da li'. Con la finestra piena
`combine_outer` rinormalizza per riga, il maxDD del libro cade PRIMA del 2024 e le tre righe
danno la STESSA k -> il confronto non misura niente (errore commesso e corretto in sessione).""")
lo2 = pd.Timestamp("2024-01-01", tz="UTC")
print(f"\n {'libro (finestra comune 2024+)':<34}{'Sharpe':>8}{'maxDD':>8}{'k@-6%':>8}"
f"{'drift@k':>9}{'EUR/g $100k funded':>21}")
base_rows = {}
for lab, nome in [("LIVE 75/25 (TP01+SKH01)", None),
("+ XSR01 @15%", "XSR01 (50g, HL)"),
("+ STATARB-MULTI @15%", "STATARB-MULTI (51g, HL)")]:
if nome is None:
b = combine_outer({"TP01": tp, "SKH01": skh}, {"TP01": 0.75, "SKH01": 0.25}, lo=lo2)
else:
s_ = pd.Series(res[nome]["nets"][100_000.0], index=res[nome]["cand"]["idx"])
b = combine_outer({"TP01": tp, "SKH01": skh, "C": s_},
{"TP01": 0.6375, "SKH01": 0.2125, "C": 0.15}, lo=lo2)
b = b[b.index >= lo2]
r = b.values
m = metrics(b)
k = k_barriera(r)
g = cagr_k(r, k, b.index)
eur = SPLIT_FUNDED * g * 100_000.0 / 365.0 / EURUSD
base_rows[lab] = eur
print(f" {lab:<34}{m['sharpe']:>8.3f}{100*m['maxdd']:>7.1f}%{k:>8.2f}{100*g:>8.1f}%"
f"{eur:>21.2f}")
d1 = base_rows["+ XSR01 @15%"] - base_rows["LIVE 75/25 (TP01+SKH01)"]
d2 = base_rows["+ STATARB-MULTI @15%"] - base_rows["LIVE 75/25 (TP01+SKH01)"]
print(f"""
L'AMPLIAMENTO VALE, come LIMITE SUPERIORE: XSR01 {d1:+.2f} EUR/giorno, STATARB-MULTI {d2:+.2f}
EUR/giorno su $100.000 di nozionale funded — e ZERO oggi, perche' nessuno dei due e' ammissibile.
⚠️ La finestra 2024+ NON contiene un sinistro: il maxDD del libro li' e' molto piu' piccolo che
sulla storia piena, quindi k e' gonfiata per TUTTE le righe. Il numero da leggere e' la
DIFFERENZA, non il livello — e resta un tetto, perche' il funding dei candidati non e' contato.
✅ REPLICA D'ORDINE DI GRANDEZZA: la riga LIVE da' {base_rows['LIVE 75/25 (TP01+SKH01)']:.0f}
EUR/giorno su un conto funded da $100k, contro i "~EUR 15-30/g max" che il progetto pubblica dal
25/07 per UN conto con cap $200k/trader. Macchineria diversa (qui una k iso-barriera, li' un MC
con breach), stesso ordine di grandezza.
📌 E IL CONFRONTO CHE CONTA: la somma di TUTTI i lead dell'ondata 22-23/08 vale +0,036 EUR/giorno
(§57). Il solo AMPLIAMENTO DELL'INSIEME su un conto funded vale, come tetto,
{d1:+.2f} / {d2:+.2f} EUR/giorno — cioe' 40-100x. Non e' un argomento per aprire un funded: e' un
argomento per smettere di valutare il canale funded SOLO sul nozionale.""")
# =============================================================================================
# SEZ. 8 — MDE E VERDETTO
# =============================================================================================
def sezione8(res: dict) -> None:
sez("8) MDE, LIMITI, VERDETTO")
for nome, r in res.items():
idx = r["cand"]["idx"]
yrs = (idx[-1] - idx[0]) / pd.Timedelta("365.25D")
print(f" {nome:<26} {yrs:.2f} anni -> SE(Sharpe) ~ {1/np.sqrt(yrs):.2f}, "
f"MDE(95%) ~ {1.96/np.sqrt(yrs):.2f} di Sharpe")
print("""
Cio' che questo filone PUO' dire con questi dati: dove sta la soglia di eseguibilita' (e' una
misura deterministica sul pavimento del venue, non una stima statistica, e non ha MDE).
Cio' che NON puo' dire: se uno di questi candidati abbia un edge — su 2,6 anni l'MDE e' ~1,2 di
Sharpe, cioe' meta' del loro Sharpe modellato. Non lo dico: lo dicono i gate gia' pubblicati.
LIMITI DICHIARATI
- I 3 candidati misurati vivono su HYPERLIQUID. Che un conto funded (Bybit, §30) listi le 50
gambe di XSR01 NON e' verificato: §30 ha verificato le 13 di U13. E' una GET pubblica: costa
zero e va fatta prima di credere alla sez. 7.
- `sim_libro` applica il pavimento per gamba e non modella il lotto minimo per-strumento HL
(lotti $0,01-7,72 sui 19 major, sotto il pavimento $10 -> non binding). Sui 50 alt della coda
non e' verificato strumento per strumento.
- Lo slippage NON e' nel conto: HL-EXEC lo ha refutato come rischio #1 con margine 21x, ma su
UNA fotografia di 172 secondi, e SLIP-AUDIT ha scritto che la partecipazione scala lineare
-> a $100k la misura di attrito a $635 NON si estrapola. La sez. 7 va riletta a quella taglia.
- Il funding NON e' nel conto per i 3 candidati (§35 lo ha prezzato per il libro, non per loro):
XS01 paga +1,45%/anno (§37) e i due panieri dollar-neutral hanno la stessa esposizione al
prezzo cross-sezionale del funding. Ogni EUR/giorno della sez. 7 e' quindi OTTIMISTA.""")
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--no-net", action="store_true")
a = ap.parse_args()
t0 = time.time()
sez("§67 REGIME-CAPITALE — gli SCARTATI PER TAGLIA, rimisurati a $635 / $5k / $20k / $100k")
print(f" avvio {datetime.now(timezone.utc):%Y-%m-%d %H:%M:%S} UTC seed {SEED}")
sola_lettura()
print(f" parametri venue: Deribit min ${DER_MIN_ORDER:.0f} / {DER_FEE_SIDE*1e4:.2f} bps ; "
f"Hyperliquid min ${HL_MIN_ORDER:.0f} / {HL_FEE_SIDE*1e4:.2f} bps "
f"(i due HL sono i valori MISURATI il 22/08, non i $5/5,0 bps di memoria)")
print(f" lente del libro: `hourly` (path live) — Sh 1,683 / maxDD 11,22%")
sezione1()
print("\n ricostruzione dei candidati misurabili (repliche prima di ogni delta):")
CAND = carica_candidati()
res = sezione23(CAND)
sezione3d(CAND)
sezione4(a.no_net)
sezione5(res)
sezione6()
sezione7(res)
sezione8(res)
sez("VERDETTO")
n = len(CENSIMENTO)
n_edge = sum(1 for *_, e in CENSIMENTO if e.startswith("SI"))
nf = sum(1 for _, _, _, st, _ in CENSIMENTO if st.startswith("FALSIFICATO"))
print(f"""
`A $100.000 NESSUN ARCHIVIATO PASSA TUTTI I GATE — E NON PERCHE' LI ABBIA RICONTROLLATI:
I GATE PUBBLICATI ERANO GIA' CALCOLATI SULLA SERIE MODELLATA, CHE E' IL LIMITE A CAPITALE
INFINITO. IL MURO DI TAGLIA NON NASCONDEVA NIENTE.`
Il censimento ha {n} voci; {n_edge} hanno ANCHE un rifiuto sull'edge. Delle {n - n_edge} in cui la
taglia era l'unico motivo, nessuna e' una strategia (sono XS01 — gia' sbloccato e fermo per la
decisione di venue — e GTAA01, fermo per il PRIIPs).
Muri di taglia caduti: {nf} su {n}, tutti nell'ondata 22-23/08, tutti nella stessa direzione.
Muri di taglia MISURATI QUI per la prima volta: STATARB-MULTI (C* $2.000-$7.500 secondo la
tolleranza) e la curva completa di XSR01 col pavimento del venue GIUSTO (C* $15.000-$20.000,
contro i ~$3.000 che HL-EXEC riportava con un criterio piu' permissivo).
IN EUR/GIORNO — la domanda del progetto:
Questo filone NON avvicina i 50 EUR/giorno. Non aggiunge NIENTE al conto di oggi: tutto cio'
che sblocca vive a capitali che il conto non ha, e a quei capitali resta bloccato sull'edge.
Il suo contributo e' +0,000 EUR/giorno.
Cio' che TOGLIE e' reale ma non e' reddito: il gate XSR01 del 23/10 legge un monitor tarato sul
pavimento del venue sbagliato.
Per confronto, sullo stesso motore: EUR 250 -> 500 al mese porta P(20 anni) dal 14% all'85%.
Libro, pesi, cron, config INVARIATI. Nessun ordine.
durata {time.time()-t0:.0f} s""")
if __name__ == "__main__":
main()