feat(pairs): attiva ETH/BTC 15m flat-skip in PORT06 (BLEND, mezza size)
Origine: gioco "Blind Traders" (100 agenti ciechi su BTC/ETH anonimizzati) -> vincitore = spread ETH/BTC reversion a 15m. Testato sul serio col gate PORT06: non duplicato (corr 1h vs 15m = 0.37), robusto (16/16 celle Sharpe>1), edge NON artefatto delle candele flat ETH 15m (filtrandole resta l'83% dello Sharpe). Percorso live costruito e validato: - pairs_research.pairs_sim_flat: engine generalizzato con exit LIVE-REALIZABLE (arma exit_ready, esce alla 1a barra pulita); regression-lock a pairs_sim. - PairsWorker: flat_skip + exit_ready + rilevamento flat da OHLC (1h byte-exact). - runner: fetch diretto dei timeframe sub-orari + override position_size per-sleeve. - validate_worker_pairs: replay worker == backtest a 15m (8452 vs 8453 trade). - _defs/build_everything: sleeve PR_ETHBTC_15M (mezza size, pos 0.10) -> PORT06 FULL 6.43->7.20, OOS 8.58->9.66, DD giu'. Rischio bilanciato col 1h. - smoke live: Cerbero serve candele 15m fresche; worker ticca. Diari docs/diary/2026-06-09-*. Caveat slippage: mezza size = blend-tilt prudente. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""GATE PORT06 FINALE — ETH/BTC 15m flat-skip, engine canonico pairs_sim_flat.
|
||||
|
||||
Usa pairs_sim_flat(flat_skip=True), cioe' la STESSA semantica live-realizable del
|
||||
PairsWorker (uscita alla prima barra pulita), validata da validate_worker_pairs.
|
||||
Conferma i numeri deployabili: baseline 1h vs SWAP 15m vs BLEND 1h+15m.
|
||||
|
||||
uv run python scripts/analysis/pairs15m_gate_final.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from scripts.analysis.pairs_research import pairs_sim_flat
|
||||
from scripts.analysis.report_families import daily_from
|
||||
from scripts.analysis.pairs15m_port06_gate import (port_metrics, eth_btc_daily, blend,
|
||||
UNIV_1H, POS, LEV)
|
||||
from scripts.portfolios._defs import PORTFOLIOS
|
||||
from src.portfolio.sleeves import all_sleeve_equities
|
||||
|
||||
CFG_15M = dict(n=66, z_in=1.674, z_exit=1.0, max_bars=35)
|
||||
|
||||
|
||||
def main():
|
||||
p = PORTFOLIOS["PORT06"]
|
||||
eq_base = dict(all_sleeve_equities())
|
||||
e1h, _ = eth_btc_daily(UNIV_1H)
|
||||
r15 = pairs_sim_flat("ETH", "BTC", tf="15m", **CFG_15M, flat_skip=True, pos=POS, lev=LEV)
|
||||
e15 = daily_from(r15["eq_ts"], r15["eq_v"])
|
||||
eblend = blend(e1h, e15, 0.5)
|
||||
corr = e1h.pct_change().fillna(0).corr(e15.pct_change().fillna(0))
|
||||
|
||||
print("=" * 92)
|
||||
print(" GATE PORT06 FINALE — ETH/BTC 15m flat-skip (pairs_sim_flat == worker live)")
|
||||
print(f" 15m: {r15['trades']} trade, {r15['n_skip_entry']} ingressi flat saltati | "
|
||||
f"corr 1h vs 15m = {corr:.3f}")
|
||||
print("=" * 92)
|
||||
print(f" {'variante':<18s} | {'FULL Sh':>8s}{'FULL DD%':>9s}{'CAGR':>6s} | {'OOS Sh':>7s}{'OOS DD%':>8s}")
|
||||
print(" " + "-" * 70)
|
||||
res = {}
|
||||
for tag, eth in [("baseline 1h", e1h), ("SWAP 15m-flat", e15), ("BLEND 1h+15m", eblend)]:
|
||||
members = dict(eq_base); members["PR_ETHBTC"] = eth
|
||||
f, o = port_metrics(members, p)
|
||||
res[tag] = (f, o)
|
||||
print(f" {tag:<18s} | {f['sharpe']:>8.2f}{f['dd']:>9.2f}{f['cagr']:>5.0f}%"
|
||||
f" | {o['sharpe']:>7.2f}{o['dd']:>8.2f}")
|
||||
fb, ob = res["baseline 1h"]
|
||||
print("\n Promosso se OOS Sharpe non peggiora E DD<=baseline (PORT06):")
|
||||
for tag in ("SWAP 15m-flat", "BLEND 1h+15m"):
|
||||
f, o = res[tag]
|
||||
ok = o["sharpe"] >= ob["sharpe"] - 0.02 and o["dd"] <= ob["dd"] + 1e-9 \
|
||||
and f["sharpe"] >= fb["sharpe"] - 0.02 and f["dd"] <= fb["dd"] + 1e-9
|
||||
print(f" {tag:<18s}: OOS {ob['sharpe']:.2f}->{o['sharpe']:.2f} DD {ob['dd']:.2f}->{o['dd']:.2f}"
|
||||
f" | FULL {fb['sharpe']:.2f}->{f['sharpe']:.2f} DD {fb['dd']:.2f}->{f['dd']:.2f}"
|
||||
f" => {'PROMOSSO' if ok else 'bocciato'}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user