feat(skyhook): pos_fn introspection for SKH01 sleeve (current open trade / flat)

_skyhook_positions(): replays the non-overlap entry+exit logic (TP/SL/max_bars) to the last
closed 230m bar and reports, per asset, the current OPEN trade (dir/entry/sl/tp/bars_in) or
'flat'. Wired into skyhook_sleeve(pos_fn=...) so the Deribit book report & web dashboard show
Skyhook's live position. Causal (closed bars only). +1 test. Currently flat/flat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-23 20:32:14 +00:00
parent 160ad300be
commit 384b9cb0af
2 changed files with 44 additions and 1 deletions
+34 -1
View File
@@ -236,8 +236,41 @@ def _skyhook_returns() -> pd.Series:
return pd.Series(0.5 * J["BTC"].values + 0.5 * J["ETH"].values, index=J.index)
def _skyhook_positions() -> dict:
"""Stato corrente del book Skyhook per asset (introspezione live): se c'e' un trade APERTO ORA
-> dir/entry/sl/tp/barre-trascorse; altrimenti 'flat'. Replica la logica non-overlap di
entry+exit (TP/SL/max_bars) fino all'ultima barra 230m chiusa. Causale: usa solo barre chiuse."""
out = {}
for a in ASSETS:
ltf, htf = build_frames(load_data(a, "5m"))
ent = skyhook_entries(ltf, htf, SKH01_V2_DD)
H = ltf["high"].values; L = ltf["low"].values; Cc = ltf["close"].values
n = len(ltf); i = 0; open_pos = "flat"
while i < n:
e = ent[i]
if e is None:
i += 1; continue
d, sl, tp, mb = e["dir"], e["sl"], e["tp"], e["max_bars"]
exit_idx = None
for s in range(1, mb + 1):
j = i + s
if j >= n: # non ancora uscito: posizione APERTA ora
break
hit = (L[j] <= sl or H[j] >= tp) if d == 1 else (H[j] >= sl or L[j] <= tp)
if hit or s == mb:
exit_idx = j; break
if exit_idx is None:
open_pos = dict(dir="LONG" if d == 1 else "SHORT", entry=round(float(Cc[i]), 2),
sl=round(float(sl), 2), tp=round(float(tp), 2),
bars_in=int((n - 1) - i), max_bars=int(mb))
break
i = exit_idx + 1
out[a] = open_pos
return out
def skyhook_sleeve(weight: float = 0.25) -> Sleeve:
return Sleeve("SKH01_skyhook", weight, _skyhook_returns)
return Sleeve("SKH01_skyhook", weight, _skyhook_returns, pos_fn=_skyhook_positions)
# ----------------------------- REGISTRY -----------------------------