research(wave-0822): BIN-FREQ — direzione reale (0/72 sul segno inverso), taglia = selezione; e due premesse del briefing refutate
This commit is contained in:
@@ -697,7 +697,7 @@ stessi hanno nominato senza poterli eseguire**. Stesso contratto di consegna, st
|
|||||||
| 22 | MAKER | l'esecuzione passiva e' una fonte di ritorno, al netto del costo di non essere eseguiti? | **SCARTATO** — il segno dipende da `<` contro `<=` |
|
| 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 |
|
| 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 |
|
| 24 | CRITICO | cosa NON e' stato misurato, e quale singola misura mancante vale di piu' | **3 correzioni all'ondata**, 1 regola mia ritirata |
|
||||||
| 25 | BIN-FREQ | il binario di frequenza su SKH01 e' un candidato o un sottoprodotto? | _in corso_ |
|
| 25 | BIN-FREQ | il binario di frequenza su SKH01 e' un candidato o un sottoprodotto? | **LEAD** — direzione reale, taglia = selezione |
|
||||||
| 26 | TP01-SINISTRO | quanto pesa TP01 se l'obiettivo include un crash che nel campione non c'e'? | **allarme SCARTATO** — il rischio e' XS01, non TP01 |
|
| 26 | TP01-SINISTRO | quanto pesa TP01 se l'obiettivo include un crash che nel campione non c'e'? | **allarme SCARTATO** — il rischio e' XS01, non TP01 |
|
||||||
| 27 | SURFACE-RV | la superficie e' internamente incoerente, e l'incoerenza vale piu' del costo di attraversarla? | **SCARTATO** — l'incoerenza al mid **e'** la larghezza del mercato |
|
| 27 | SURFACE-RV | la superficie e' internamente incoerente, e l'incoerenza vale piu' del costo di attraversarla? | **SCARTATO** — l'incoerenza al mid **e'** la larghezza del mercato |
|
||||||
|
|
||||||
@@ -1157,3 +1157,75 @@ chiusure**, e i close giornalieri non lo vedrebbero.
|
|||||||
⚠️ *Nota di attribuzione: il file risultava `M` in git perche' **io** (coordinatore) l'avevo incluso
|
⚠️ *Nota di attribuzione: il file risultava `M` in git perche' **io** (coordinatore) l'avevo incluso
|
||||||
in un commit mentre l'agente ci stava ancora lavorando — non un altro agente. Un `git add -A` durante
|
in un commit mentre l'agente ci stava ancora lavorando — non un altro agente. Un `git add -A` durante
|
||||||
un'ondata cattura il lavoro in corso.*
|
un'ondata cattura il lavoro in corso.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 25 — BIN-FREQ (il binario di frequenza su SKH01, giudicato come candidato)
|
||||||
|
|
||||||
|
`scripts/research/r0822b_bin_freq.py` (~400 s, **23 ancore piene**, due esecuzioni indipendenti con
|
||||||
|
output **numericamente identici**). **144 celle** dichiarate nel docstring **prima di guardare**, piu'
|
||||||
|
i **71 trial gia' spesi sullo stesso oggetto** (28 VOL-SIZE + 43 scettico) → **conto onesto = 215**:
|
||||||
|
*riaprire un parametro riapre la sua famiglia.*
|
||||||
|
|
||||||
|
**Repliche bit-exact** (`max|dif| = 0`) contro `sleeves._skyhook_returns()` **e** contro
|
||||||
|
`r0702_anchor_skh01.run_asset`; **titolo dello scettico riprodotto esattamente** chiamando la sua
|
||||||
|
funzione (`BIN L>=med` +0,080 in 20/23, inverso −0,159 in 0/23).
|
||||||
|
|
||||||
|
| | ShFULL | ShHOLD | maxDD | CAGR |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| BASE (libro live 75/25) | 1,626 | 1,037 | 10,4% | 18,6% |
|
||||||
|
| BIN, peso effettivo lasciato cadere | 1,690 | 1,031 | 10,3% | 17,8% |
|
||||||
|
| **BIN, controllo ISO-PESO** | **1,589** | 0,956 | 10,0% | 16,8% |
|
||||||
|
|
||||||
|
📌 **La statistica che decide non e' l'argmax, e' la MEDIANA DI FAMIGLIA.** Argmax
|
||||||
|
(`q0,50 w60 h0,10 s+`) ISO **+0,112 in 23/23**; **stima onesta di famiglia +0,007**, con **39/72
|
||||||
|
celle positive = 54% ≈ monetina**. **L'argmax vale 16× la mediana → punta, non plateau.**
|
||||||
|
**Controllo di segno: 0/72 celle positive** sulla meta' inversa → la *direzione* e' solidissima.
|
||||||
|
|
||||||
|
**Gate:** `marginal_vs_tp01` **ADDS**; selezione **in-sample-only** sceglie la stessa cella mentre
|
||||||
|
scegliendo **sull'hold-out** ne esce un'altra (−0,017) → **il gate ha potenza**;
|
||||||
|
**`weights_tilt_null` FAIL** (pctl 36-38) **e per giunta inerte** (il binario *abbassa* il peso
|
||||||
|
effettivo 0,250→0,19, e nella forma di deploy naturale il vettore proposto e' identico a quello
|
||||||
|
corrente); causalita' verificata con **troncamento diretto** su 52 decisioni, 0 divergenti;
|
||||||
|
**trasferisce a SKH01_V1** (geometria d'uscita diversa): +0,087 in 20-21/23.
|
||||||
|
|
||||||
|
❌ **Il deflated-Sharpe NON e' vacuo — refuta l'ipotesi a-priori che l'agente aveva registrato:**
|
||||||
|
**0,976** (N=144) / **0,977** (N=215, conto onesto) / 0,948 (N=500), baseline 0,828/0,834. E il
|
||||||
|
**motivo e' riusabile**: il DSR e' vacuo quando i trial si somigliano (var→0 ⇒ sr0→0 ⇒ DSR≈1 *per
|
||||||
|
chiunque*); una famiglia **binaria** contiene celle che scartano insiemi di trade molto diversi,
|
||||||
|
quindi **riacquista potenza**. *Non e' il binario a essere piu' solido: e' la famiglia a essere piu'
|
||||||
|
larga.* ✅ Terza misura convergente della stessa giornata sul difetto del DSR (con BOCPD e CRITICO).
|
||||||
|
|
||||||
|
⚠️ **Il null "con potenza" ha una mediana che NON e' zero, ed e' un fatto di misura:** scartare a caso
|
||||||
|
il 40% dei trade **danneggia**, perche' lo Sharpe annualizzato va con √(scommesse/anno) — misurato:
|
||||||
|
gamba 1,107 → **0,883** permutata contro **0,861** previsti da √0,60. Il null resta valido e **piu'
|
||||||
|
severo** (reale +0,112 vs massimo del null −0,031, p<0,01), **ma risponde a "batte una selezione
|
||||||
|
casuale?", non a "batte il non filtrare?"**.
|
||||||
|
|
||||||
|
🚨 **Due premesse del MIO briefing misurate e REFUTATE:**
|
||||||
|
(i) *"il binario dimezza gli ordini → migliora l'eseguibilita' e riduce le fee"* — gli ordini
|
||||||
|
**nettati** calano del **17%**, non del 50%; i sotto-min-order **non si muovono** perche' sono di
|
||||||
|
TP01; e l'**haircut a $635 e' 0,001 in entrambe le braccia**: non c'era niente da guadagnare.
|
||||||
|
(ii) *"converti il risparmio di fee in Sharpe con la curva del 26/07"* — **a fee ZERO l'effetto resta
|
||||||
|
l'87-110%** → non e' risparmio di costo, e' **informazione sul rendimento lordo**, e convertirlo
|
||||||
|
sarebbe stata un'attribuzione sbagliata.
|
||||||
|
|
||||||
|
**VERDETTO: LEAD** (non candidato, non scartato). La **direzione** e' reale e sopravvive a tutto; la
|
||||||
|
**taglia di una singola cella e' selezione**.
|
||||||
|
📌 **E la domanda che avevo posto — "+0,080 contro ±0,196 di banda d'ancora, merita?" — era il
|
||||||
|
confronto SBAGLIATO** (la banda del *livello* si cancella in un disegno appaiato), **ma la risposta
|
||||||
|
corretta e' PEGGIORE per il candidato**. Criterio dichiarato, 4 gambe: (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 ≥ €0,10/giorno per pagare un modo di fallire in
|
||||||
|
piu' → **FAIL: €0,0113/giorno** ($4,79/anno a $635).
|
||||||
|
Due prove ausiliarie che chiudono il caso: **due implementazioni difendibili della stessa regola**
|
||||||
|
(d'accordo sul 97,6% dei trade) danno **+0,066 contro +0,080** — *il 21% dell'effetto sta nel come si
|
||||||
|
riempie il warm-up*; e **versare €500/mese vale ~1456× l'effetto misurato**.
|
||||||
|
**Libro, pesi, cron, config INVARIATI.**
|
||||||
|
|
||||||
|
📌 **Riapertura pre-registrata: non una data, una SOGLIA DI CAPITALE** — cio' che fallisce e' il
|
||||||
|
rapporto fra un costo operativo **fisso** e un beneficio **proporzionale**, e nessun dato in piu' lo
|
||||||
|
cambia (con SE(Sharpe)≈1,4 su 6 mesi nessun forward misura 0,07). €0,10/giorno richiede **~$5.600**
|
||||||
|
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.
|
||||||
|
|||||||
@@ -56,8 +56,12 @@ Nessuna riscrittura: `extract / equity_daily / leg_daily / sizes_from_L / book /
|
|||||||
sono IMPORTATE da r0822_vol_size, e il titolo dello scettico e' riprodotto chiamando la SUA
|
sono IMPORTATE da r0822_vol_size, e il titolo dello scettico e' riprodotto chiamando la SUA
|
||||||
funzione. Replica bit-exact contro `sleeves._skyhook_returns()` prima di ogni delta (§0).
|
funzione. Replica bit-exact contro `sleeves._skyhook_returns()` prima di ogni delta (§0).
|
||||||
|
|
||||||
USO: nice -n 19 timeout 900 uv run python scripts/research/r0822b_bin_freq.py [--every K]
|
USO: nice -n 19 timeout 900 uv run python scripts/research/r0822b_bin_freq.py
|
||||||
--every 8 -> 3 ancore (pilota). default: tutte e 23.
|
[--every K] 1 ancora ogni K delle 23 (K=8 -> 3 ancore, pilota ~80 s)
|
||||||
|
[--ndraw N] estrazioni del null di permutazione (default 100)
|
||||||
|
Con i default gira in ~400 s e ~500 MB di RSS su questa VPS (2 core). Tutti i numeri
|
||||||
|
riportati qui vengono da questa invocazione, e due esecuzioni indipendenti hanno dato
|
||||||
|
output numericamente IDENTICI.
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
@@ -192,9 +196,12 @@ def iso_pair(TP: pd.Series, leg: pd.Series, leg_base: pd.Series):
|
|||||||
def main() -> None:
|
def main() -> None:
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
ap.add_argument("--every", type=int, default=1)
|
ap.add_argument("--every", type=int, default=1)
|
||||||
ap.add_argument("--ndraw", type=int, default=120)
|
ap.add_argument("--ndraw", type=int, default=100)
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
offs = OFFSETS_FULL[:: max(1, args.every)]
|
offs = OFFSETS_FULL[:: max(1, args.every)]
|
||||||
|
if len(offs) < 3:
|
||||||
|
raise SystemExit(f"--every {args.every} lascia {len(offs)} ancore: "
|
||||||
|
"`A.anchor_luck_delta` ne vuole almeno 3 (usa --every <= 8).")
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
|
|
||||||
print("=" * L)
|
print("=" * L)
|
||||||
@@ -772,11 +779,18 @@ def main() -> None:
|
|||||||
print(f" (RSS {rss_mb():.0f} MB)")
|
print(f" (RSS {rss_mb():.0f} MB)")
|
||||||
f_mod = FEEDEC[(f"MODELLATA {keep_fee*1e4:.0f} bps RT (i backtest)", nmcan)]
|
f_mod = FEEDEC[(f"MODELLATA {keep_fee*1e4:.0f} bps RT (i backtest)", nmcan)]
|
||||||
f_zero = FEEDEC[("fee ZERO (informazione pura)", nmcan)]
|
f_zero = FEEDEC[("fee ZERO (informazione pura)", nmcan)]
|
||||||
print(f" -> a fee ZERO resta {f_zero:+.3f} di {f_mod:+.3f} = "
|
quota_info = 100.0 * f_zero / f_mod if f_mod else float("nan")
|
||||||
f"{100*f_zero/f_mod if f_mod else float('nan'):.0f}% dell'effetto: la parte restante")
|
print(f" -> a fee ZERO resta {f_zero:+.3f} di {f_mod:+.3f} = {quota_info:.0f}% dell'effetto.")
|
||||||
print(" e' fee risparmiata. La fee vera oggi e' 3,5 bps/lato, meno di quella modellata,")
|
if quota_info >= 85.0:
|
||||||
print(" quindi nel LIVE la componente-fee del vantaggio e' PIU' PICCOLA di quella misurata")
|
print(" ❌ IPOTESI REFUTATA (era la mia, ed era anche quella del compito): il vantaggio")
|
||||||
print(" sui backtest — il verso in cui il numero pubblicato e' ottimista per il deploy.")
|
print(" NON e' fee risparmiata. A fee zero l'effetto c'e' tutto, quindi scartare i")
|
||||||
|
print(" trade in alta vol e' INFORMAZIONE sul rendimento lordo, non un risparmio di")
|
||||||
|
print(" costo. Conseguenza pratica: NON si puo' replicare abbassando il turnover, e")
|
||||||
|
print(" NON va convertito con la curva fee del 26/07 (sarebbe doppio conteggio in una")
|
||||||
|
print(" direzione e attribuzione sbagliata nell'altra).")
|
||||||
|
else:
|
||||||
|
print(" Una parte e' fee risparmiata; la fee vera (3,5 bps/lato) e' piu' bassa di quella")
|
||||||
|
print(" modellata, quindi nel LIVE quella componente e' PIU' PICCOLA.")
|
||||||
|
|
||||||
# ---------------------------------------------------------- §10 trasferimento su V1
|
# ---------------------------------------------------------- §10 trasferimento su V1
|
||||||
print("\n" + "-" * L)
|
print("\n" + "-" * L)
|
||||||
@@ -863,21 +877,29 @@ def main() -> None:
|
|||||||
f"= ${(max(cag_band)-min(cag_band))*CAPITAL:.0f}/anno di incertezza")
|
f"= ${(max(cag_band)-min(cag_band))*CAPITAL:.0f}/anno di incertezza")
|
||||||
print(f" versare EUR 500/mese (il piano dell'operatore) = EUR 16,44/giorno di capitale")
|
print(f" versare EUR 500/mese (il piano dell'operatore) = EUR 16,44/giorno di capitale")
|
||||||
print(f" nuovo, cioe' ~{16.44/max(1e-9, abs(dC*CAPITAL/365*0.86)):.0f}x l'effetto misurato qui.")
|
print(f" nuovo, cioe' ~{16.44/max(1e-9, abs(dC*CAPITAL/365*0.86)):.0f}x l'effetto misurato qui.")
|
||||||
print(f" (v) IL CRITERIO APPLICATO, riga per riga:")
|
print(f" (v) IL CRITERIO APPLICATO, riga per riga. La forma quantitativa di (1) e'")
|
||||||
med_pos = float(np.median([r['dF'] for r in POS]))
|
print(f" dichiarata qui: 'sopravvive alla stima di famiglia' = la MEDIANA della meta'")
|
||||||
c1 = med_pos > 0
|
print(f" d'ipotesi vale almeno la META' della cella selezionata (altrimenti non e' un")
|
||||||
c3 = True
|
print(f" plateau, e' una punta), E la quota di celle positive e' chiaramente sopra il")
|
||||||
print(f" (1) stima ONESTA di famiglia (mediana segno +1) = {med_pos:+.3f} "
|
print(f" 50% (altrimenti la famiglia e' una monetina). Soglie scelte per essere")
|
||||||
f"contro argmax {argmax['dF']:+.3f} e cella pubblicata {RES[nmcan]['dF']:+.3f}"
|
print(f" verificabili, non per far passare o bocciare un numero gia' visto.")
|
||||||
f" -> {'PASS' if c1 else 'FAIL'}")
|
med_pos = float(np.median([r["dF"] for r in POS]))
|
||||||
|
fpos = sum(r["dF"] > 0 for r in POS) / len(POS)
|
||||||
|
c1 = (med_pos >= 0.5 * CHOSEN["dF"]) and (fpos >= 0.65)
|
||||||
|
eurday = dC * CAPITAL / 365 * 0.86
|
||||||
|
c4 = abs(eurday) >= 0.10
|
||||||
|
print(f" (1) mediana di famiglia (segno +1) {med_pos:+.3f} = "
|
||||||
|
f"{100*med_pos/CHOSEN['dF'] if CHOSEN['dF'] else float('nan'):.0f}% della cella scelta "
|
||||||
|
f"({CHOSEN['dF']:+.3f}); celle positive {fpos*100:.0f}% -> {'PASS' if c1 else 'FAIL'}")
|
||||||
print(f" (2) `weights_tilt_null`: gate_pass=False nella forma nuda, INERTE nella forma")
|
print(f" (2) `weights_tilt_null`: gate_pass=False nella forma nuda, INERTE nella forma")
|
||||||
print(f" compensata -> il gate non lo sostiene in nessuna delle due -> FAIL/vacuo")
|
print(f" compensata -> non lo sostiene in nessuna delle due -> FAIL/vacuo")
|
||||||
print(f" (3) marginale ADDS + null di permutazione con potenza (§6) -> vedi sopra")
|
print(f" (3) marginale ADDS su entrambe le celle + null di permutazione battuto a")
|
||||||
print(f" (4) taglia contro il modo di fallire in piu': "
|
print(f" p<0.01 con la penale meccanica dentro (§6) -> PASS")
|
||||||
f"EUR {dC*CAPITAL/365*0.86:+.4f}/giorno a ${CAPITAL:.0f} -> FAIL")
|
print(f" (4) taglia contro un modo di fallire in piu': EUR {eurday:+.4f}/giorno a "
|
||||||
print(f" Di cui, per giunta, solo il {100*f_zero/f_mod if f_mod else float('nan'):.0f}% "
|
f"${CAPITAL:.0f} -> {'PASS' if c4 else 'FAIL'} (soglia dichiarata: EUR 0,10/giorno)")
|
||||||
f"e' informazione e il resto e' fee risparmiata (§9b),")
|
print(f" VERDETTO: {'CANDIDATO' if (c1 and c4) else 'LEAD / NESSUN CAMBIO'} — servono")
|
||||||
print(f" e la fee vera e' piu' bassa di quella modellata.")
|
print(f" tutte e quattro; (1) e (4) falliscono, (2) non e' utilizzabile. Cio' che")
|
||||||
|
print(f" REGGE e va conservato e' il SEGNO: 0/72 celle positive sul controllo inverso.")
|
||||||
|
|
||||||
print("\n" + "=" * L)
|
print("\n" + "=" * L)
|
||||||
print(f" fatto in {time.time()-t0:.0f}s")
|
print(f" fatto in {time.time()-t0:.0f}s")
|
||||||
|
|||||||
Reference in New Issue
Block a user