Hyperliquid geprueft: Orderbuch-Stimme raus, Funding gemessen (traegt nicht),

Kontext in die Meldungen (v=145)

Direkt gegen die HL-API geprueft statt aus dem Code geschlossen.

ANGEBOT: 4 Oel-Maerkte (2 liquide: xyz:CL OI 3,07 Mio, xyz:BRENTOIL 2,25 Mio),
je Markt mark/oracle/funding/open_interest/day_volume + l2Book (20 Level je
Seite). Historie: fundingHistory 5.095 Stundenwerte ueber 7 Monate inkl.
premium. Open Interest hat KEINE Historie -> waere sammelpflichtig.

Netz-Frage geklaert: config sagt testnet (leeres Buch, 0 Bids/0 Asks), aber es
sind zwei Schalter — [hyperliquid] network steuert das Handeln (aus),
[sim] price_network die Daten (mainnet, live bestaetigt).

(1) Mehr Orderbuch-Daten: NEIN. Zweimal unabhaengig gemessen — bookflow_report
    0,2-1,0 bp gegen eine ~3-bp-Schwelle und KIPPT; Lead-Lag: Pepperstone
    fuehrt, HL trifft nach 6 s zu 51 %.
(2) Modul "Orderbuch" Gewicht 0,5 -> 0. Ueber 2.688 Episoden beidhaelftig
    negativ (-0,054/-0,066, 49 % Treffer). Chip bleibt.
(3) analyze_hl_funding.py: Funding/Premium gegen den CFD, 2 Haelften.
    ⚠ Der erste Lauf meldete mehrere "robuste" Buckets und war FALSCH —
    ueberlappende Forward-Fenster (aus n=506 werden ~21 unabhaengige Faelle)
    und global gebildete Quintile (Bucket mit der Zeit konfundiert). Dass
    Funding- und Premium-Tabelle fast identisch waren, war der dritte Hinweis:
    HL rechnet das Funding aus dem Premium. Entueberlappt haelt kein Bucket.
(4) hl_ctx in den Meldungen (#hl-note) als reine Anzeige.
    ⚠ Zwei Bau-Fallen behoben: der Aufruf erbte den 2-s-Timeout der Waende und
    lief still ins Leere (braucht real 7,2 s), und er haette den Trend-Loop
    blockiert -> Daemon-Thread wie beim Wirtschaftskalender.

Live verifiziert: hl_ctx befuellt, Orderbuch weight=0 bei erhaltenem Chip,
v=145 ausgeliefert, eine Instanz auf Port 8000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-06 23:38:01 +02:00
co-authored by Claude Opus 5
parent 874ee16e00
commit 2cdd1ba0e8
7 changed files with 375 additions and 4 deletions
+58
View File
@@ -33,6 +33,12 @@ log = get_logger("hlwalls")
_TIMEOUT_S = 2.0 # der MT5-Loop darf nicht am HTTP hängen
_TTL_S = 10.0 # Cache — die Wände wandern langsamer als der Export-Takt (~5 s)
_MARKET_TTL_S = 300.0 # Funding/OI aendern sich stuendlich — 5 min genuegt
# ⚠ EIGENER, laengerer Timeout: `/api/market` fragt die HL-API live nach ALLEN
# Oel-Maerkten (4 Stueck) und braucht deutlich laenger als der Waende-Endpunkt,
# der aus einer lokalen DB liest. Mit dem kurzen Waende-Timeout lief der Aufruf
# immer ins Leere — und der stille `except` machte daraus ein wortloses None.
_MARKET_TIMEOUT_S = 12.0
_MAX_AGE_S = 60.0 # älter = HL-Feed steht → nicht mehr zeichnen
_STALE_GRACE_S = 120.0 # nach einem Fehlschlag den letzten guten Stand so lange
# weiterreichen (Blink-Fix — s. Kommentar in `walls()`)
@@ -47,6 +53,58 @@ class HLWalls:
self._cache: dict | None = None
self._cache_ts = 0.0
self._fail_logged = False
self._mkt_cache: dict | None = None
self._mkt_ts = 0.0
def market(self) -> dict | None:
"""HL-KONTEXT je Oel-Markt: Funding, Open Interest, Oracle-Premium.
⚠⚠ REINE ANZEIGE — kein Verdict-Gewicht, kein Trade-Trigger. Gemessen
(`analyze_hl_funding.py`, 2026-08-06, 5.095 Funding-Stundenwerte ueber
7 Monate gegen den Pepperstone-CFD): **entueberlappt haelt KEIN Bucket**
die 2-Stichproben-Regel. Der erste Lauf sah nach mehreren robusten
Effekten aus — das war Autokorrelation (stuendliche Beobachtungen,
4/12/24-h-Fenster teilen sich fast ihre ganze Laenge).
Deshalb steht das hier als Kontext in den Meldungen und NICHT in der
Empfehlung.
Quelle ist das LOKALE Dashboard (Port 8001), nicht die HL-API direkt —
keine neue externe Abhaengigkeit im Trading-Bot. Eigene, laengere
Drosselung (5 min): Funding aendert sich stuendlich, das braucht nicht
den 5-s-Takt der Waende. Fail-safe: bei Fehlern None.
"""
if not self.enabled:
return None
now = time.time()
with self._lock:
if (self._mkt_cache is not None
and now - self._mkt_ts < _MARKET_TTL_S):
return self._mkt_cache
aus = None
try:
url = self.url.replace("/api/walls", "/api/market")
with urllib.request.urlopen(url, timeout=_MARKET_TIMEOUT_S) as r:
d = json.loads(r.read().decode())
if d.get("ok"):
for m in (d.get("markets") or []):
# Nur der Markt, aus dem auch die Waende kommen.
if m.get("market") != "xyz:CL":
continue
mark, orac = m.get("mark_px"), m.get("oracle_px")
aus = {"funding": m.get("funding"),
"open_interest": m.get("open_interest"),
"mark": mark, "oracle": orac,
"premium": (float(mark) - float(orac))
if (mark and orac) else None,
"day_volume": m.get("day_volume"),
"network": d.get("network")}
break
except Exception:
aus = None # still — Kontext darf nie stoeren
with self._lock:
if aus is not None:
self._mkt_cache, self._mkt_ts = aus, now
return self._mkt_cache
def walls(self) -> dict | None:
"""{'bid','bid_sz','ask','ask_sz','basis','imb5'} auf MT5-Preisniveau —