Files
PythagorasGoal/scripts/research/skyhook/runs/SKH_P_REGIME_plateau.py
T
Adriano Dal Pastro de72e3ce1f feat(skyhook): SKH01-V2-DD — asymmetric %-exits cut standalone DD <30% (2-wave agent research)
Second agent wave (skyhook-improve-v2, 14 DD-reduction families, each adversarially
verified by 2 skeptics) beats the prior winner on the only unmet goal (DD<30%).

Winner = ASYM_LS -> promoted to engine as SKH01_V2_DD:
  same signal (ptn_n=45, vola[35,95], vol_lo=0, exit-bars 24/16) but exits switched
  from ATR to FIXED-PCT ASYMMETRIC — long sl4%/tp10%, short sl2%(tighter)/tp8%.
  The tight short %-SL caps the per-trade loss that forms the maxDD in vol spikes.

Verified (sk.study, independent re-run): standalone maxDD BTC 21.4% / ETH 27.4% (<30%),
minFull +0.99, minHold +1.26, causality 0/400 both assets, fee-surviving to 0.40%RT,
marginal vs TP01 ADDS (corr 0.09, in-sample edge, robust_oos, multicut, clean-year +0.57),
blend 0.75*TP01+0.25*SKH uplift_hold +0.87; blend 50/50 full 1.84/hold 1.59/DD 10.7%.
Plateau (not knife-edge); both skeptics holds_up=high, killer=null.

Engine: per-direction short exit overrides (exit_mode_short/sl_*_short/tp_*_short),
backward-compatible (None -> symmetric, V1/intermediate-winner unchanged). +3 tests (8/8 pass).

Lessons: DD is cut by changing the exit MECHANISM (%-SL, L/S asymmetry, ensembles), NOT by
entry-only kill-switch / vol-target / cadence. PATTERN_CONF killed as overfit (knife-edge).
PCTL_DD unverified (rate-limit) and ENS_PARAM/TPSL_DD recency/hedge-loaded -> forward-monitor.
NOT yet wired to live sleeves: re-verify blend@0.25 + causality on execution code before deploy.

Includes both waves' research scripts (runs/SKH_* wave 1, runs/SKH2_* wave 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:10:38 +00:00

47 lines
1.6 KiB
Python

"""SKH_P_REGIME_plateau — tight plateau probe around the sweep winner
vola_lo=20, vola_hi=88, vol_lo=55, vol_hi=80 (V1 base: ptn_n=55, sl_atr=2.5, tp_atr=6.0).
Confirm neighbors in ALL 4 band dims are also good (no knife-edge).
"""
from __future__ import annotations
import sys
sys.path.insert(0, "/opt/docker/PythagorasGoal/scripts/research/skyhook")
import skyhooklib as sk
from src.strategies.skyhook import SkyhookParams
ASSETS = ("BTC", "ETH")
BASE = dict(ptn_n=55, sl_atr=2.5, tp_atr=6.0)
WIN = dict(vola_lo=20, vola_hi=88, vol_lo=55, vol_hi=80)
def ev(**bands):
p = SkyhookParams(**{**BASE, **bands})
res = {a: sk.run_asset(a, p, sk.FEE_RT) for a in ASSETS}
mf = min(res[a]["full"]["sharpe"] for a in ASSETS)
mh = min(res[a]["holdout"]["sharpe"] for a in ASSETS)
tr = min(res[a]["full"]["n_trades"] for a in ASSETS)
dd = max(res[a]["full"]["maxdd"] for a in ASSETS)
return mf, mh, tr, dd
def probe(dim, values):
print(f"\n-- perturb {dim} (others at winner) --")
for v in values:
bands = dict(WIN); bands[dim] = v
mf, mh, tr, dd = ev(**bands)
mark = " <-- WIN" if v == WIN[dim] else ""
print(f" {dim}={v:>4}: minF={mf:+.2f} minH={mh:+.2f} tr={tr:>3} DD={dd*100:.0f}%{mark}")
def main():
mf, mh, tr, dd = ev(**WIN)
print(f"WINNER {WIN}: minF={mf:+.2f} minH={mh:+.2f} tr={tr} DD={dd*100:.0f}%")
probe("vola_lo", [15, 20, 25, 30])
probe("vola_hi", [83, 85, 88, 90, 92])
probe("vol_lo", [45, 50, 55, 60, 65])
probe("vol_hi", [75, 78, 80, 82, 85])
if __name__ == "__main__":
main()