Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.1 KiB
2026-06-23 — SKH01 "Skyhook": porting onesto del sistema ES dual-timeframe su BTC/ETH
Branch: strategy_skyhook. Engine: src/strategies/skyhook.py. Harness: scripts/research/skyhook/skyhooklib.py.
Test: tests/test_skyhook.py (5 pass). Ricerca: scripts/research/skyhook/{sweep,grid,check_v1}.py + runs/.
Il brief
Sistema "Skyhook" (origine ES / E-mini S&P, genetico, a doppio timeframe), da portare su crypto:
- data2 = 690 min (segnale), data1 = 230 min (esecuzione). NB 690 = 3 × 230.
- NON trend-follower: entra solo quando coincidono (a) un regime di volatilità/volume e (b) un pattern di breakout.
- Pipeline per barra: indicatori (BuzVola su ATR, BuzVolume su volume, tipo-Chande 0-100) → fasce regime → pattern (Donchian/breakout su data2) → composer (regime AND pattern) → ingresso (max 1/giorno, stop-and-reverse) → uscite (time-based asimmetrico uscitalong=24 / uscitashort=18 + stop/profit).
- Ancore demo: trend lineare → BuzVola=50 (vol steady → neutro), BuzVolume=100 (volume in rampa).
Ricostruzione (fedele + onesta)
- Resample dal feed 5m certificato con
origin='epoch': 230 min = 46×5m, 690 min = 138×5m, e i confini 690 sono un sottoinsieme dei confini 230 → una barra HTF chiude esattamente su una chiusura LTF. Merge HTF→LTF causale:merge_asofbackward sulla chiusura HTF (≤ chiusura LTF), così una barra HTF è usata solo quando è davvero chiusa. (~2287 barre/anno LTF, ~762 HTF.) - BuzVola / BuzVolume =
chande01(Chande Momentum Oscillator normalizzato 0-100): serie steady → 50, rampa-su → 100, rampa-giù → 0. Le ancore demo sono soddisfatte a livello di indicatore (è la lettura fedele: "vol steady → neutro"). NB: l'EMA-ATR su un linspace sintetico dà 100 per drift di warm-up/floating-point, non per comportamento reale — su BTC reale BuzVola oscilla intorno a 50 (EMA-ATR vs SMA-ATR corr 0.90). - Pattern = Donchian breakout leak-free (shift(1)) su HTF,
ptn_nbarre (default 13 da 13/13/1). - Regime = bande-soglia tunabili su BuzVola/BuzVolume (i magici interi 4/3/2 - 4/2/2 non sono
nel brief; ricostruiti come
[vola_lo,vola_hi]×[vol_lo,vol_hi]). - Composer = regime AND pattern. Ingressi ≤1/giorno (prima barra qualificante).
- Uscite: time-based asimmetrico (
uscitalong/uscitashortbarre LTF) + hard stop/profit. Lo "stop 2000 / profit 5000" in $ del sistema ES → multipli di ATR LTF (scale-free): defaultsl_atr=2.0,tp_atr=5.0(~ rapporto 40:100 pt ES), con modalitàpctalternativa. - Engine espresso come entries
{dir,tp,sl,max_bars}perbacktest_signals(motore onesto del progetto: TP/SL intrabar, max_bars, non-overlap). Causalità verificata con prefix-recompute (0 mismatch).
Baseline → V1 (lever scout + grid, inline, veloce)
- Baseline (default 13/13, sl2/tp5, vola[35,95], vol_lo50): causale, fee-surviving, FULL Sharpe BTC +0.91 / ETH +0.64, ma HOLD-OUT debole (BTC −0.09 / ETH +0.17) → FAIL del gate onesto.
- Lever scout (
sweep.py): gli short servono (long_only → HOLD −0.52); il regime gate conta (togliere la banda vola → HOLD −0.80); il floor di volume a 50 frenava l'hold-out (vol_lo=40 o 0 → PASS); breakout più lento (ptn_n=55) e stop più larghi (sl2.5/tp6) alzano l'hold-out. - Grid combinato (
grid.py): vincitrice SKH01-V1SkyhookParams(ptn_n=55, sl_atr=2.5, tp_atr=6.0, vola_lo=35, vola_hi=95, vol_lo=0.0):- min-asset FULL +0.69, HOLD-OUT +0.64 (BTC 0.64 / ETH 0.64), PASS, fee-surviving a 0.30%RT.
- BTC FULL +0.69/+275% DD49% ; ETH FULL +1.01/+871% DD31% ; entrambi HOLD-OUT positivi.
- Marginal vs TP01 = ADDS e regge i gate induriti: corr 0.06 (ortogonale, NON trend-beta),
has_insample_edge=True(Sharpe in-sample standalone 1.15),is_hedge=False, multi-cut persistente. Blend 0.75·TP01 + 0.25·SKH01: HOLD Sharpe 0.31 → 0.74 (+0.44), DD 11.9%; blend 50/50 HOLD 0.88, DD 17.8%. - Unico sub-gate fallito:
clean_year_uplift+0.014 (sotto 0.02) →earns_slot=Falseper un pelo, nonostante tutto il resto sia forte. Debolezza principale: DD standalone alto (40-49%).
→ SKH01 è un diversificatore quasi-ortogonale reale (non un TP01 travestito): da solo è volatile, ma come sleeve al 25% migliora moltissimo l'hold-out del portafoglio a DD bassissimo.
Onda multi-agente (30 agenti + verifica avversariale) — vedi sotto
[Sintesi in aggiornamento al termine del workflow skyhook-improve: obiettivi = battere V1
sull'hold-out, tagliare il DD <30%, e portare earns_slot=True. Famiglie: param (RR, ptn_n,
regime bands, exit bars, chande, local), regime-redef (percentile, realized-vol, vol-expansion,
LTF, stochastic, volume-z), pattern (confirmation, range-expansion, ROC, Keltner, NR, dual),
exit (trailing/chandelier, breakeven, R-multiple, regime-stop, time-only), sizing/overlay
(vol-target, trend-filter, asimmetria L/S, DVOL gate, DD kill-switch, day-of-week). Ogni
candidato passato per 2 scettici avversariali (window-luck/jackknife + causalità/fee/plateau).]