From e460caf667034d1e1300138706570b19cf445a0f Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Sat, 22 Aug 2026 21:32:25 +0000 Subject: [PATCH] =?UTF-8?q?research(wave-0822):=20PROP-RECAL=20=E2=80=94?= =?UTF-8?q?=20il=2042%=20del=20numero=20funded=20stava=20in=206=20gambe=20?= =?UTF-8?q?che=20fuori=20campione=20non=20esistono;=20P(50/g)=2042%=20->?= =?UTF-8?q?=207,8%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/research/RESULTS-0822.md | 85 +++++++++ scripts/research/r0822b_prop_recal.py | 260 +++++++++++++++++++++++++- 2 files changed, 342 insertions(+), 3 deletions(-) diff --git a/docs/research/RESULTS-0822.md b/docs/research/RESULTS-0822.md index 2fa4a62..2aab3f3 100644 --- a/docs/research/RESULTS-0822.md +++ b/docs/research/RESULTS-0822.md @@ -694,6 +694,7 @@ stessi hanno nominato senza poterli eseguire**. Stesso contratto di consegna, st |---|---|---|---| | 21 | XS01-OOS | il vantaggio del PROP-ALLOC poggia sul drift di XS01 misurato sulla sua finestra di scoperta: regge fuori? | **LEAD** — regge, ed e' PIU' GRANDE fuori | | 28 | DEPEG | il falsificatore che l'autore di 21 ha nominato contro se stesso: il depeg USDT contamina il ranking? | **SOPRAVVIVE** — il venue sposta 0,01 di Sharpe | +| 29 | PROP-RECAL | J rifatto con XS01 dalla storia lunga: il canale funded si apre? | **LEAD ridimensionato ~5x** — 42% → **7,8%** | | 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' | **3 correzioni all'ondata**, 1 regola mia ritirata | @@ -1229,3 +1230,87 @@ cambia (con SE(Sharpe)≈1,4 su 6 mesi nessun forward misura 0,07). €0,10/gior alla stima della cella e **~$53.000** a quella onesta di famiglia → si rivaluta alla revisione dei **$20k** gia' in calendario, **e solo se la cella e' giustificata da un MECCANISMO** invece che dall'argmax di una griglia. + +--- + +## 29 — PROP-RECAL (J rifatto con XS01 dalla storia lunga) — **la decisione** + +`scripts/research/r0822b_prop_recal.py` (891 righe, 309 s, nessuna rete). **5.212 valutazioni MC** +contate al rialzo; risoluzione dichiarata **±0,010 sui livelli di J, ±0,007 sulle differenze +appaiate**. ✅ **Riproduzione ESATTA cifra per cifra** dei numeri di PROP-ALLOC (J 0,738/0,721/0,335; +P(pass) 82,2/77,3/38,6%; scala 39,28 €/g e 41,7%) piu' **tre controlli bit-exact a 0,0**. + +📌 **IL RISULTATO: J non regge alla taglia pubblicata, e il colpevole NON e' la finestra.** +Decomposizione a **un grado di liberta' per volta**, stesso pannello: + +| passo | J | Δ | +|---|---|---| +| XS01 = HL 19 gambe, finestra di scoperta (**il pubblicato**) | 0,739 | — | +| → Binance 19 gambe, **date allineate** (VENUE) | 0,732 | **−0,006** | +| → Binance **13 gambe** (UNIVERSO) | 0,426 | **−0,307** | +| → pannello lungo (FASE) | 0,459 | +0,034 | +| → **fuori campione 2021-2023** (FINESTRA) | 0,520 | **+0,061** | + +🚨 **Il 42% del numero pubblicato sta nelle 6 gambe che fuori campione non esistono** (ARB OP SUI APT +SEI TIA) — **e quelle 6 furono messe nell'universo nel 2026-06 guardando la liquidita' HL del 2024+, +cioe' dentro la finestra di scoperta.** La finestra fuori campione, da sola, **migliora**. +✅ Allargare l'universo man mano che le gambe nascono (10→19 espandente) da' **J identico a U13**: +i 0,307 **non si recuperano**. + +⚠️ **Errore di metodo catturato prima di pubblicare:** la prima stesura dava al passo venue **−0,254** +e avrebbe pubblicato *"Binance costa un quarto di J"*. Era **FASE, non venue** — `xsec_engine` +ribilancia sulla parita' dell'indice di pannello, e due pannelli che iniziano a date diverse +ribilanciano in **giorni di calendario diversi**. Allineati i pannelli, il venue vale **−0,006** = +✅ **replica indipendente della validazione di XS01-OOS, sulla funzione obiettivo invece che sullo +Sharpe.** + +**J onesto** (mediana delle 10 fasi, peso 38/38/25): + +| finestra | mediana J | banda p10-p90 | LIVE 75/25 | **delta appaiato** | +|---|---|---|---|---| +| **W-LONG 2021+** | **0,453** | [0,431 – 0,488] | 0,281 | **+0,175 (10/10 fasi)** | +| W-OOS 2021-23 | 0,504 | [0,455 – 0,608] | 0,364 | +0,146 (10/10) | +| W-DISC 2024+ | 0,442 | [0,404 – 0,464] | 0,331 | +0,112 (9/10) | + +XS01 standalone fuori campione: Sharpe 1,04, drift 22,7%, **maxDD −19,2%** contro −11,2% dello sleeve +ufficiale → **il rendimento regge, la coda no, e la barriera guarda la coda.** + +📌 **Il peso 0,50 non sopravvive; la REGIONE robusta si': w_XS ∈ [25%, 38%] e' entro il 3% +dell'ottimo su TUTTE E TRE le finestre**, discovery inclusa. A 50% J scende a 0,438/0,477/0,408 e il +maxDD di libro risale a −12,6%/−11,6%/−9,1% (contro −9,6%/−9,6%/−7,3% a 25%) = **replica +indipendente del punto (ii) di XS01-OOS**. + +🚨 **IL NUMERO OPERATIVO, con banda di fase: P(≥50 €/g) da €600 in 36 mesi = 7,8% [7,2–9,1%], con +P(zero) 25,5%** — contro il **41,7%** pubblicato stamattina. **6,6%** se la firm non lista gli alt; +**4,3%** per il libro live. ⚠️ J e P(≥50/g) hanno **argmax diversi**: si cita il centro della regione +robusta, non l'argmax di finestra. + +**Stress ora ancorati al MISURATO** (delta appaiato argmax−LIVE): drift pieno +0,193 · SKH ×0,50 ++0,124 · SKH ×0,33 +0,113 · **`XS ×0,00` +0,041** · SKH ×0,33 + XS ×0,00 **−0,024** (peggio del libro +live). Lo scenario severo **cambia stato**: non e' piu' *"non sappiamo se il drift esiste"* ma un +contro-fattuale a rendimento nullo, e dice che **XS01 come pura decorrelazione vale +0,04** — tutto il +resto e' il suo drift, che ora e' misurato per **13 gambe su 19**. + +**Gate:** lente **accoppiata obbligatoria** ovunque (close-only girata solo come controllo: **regala ++0,020 di J**); **banda di fase di XS01 girata — prima volta sotto la lente prop** (fortuna della fase +canonica solo +0,019, delta positivo **10/10**); null del de-levering **strutturale** (ogni +configurazione valutata a 8 leve). ⚠️ **Banda d'ancora di SKH01 (23 offset) NON girata**, surrogata +col taglio del drift — **e' la distorsione dichiarata due volte e mai rimossa**, ed e' diventata la +gamba (b) del gate. + +**VERDETTO: LEAD — ridimensionato di un fattore ~5 sul numero operativo, non falsificato.** L'edge +sopravvive alla storia lunga (+0,175 di J, **10/10 fasi**, col 2022 dentro); crollano il **peso 50%** +e il contributo delle **6 gambe non testabili**, non la finestra. + +📌 **`GATE PROP-01` — sostituisce l'attesa di anni, che e' CHIUSA:** +**(a) LISTINO — verifica, €0, BLOCCANTE prima di ogni spesa:** ≥10 delle 13 gambe negoziabili **con +short**; sotto 10 il meccanismo congelato **non ribilancia affatto**. FAIL → si decide sulla riga +senza XS01. *E' la stessa classe dell'errore GTAA01/PRIIPs.* +**(b) BANDA D'ANCORA DI SKH01 SOTTO LA LENTE PROP — misura, data 2026-10-31:** mediana delle +differenze appaiate sui 23 offset, **PASS se > +0,05** (l'agente dichiara **prima** di aspettarsi un +PASS; il surrogato dice +0,11/+0,12). +**(c) CAPITALE:** un'eval HYRO $100k costa **$579 su un conto di $635** — la prima eval consuma il +**91%** del conto. + +**`IL CANALE FUNDED: SI APRE A CONDIZIONE DI leggere il listino della firm` — e di citarlo come +P(≥50 €/g) 7,8% [7,2–9,1%] con P(zero) 25,5%, non 42%.** diff --git a/scripts/research/r0822b_prop_recal.py b/scripts/research/r0822b_prop_recal.py index e39acd8..dcef4bd 100644 --- a/scripts/research/r0822b_prop_recal.py +++ b/scripts/research/r0822b_prop_recal.py @@ -74,6 +74,32 @@ CONVENZIONI DICHIARATE ha una risoluzione e va detta**: SE su un livello di J ~ +-0,010, sulle differenze APPAIATE (indici di bootstrap condivisi) molto meno, ~+-0,007. +ESITO (2026-08-22, corsa completa 309 s, 5.212 celle dichiarate) +---------------------------------------------------------------- +* RIPRODUZIONE **ESATTA** dei numeri pubblicati: J 0,738 / 0,721 / 0,335, P(pass) 82,2 / 77,3 / + 38,6%, delta appaiati +0,0164 e +0,3996, scala di conti 39,28 EUR/g e P(>=50/g) 41,7%. Tre + controlli bit-exact in piu' (il mio costruttore di tuple = quello del 25/07; il mio costruttore + di libro = `PA.book_RG`, anche sotto stress): **max|diff| = 0,0** su tutti. +* **J NON regge alla taglia pubblicata, e il colpevole NON e' la finestra.** Decomposizione a un + grado di liberta' per volta, tutta sullo stesso pannello: venue (HL -> Binance, 19 gambe, + date allineate) **-0,006**; universo (19 -> 13 gambe) **-0,307**; fase **+0,034**; finestra + (2024+ -> 2021-2023) **+0,061**. Il 42% del numero pubblicato sta nelle **6 gambe che non + esistono fuori campione** (ARB OP SUI APT SEI TIA), non nel periodo. +* Numeri onesti sulla parte testabile (13 gambe), mediana delle 10 fasi di XS01, peso 38/38/25: + J **0,453** su W-LONG 2021+ (LIVE 0,281; delta appaiato **+0,175**, positivo 10/10 fasi), + **0,504** su W-OOS 2021-23, **0,442** su W-DISC. Cioe' ~0,45-0,50 invece di 0,738. +* **La previsione registrata prima e' confermata sui pesi e sbagliata (ottimista) sul livello:** + regione robusta **w_XS = 25-38%** su TUTTE e tre le finestre (prevista [0,25 ; 0,38]) — quindi + il **50% dell'argmax di PROP-ALLOC non sopravvive**; J 0,45-0,52 contro [0,50 ; 0,70] previsto; + P(>=50/g) 7,8% contro [10% ; 35%] previsto. +* **Il numero operativo: P(>=50 EUR/g) da EUR 600 in 36 mesi = 7,8% [banda di fase 7,2-9,1%], + P(zero) 25,5%** — contro il 41,7% pubblicato, e contro **6,6%** se la firm non lista gli alt. + Il libro live sulla stessa lente fa 4,3%. +* Lo scenario severo di PROP-ALLOC (`XS x0,00`) **cambia stato**: non e' piu' "non sappiamo se il + drift esiste" ma un contro-fattuale a rendimento nullo, e li' il delta scende a **+0,041** + (col taglio congiunto SKH x0,33 diventa **-0,024**, cioe' peggio del libro live). Tutto il + vantaggio vive sul drift di XS01 — che ora e' misurato, per 13 gambe su 19. + Uso: `nice -n 19 timeout 900 uv run python scripts/research/r0822b_prop_recal.py` Rete: NESSUNA (tutto da disco: parquet certificati + cache Binance di r0822b_xs01_oos). """ @@ -190,7 +216,7 @@ def bin_loader(sym: str) -> pd.DataFrame: """Legge dalla cache di r0822b (nessuna rete) e SCARTA la barra del giorno in corso: una barra giornaliera parziale in coda e' esattamente il difetto trovato oggi nei monitor forward.""" d = X.fetch_binance_daily(sym) - today = pd.Timestamp.utcnow().normalize().value // 10**6 + today = pd.Timestamp.now("UTC").normalize().value // 10**6 return d[d["timestamp"] < today].reset_index(drop=True) @@ -466,6 +492,83 @@ def main() -> None: f" (PROP-ALLOC pubblicava {PUB['dJ_vs_live']:+.4f} su W-DISC con XS01 HL)") tick("§3 griglie") + # ================================================== §3-bis. DECOMPOSIZIONE + hr("§3-bis. DA DOVE VIENE IL SALTO 0.738 -> ~0.47 — un grado di liberta' alla volta") + print(" Fra il numero pubblicato e quello di §3 cambiano TRE cose insieme (venue, universo,") + print(" finestra). Sommarle e chiamarle 'l'effetto della storia lunga' sarebbe l'errore che") + print(" il progetto ha gia' pagato due volte. Qui si muove un grado di liberta' per volta,") + print(" sempre sul MIO pannello a 3 gambe (cosi' anche il pannello smette di essere una") + print(" variabile nascosta).") + ev_d, fu_d = res[WINDOWS[2][0]]["ev"], res[WINDOWS[2][0]]["fu"] + ev_o, fu_o = res[WINDOWS[1][0]]["ev"], res[WINDOWS[1][0]]["fu"] + ev_l, fu_l = res[WINDOWS[0][0]]["ev"], res[WINDOWS[0][0]]["fu"] + # ⚠ ERRORE CATTURATO IN SESSIONE, e vale piu' del numero che correggeva: `xsec_engine` + # ribilancia quando `i % H == phase`, dove `i` e' l'indice NEL PANNELLO. Due pannelli che + # cominciano a date diverse ribilanciano quindi in GIORNI DI CALENDARIO diversi: confrontarli + # misura la FASE, non il venue. Alla prima stesura il passo "venue" dava -0.254 di J (e + # avrei pubblicato "Binance costa un quarto di J") mentre XS01-OOS aveva misurato dSharpe + # -0.025 sullo stesso confronto fatto bene. Qui il pannello Binance e' RIALLINEATO alle + # stesse date di quello HL, cosi' la parita' dell'indice — e con essa la fase — coincide. + hl_idx = ref.index + C19 = Cb[list(XS_UNIVERSE)].reindex(hl_idx).dropna() + xs19_al = xs_tuples(C19, Ob.reindex(C19.index)[C19.columns], + Hb.reindex(C19.index)[C19.columns], + Lb.reindex(C19.index)[C19.columns], phase=0) + C13 = Cb[X.U13].reindex(C19.index).dropna() + xs13_al = xs_tuples(C13, Ob.reindex(C13.index)[X.U13], Hb.reindex(C13.index)[X.U13], + Lb.reindex(C13.index)[X.U13], phase=0) + bump(2) + steps = [("XS01 = HL 19 gambe W-DISC (= il pubblicato)", I_DISC, ref, ev_d, fu_d), + ("XS01 = BINANCE 19 g. W-DISC allineato (VENUE)", I_DISC, xs19_al, ev_d, fu_d), + ("XS01 = BINANCE 13 g. W-DISC allineato (UNIVERSO)", I_DISC, xs13_al, ev_d, fu_d), + ("XS01 = BINANCE 13 g. W-DISC pannello lungo (FASE)", I_DISC, xs13, ev_d, fu_d), + ("XS01 = BINANCE 13 g. W-OOS (FINESTRA)", I_OOS, xs13, ev_o, fu_o)] + print(f"\n {'passo':>50} {'argmax':>10} {'leva':>6} {'J':>7} {'dJ dal passo prima':>20}") + prev = None + dec = {} + for lab2, ii, xf, ev, fu in steps: + Gs = scan(grid, ii, xf, ev, fu) + b2 = best_row(Gs) + dec[lab2] = b2 + dj = "" if prev is None else f"{float(b2['J'])-prev:>+20.3f}" + print(f" {lab2:>50} {b2['w']:>10} {b2['lev']:>6.3f} {b2['J']:>7.3f} {dj}") + prev = float(b2["J"]) + print("\n Le righe sono ordinate dal piu' al meno controllabile. Quella che il progetto deve") + print(" guardare e' la piu' grande: se e' la FASE, il numero pubblicato non e' un numero") + print(" di strategia ma di calendario, ed e' il quarto modo d'ingannarsi dell'elenco del") + print(" brief. La finestra fuori campione, da sola, non peggiora nulla — conferma su J cio'") + print(" che XS01-OOS ha misurato sul rendimento.") + + print("\n E l'altro capo della banda: universo ESPANDENTE (10 -> 19 gambe man mano che") + print(" vengono quotate), che e' cio' che un implementatore in tempo reale avrebbe avuto:") + print(f" {'finestra':>34} {'argmax':>10} {'leva':>6} {'J':>7} {'maxDD':>7} " + f"{'J con U13':>10}") + for lab2, ii, ev, fu in (("W-OOS 2021-2023", I_OOS, ev_o, fu_o), + ("W-LONG 2021+", I_LONG, ev_l, fu_l)): + Gs = scan(grid, ii, xsEXP, ev, fu) + b2 = best_row(Gs) + j13 = float(best_row(res[[w for w in res if w.startswith(lab2.split()[0])][0]]["G"])["J"]) + print(f" {lab2:>34} {b2['w']:>10} {b2['lev']:>6.3f} {b2['J']:>7.3f} " + f"{b2['maxdd']*100:>6.1f}% {j13:>10.3f}") + + hr("§3-ter. CONTROLLO DI LENTE — quanto sarebbe cieca la close-only su QUESTI numeri") + print(" Su una regola di DD a UN GIORNO la close-only non scatta mai. Non e' un'opinione:") + print(" si vede rigirando le stesse celle con gap = 0.") + bL0 = best_row(res[WINDOWS[0][0]]["G"]) + Rc, Gc = rg(wdict(bL0["w"]), I_LONG, xs13) + o_cp = obj_rg(Rc, Gc, float(bL0["lev"]), ev_l, fu_l) + Rd_ = PA.deluck(Rc) + e_cl = PA.eval_sim(Rd_, Gc, ev_l, float(bL0["lev"]), HYRO, lens="close") + f_cl = PA.funded_sim(Rd_, Gc, fu_l, float(bL0["lev"]), HYRO, 100_000.0, lens="close") + bump(2) + print(f" W-LONG argmax {bL0['w']} @{bL0['lev']:.2f}x :" + f" ACCOPPIATA J {o_cp['J']:.3f} (P(pass) {o_cp['p_pass']:.1%}, P(vivo) {o_cp['p_alive']:.1%})") + print(f" {'':>44} CLOSE-ONLY J {e_cl['p_pass']*f_cl['p_alive']:.3f} " + f"(P(pass) {e_cl['p_pass']:.1%}, P(vivo) {f_cl['p_alive']:.1%})") + print(f" -> la close-only regala {e_cl['p_pass']*f_cl['p_alive']-o_cp['J']:+.3f} di J. Ogni") + print(" numero di questo file e' ACCOPPIATO; la close-only e' qui solo come controllo.") + tick("§3-bis/ter decomposizione") + # ================================================== §4. LA REGIONE, NON IL PUNTO hr("§4. IL PESO DI XS01 — c'e' una REGIONE robusta su ENTRAMBE le finestre?") print(" PROP-ALLOC ha gia' misurato che il PUNTO non conta (il massimo di 200 pesi casuali") @@ -502,6 +605,60 @@ def main() -> None: f"{[wx for wx in xs_levels if all(wx in prof_by_w[l] and prof_by_w[l][wx] >= 0.95*max(prof_by_w[l].values()) for l, _ in WINDOWS)]})") tick("§4 regione") + # ================================================== §4-bis. BANDA DI FASE + hr("§4-bis. LA BANDA DI FASE DI XS01 (H=10) SOTTO LA LENTE PROP — mai girata prima") + print(" XS01 ribilancia ogni 10 giorni: le fasi possibili sono 10 e il progetto misura che la") + print(" fase canonica e' fortunata (audit 02/07: DD al 15° pctl, FULL all'85°). PROP-ALLOC") + print(" gira sulla SOLA fase 0. Qui la si gira tutta, al peso della REGIONE ROBUSTA di §4.") + print(" La stima onesta e' la MEDIANA della banda; il confronto col LIVE e' la MEDIANA delle") + print(" DIFFERENZE APPAIATE (mai la differenza delle mediane).") + W_ROB = "38/38/25" + print(f"\n peso fisso {W_ROB} (centro della regione robusta), leva scelta per fase") + print(f" {'finestra':>28} {'J fase 0':>9} {'MEDIANA':>9} {'banda p10-p90':>16} " + f"{'fasi>LIVE':>10} {'delta appaiato mediano':>24}") + phase_med = {} + for lab, ii in WINDOWS: + ev, fu = res[lab]["ev"], res[lab]["fu"] + RL, GL = rg({"TP01": 0.75, "SKH01": 0.25}, ii, xs13) + jL, lvL = -1.0, None + vL = None + for lv in LEVS: + o = obj_rg(RL, GL, lv, ev, fu) + if o["J"] > jL: + jL, lvL, vL = o["J"], lv, o["jvec"] + js, deltas, bestph = [], [], {} + for ph in range(10): + xsp = xs_tuples(p13, o13, h13, l13, phase=ph) + Rp, Gp = rg(wdict(W_ROB), ii, xsp) + jb, vb = -1.0, None + for lv in LEVS: + o = obj_rg(Rp, Gp, lv, ev, fu) + if o["J"] > jb: + jb, vb = o["J"], o["jvec"] + js.append(jb) + deltas.append(float((vb - vL).mean())) + bestph[ph] = jb + bump(10 * len(LEVS) + len(LEVS)) + med = float(np.median(js)) + phase_med[lab] = dict(median=med, band=(float(np.percentile(js, 10)), + float(np.percentile(js, 90))), + ph0=js[0], jlive=jL, dmed=float(np.median(deltas)), + npos=int(sum(1 for d in deltas if d > 0)), + argmax_phase=int(np.argmax(js))) + print(f" {lab:>28} {js[0]:>9.3f} {med:>9.3f} " + f"[{np.percentile(js, 10):>6.3f},{np.percentile(js, 90):>6.3f}] " + f"{sum(1 for j2 in js if j2 > jL):>7}/10 " + f"{np.median(deltas):>+18.3f} ({sum(1 for d in deltas if d > 0)}/10 >0)") + print(f"\n J del libro LIVE 75/25 (non dipende dalla fase di XS01): " + f"{phase_med[WINDOWS[0][0]]['jlive']:.3f} W-LONG, " + f"{phase_med[WINDOWS[1][0]]['jlive']:.3f} W-OOS, " + f"{phase_med[WINDOWS[2][0]]['jlive']:.3f} W-DISC") + print(" ⚠ Questa e' la banda della fase di XS01 SOLTANTO. La banda d'ancora di SKH01 (23") + print(" offset, quella che il progetto misura come la piu' grande da restituire) resta") + print(" NON GIRATA sotto questa lente — costo del recon orario. §5 la surroga con un") + print(" taglio del drift, che e' una stima, non una misura.") + tick("§4-bis banda di fase") + # ================================================== §5. LA BANDA ANCORATA AL MISURATO hr("§5. LA BANDA — con gli stress ANCORATI a cio' che e' misurato, non a cio' che era assunto") print(" PROP-ALLOC pubblicava 42% / 7,7% / 0,7% dove il caso severo era 'XS x0,00' = il drift") @@ -511,10 +668,13 @@ def main() -> None: print(" non sotto questa lente) e (b) il LISTINO della firm (§6). Gli stress qui sotto sono") print(" quelli, non un pessimismo arbitrario.") st_rows = [] - STRESS = ((), (("SKH01", 0.50),), (("SKH01", 0.33),)) + STRESS = ((), (("SKH01", 0.50),), (("SKH01", 0.33),), + (("XS01", 0.00),), (("SKH01", 0.33), ("XS01", 0.00))) SLAB = {(): "nessuno (drift pieno)", (("SKH01", 0.50),): "SKH x0.50 (ancora 26/07)", - (("SKH01", 0.33),): "SKH x0.33 (ancora severa)"} + (("SKH01", 0.33),): "SKH x0.33 (ancora severa)", + (("XS01", 0.00),): "XS x0.00 [ORA SUPERATO]", + (("SKH01", 0.33), ("XS01", 0.00)): "SKH x0.33 + XS x0.00 [vecchio severo]"} for lab, ii in (WINDOWS[0], WINDOWS[1]): Gw, ev, fu = res[lab]["G"], res[lab]["ev"], res[lab]["fu"] top_keys = list(Gw.sort_values("J", ascending=False).drop_duplicates("w")["w"].head(10)) @@ -546,6 +706,11 @@ def main() -> None: f"{oL['J']:>11.3f} {d_.mean():>+11.4f} " f"+-{d_.std(ddof=1)/np.sqrt(len(d_)):.4f}") st_rows.append((lab, SLAB[dmt], best_k, best_l, best_j, oL["J"])) + print(" Le ultime due righe sono gli scenari di PROP-ALLOC. `XS x0.00` significava") + print(" 'il drift di XS01 potrebbe essere zero, non lo sappiamo': dopo XS01-OOS e") + print(" questo file NON e' piu' uno stress plausibile ma un contro-fattuale, perche'") + print(" quel drift e' MISURATO fuori campione ed e' positivo. Resta utile come") + print(" pavimento: dice quanto vale XS01 come pura DECORRELAZIONE, a rendimento nullo.") tick("§5 banda") # ================================================== §6. XS01 ASSENTE @@ -612,6 +777,43 @@ def main() -> None: bump(12) tick("§7 scala di conti") + hr("§7-bis. LA BANDA DI FASE DEL NUMERO OPERATIVO — P(>=50/g) alle 10 fasi di XS01") + print(" Il numero che l'operatore legge non puo' stare su una fase sola. Peso fisso") + print(f" {W_ROB} (regione robusta), finestra W-LONG, leva per fase = quella che massimizza J.") + ev_l2, fu_l2 = res[WINDOWS[0][0]]["ev"], res[WINDOWS[0][0]]["fu"] + pt, med_eur, zeros = [], [], [] + print(f"\n {'fase':>5} {'leva':>6} {'J':>7} {'EUR/g med':>10} {'P(>=10/g)':>10} " + f"{'P(>=50/g)':>10} {'P(zero)':>8}") + for ph in range(10): + xsp = xs_tuples(p13, o13, h13, l13, phase=ph) + Rp, Gp = rg(wdict(W_ROB), I_LONG, xsp) + jb, lvb = -1.0, None + for lv in LEVS: + o = obj_rg(Rp, Gp, lv, ev_l2, fu_l2) + if o["J"] > jb: + jb, lvb = o["J"], lv + cfg = tuple(wdict(W_ROB).get(n, 0.0) for n in W3) + key = (cfg[0], cfg[1], cfg[2], "shared") + saved = pc._TUP_CACHE.pop(key, None) + pc._TUP_CACHE[key] = (Rp, Gp, I_LONG) + r = pc.simulate([cfg], [0] * pl.MAX_CONCURRENT, n_paths=1500, lev=lvb, + seed=20260822, lens="coupled", start=str(I_LONG[0].date())) + pc._TUP_CACHE.pop(key, None) + if saved is not None: + pc._TUP_CACHE[key] = saved + pt.append(r["p_target"]); med_eur.append(r["med"]); zeros.append(r["p_zero"]) + print(f" {ph:>5} {lvb:>6.3f} {jb:>7.3f} {r['med']:>10.2f} {r['p_ge10']:>10.1%} " + f"{r['p_target']:>10.1%} {r['p_zero']:>8.1%}") + bump(10 * len(LEVS)) + print(f"\n MEDIANA su 10 fasi: EUR/g {np.median(med_eur):.2f} | " + f"P(>=50/g) {np.median(pt):.1%} [p10 {np.percentile(pt,10):.1%}, " + f"p90 {np.percentile(pt,90):.1%}] | P(zero) {np.median(zeros):.1%}") + print(f" Contro il PUBBLICATO di PROP-ALLOC: P(>=50/g) 41.7%, P(zero) 13.9% (fase 0, XS01 a") + print(f" 19 gambe, finestra di scoperta).") + ladder_band = (float(np.median(pt)), float(np.percentile(pt, 10)), float(np.percentile(pt, 90)), + float(np.median(zeros))) + tick("§7-bis banda di fase della scala") + # ================================================== §8. SINTESI + GATE hr("§8. SINTESI — la banda da citare, e il gate da RI-REGISTRARE") bL = best_row(res[WINDOWS[0][0]]["G"]) @@ -623,11 +825,63 @@ def main() -> None: print(f" W-OOS 2021-2023 argmax {bO['w']:>10} @{bO['lev']:.2f}x J {bO['J']:.3f}") print(f" W-LONG 2021+ argmax {bL['w']:>10} @{bL['lev']:.2f}x J {bL['J']:.3f}") print(f" (PROP-ALLOC pubblicato, XS01 HL 19 gambe, W-DISC: 25/25/50 @0.75x J 0.738)") + print(f"\n Gli stessi J, ma alla MEDIANA delle 10 fasi di XS01 (peso fisso 38/38/25):") + for lab, _ in WINDOWS: + pm = phase_med[lab] + print(f" {lab:>28} fase 0 {pm['ph0']:.3f} -> MEDIANA {pm['median']:.3f} " + f"[{pm['band'][0]:.3f},{pm['band'][1]:.3f}] LIVE {pm['jlive']:.3f} " + f"delta mediano {pm['dmed']:+.3f} ({pm['npos']}/10 >0)") print(f"\n P(>=50 EUR/g) in 36 mesi, banda onesta:") for short in ("W-LONG", "W-OOS", "W-DISC"): row = " | ".join(f"{k}: {lad[(short, k)]['p_target']:.1%}" for k in ("argmax", "2550", "noxs", "live") if (short, k) in lad) print(f" {short:>8} {row}") + print(f"\n P(>=50 EUR/g) — IL NUMERO DA CITARE (W-LONG, peso {W_ROB}, mediana di 10 fasi):") + print(f" {ladder_band[0]:.1%} [banda di fase {ladder_band[1]:.1%} - {ladder_band[2]:.1%}]" + f" P(zero) {ladder_band[3]:.1%}") + print(f" contro il 41.7% pubblicato (fase 0, XS01 a 19 gambe, finestra di scoperta)") + print(f" e contro il {lad[('W-LONG', 'noxs')]['p_target']:.1%} se la firm non lista gli alt.") + + hr("§8-bis. IL GATE DA RI-REGISTRARE — `GATE PROP-01`") + print(""" SOSTITUISCE il gate del 22/08 ("non aprire un funded prima che XS01 abbia una + finestra fuori dal 2024-2026"), che e' CHIUSO: la finestra esiste, e' stata misurata, e + NON e' lei il problema (+0.061 di J, cioe' migliora). Tre gambe, in ordine di costo + crescente, perche' la prima puo' chiudere la questione da sola. + + (a) LISTINO — VERIFICA, non misura. Costo EUR 0. BLOCCANTE, prima di qualunque spesa, + nessuna data perche' precede tutto. + Leggere il listino della firm e contare quante delle 13 gambe U13 (BTC ETH BNB XRP + LTC ADA LINK DOGE SOL AVAX NEAR AAVE INJ) sono negoziabili CON SHORT ABILITATO. + PASS se >= 10 (il meccanismo congelato ha `min_assets = 10`: sotto, non ribilancia). + FAIL -> il canale non si chiude, ma si valuta sulla riga SENZA XS01: J 0.38-0.40 + invece di 0.45-0.52, P(>=50/g) ~6.6% invece di ~10%, e soprattutto la + raccomandazione "riallocare per la barriera" DECADE (senza XS01 l'argmax e' 38/62 o + 50/50, cioe' un tilt su SKH01, lo sleeve che il progetto misura come il piu' fragile). + E' la stessa classe dell'errore GTAA01/PRIIPs: 5 settimane di misure su un'assunzione + mai verificata sul conto reale, e il controllo costo' un ordine di prova. + + (b) BANDA D'ANCORA DI SKH01 SOTTO LA LENTE PROP — MISURA. Data: 2026-10-31. + E' l'unica distorsione dichiarata due volte (PROP-ALLOC e questo file) e mai rimossa. + Costo: rifare `pc._hourly_legs` ai 23 offset della griglia 230m/690m e rigirare §3. + Metrica: MEDIANA DELLE DIFFERENZE APPAIATE J(peso nella regione w_XS 25-38%) - + J(libro LIVE 75/25) sui 23 offset, finestra W-LONG. + PASS se > +0.05. Surrogato di oggi (taglio del drift SKH x0.50 / x0.33): +0.124 e + +0.113; banda di FASE di XS01, che ho potuto girare: +0.175, positiva in 10/10. + Mi aspetto un PASS e lo dichiaro prima. FAIL <= +0.05 -> il vantaggio era calendario. + + (c) CAPITALE DEL BIGLIETTO — condizione, non data. Un'eval HYRO $100k costa $579 su un + conto di $635. E' gia' dentro la simulazione della scala (e' gran parte del P(zero) + del 26-34%), ma va detto: la prima eval consuma il 91% del conto vivo. + + COSA FA FALLIRE L'INTERO RISULTATO + 1. il listino non ha 10 gambe shortabili -> (a); + 2. la banda d'ancora di SKH01 azzera il delta -> (b); + 3. si continua a citare 0.738. E' un numero a 19 GAMBE, e le 6 che lo separano dalle + 13 testabili valgono -0.307 di J MISURATI sulla stessa finestra e sullo stesso + venue = il 42% del totale. Quelle 6 (ARB OP SUI APT SEI TIA) non hanno storia + fuori campione E sono state incluse nell'universo nel 2026-06 guardando la + liquidita' HL del 2024+, cioe' dentro la finestra di scoperta.""") + print(f"\n TRIAL/CELLE DICHIARATI (al rialzo): {TRIALS}") print(f"\n fatto in {time.time()-t0:.0f}s") print("=" * 104)