diff --git a/CLAUDE.md b/CLAUDE.md index 4d1a1ec..2c1c05e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5882,6 +5882,47 @@ immer nahe 1 und sagen nichts über Vorlauf. unsichtbar. Praktisch aber irrelevant — bei 1-s-Poll, WireGuard und Market-Order ist er nicht ausbeutbar, und die Asymmetrie bei ±1 zeigt die Richtung bereits. +### ⚠⚠ ORDERBUCH FÜR DIE EMPFEHLUNG? NEIN — ES IST REAKTIV, NICHT PRÄDIKTIV (`analyze_orderbook_pred.py`, 2026-08-17) + +User-Frage. Neu gerechnet auf **196.720 Buch-Schnappschüssen / 17,4 Tagen** mit +dem MT5-Kurs in derselben Zeile (64 % davon bei lebendem Broker verwertbar). +Merkmale `imb1`/`imb5`/`imb20`, Horizonte 60 s und 300 s, Quintile **je Hälfte**, +**nicht überlappende** Fenster, 95-%-Bootstrap. + +**Ergebnis: alle 12 Zellen haben ein Intervall, das die Null enthält.** Keine +Vorhersagekraft belegt. + +⚠⚠ **DER AUFSCHLUSSREICHE TEIL IST DIE RÜCKWÄRTS-KONTROLLE.** Berichtet wird +neben der künftigen auch die **vergangene** MT5-Bewegung je Quintil — in **10 von +12 Zellen ist die RÜCKWÄRTS-Spanne grösser als die vorwärts:** +| Merkmal · Horizont | vorwärts | **rückwärts** | +|---|---|---| +| imb1 · 60 s (H1/H2) | −0,05 / +0,08 bp | **+0,72 / +0,50** | +| imb1 · 300 s (H1/H2) | +0,06 / −0,91 | **+1,31 / +1,73** | +| imb5 · 60 s (H1/H2) | −0,09 / +0,10 | **+0,53 / +0,78** | +| imb20 · 60 s (H1/H2) | +0,05 / +0,06 | **+0,63 / +0,65** | +**Das Buch spiegelt die Bewegung, die auf Pepperstone SCHON PASSIERT ist** — es +ist reaktiv. Die beiden Ausnahmen (imb5/imb20 · 300 s · H1) reproduzieren in H2 +nicht (dort +0,44 gegen rückwärts +1,83). +✅ **Damit passt es exakt zum Lead-Lag-Befund vom selben Tag:** Pepperstone führt +HL um ~6 s (r(k=−1)=+0,455 gegen r(k=+1)=+0,020). Ein Orderbuch, dessen Börse +hinterherläuft, kann den Broker nicht vorhersagen — der Befund ist damit nicht +nur gemessen, sondern **mechanistisch erklärt**. + +⚠ **Und die ökonomische Hürde entscheidet ohnehin:** die grösste +Vorwärts-Spanne über alle Zellen ist **+1,63 bp**, der Pepperstone-Spread liegt +bei **~2,7 bp**. Selbst die beste Zelle — statistisch nicht von null zu trennen +und in der anderen Hälfte nicht reproduziert — läge **unter** den Kosten. + +✅ **URTEIL: Das Orderbuch taugt nicht für die Empfehlung.** Das bestätigt +unabhängig die Entmachtung des Verdict-Moduls „Orderbuch" am 06.08. (Gewicht +0,5 → 0, über 2.688 Episoden beidhälftig negativ) — damals aus der +Verdict-Telemetrie, jetzt aus den Rohdaten der Quelle selbst. +⚠ **Grenzen, ehrlich:** nach der Entkopplung bleiben bei 300 s nur 1.252/1.254 +Fälle, die Intervalle sind entsprechend breit; gemessen wurde die **Imbalance**, +nicht die Wände (deren Preis-Zuordnung bräuchte die Basis-Korrektur und wäre +damit zirkulär); und 17,4 Tage sind EIN Regime. + ### ✅ S/R-AUTO-CLOSE WIEDER AN (User-Entscheidung 2026-08-11) Frage war: „sollten wir Trades bei einem S/R-Bounce automatisch schliessen?" diff --git a/analyze_orderbook_pred.py b/analyze_orderbook_pred.py new file mode 100644 index 0000000..737d5a3 --- /dev/null +++ b/analyze_orderbook_pred.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +"""Sagt das Hyperliquid-ORDERBUCH den Pepperstone-Kurs vorher? (User 2026-08-17) + +Im Projekt ist das Verdict-Modul „Orderbuch" am 06.08. entmachtet worden (ueber +2.688 Episoden beidhaelftig NEGATIV, 49 % Treffer). Hier wird die Frage neu und +sauber gestellt — auf **196.712 Buch-Schnappschuessen / 17,4 Tagen**, mit dem +MT5-Kurs in derselben Zeile. + +⚠⚠ DER ENTSCHEIDENDE KONTROLLTEST (heute erst moeglich): am 17.08. wurde +gemessen, dass **Pepperstone dem HL-Kurs VORAUSLAEUFT** (r(k=-1)=+0,455 gegen +r(k=+1)=+0,020). Ein Orderbuch-Signal, das nur die BEREITS GESCHEHENE +Pepperstone-Bewegung spiegelt, sieht in einer naiven Auswertung praediktiv aus. +Deshalb wird hier IMMER beides berichtet: + RUECKWAERTS = Zusammenhang mit der VERGANGENEN MT5-Bewegung (reaktiv?) + VORWAERTS = Zusammenhang mit der KUENFTIGEN (praediktiv?) +Nur wenn vorwaerts deutlich mehr steht als rueckwaerts, ist es Vorhersage. + +WEITERE FALLEN, alle behandelt: + · **Geschlossener Broker** (~1/3 der Zeit) muss raus — sonst ist die kuenftige + Rendite strukturell 0 und alles sieht „stabil" aus. + · **Ueberlappende Fenster**: bei 6-s-Abtastung und 300-s-Horizont teilen sich + 50 Beobachtungen dasselbe Fenster. Das effektive n ist ~n/50 — genau der + Fehler, der am 07.08. elf Hypothesen ausgeloest hat. -> nicht ueberlappend. + · **Quintile je HAELFTE** bilden, nicht global — sonst ist die Bucket-Zugehoerig- + keit mit der Zeit konfundiert (die Lehre aus `analyze_hl_funding.py`). + · **Oekonomische Huerde**: Pepperstone-Spread ~0,0225 $ auf ~82 $ = **~2,7 bp**. + Alles darunter ist von den Kosten gefressen, egal wie sauber es aussieht. + +Aufruf: python analyze_orderbook_pred.py +""" +from __future__ import annotations + +import math +import random +import sqlite3 + +DB = r"C:\Users\ah\Downloads\HyperLiquid-WTI Trader\orderflow.db" +_LEBT_S = 180.0 +_SPREAD_BP = 2.7 +_MERKMALE = ("imb1", "imb5", "imb20") + + +def lade(): + db = sqlite3.connect(DB) + sp = ",".join(_MERKMALE) + rows = db.execute( + f"SELECT ts,{sp},wall_bid_sz,wall_ask_sz,mt5_mid FROM book " + "WHERE mt5_mid>0 ORDER BY ts").fetchall() + letzte, vor, out = None, None, [] + for r in rows: + mt = r[-1] + if vor is None or mt != vor: + letzte = r[0] + vor = mt + if letzte is not None and (r[0] - letzte) <= _LEBT_S: + out.append(r) + return rows, out + + +def ci_mittel(xs, n=2000, seed=13): + if len(xs) < 20: + return None, None + r = random.Random(seed); m = len(xs) + b = sorted(sum(xs[r.randrange(m)] for _ in range(m)) / m for _ in range(n)) + return b[int(.025 * n)], b[int(.975 * n)] + + +def stichprobe(rows, idx, schritt, zurueck): + """NICHT ueberlappende Faelle: (merkmal, rendite_vorwaerts_bp, + rendite_rueckwaerts_bp). `schritt` = Beobachtungen je Horizont.""" + out = [] + for i in range(zurueck, len(rows) - schritt, schritt): + # Luecken-Schutz: die Zeitspanne muss zum Horizont passen + if rows[i + schritt][0] - rows[i][0] > schritt * 20: + continue + if rows[i][0] - rows[i - zurueck][0] > zurueck * 20: + continue + m0, m1, mv = rows[i][-1], rows[i + schritt][-1], rows[i - zurueck][-1] + if m0 <= 0 or mv <= 0: + continue + x = rows[i][idx] + if x is None: + continue + out.append((x, (m1 - m0) / m0 * 1e4, (m0 - mv) / mv * 1e4)) + return out + + +def quintile(paare, feld): + """Quintile JE Stichprobe (nicht global) — sonst Zeit-Konfundierung.""" + s = sorted(paare, key=lambda x: x[0]) + k = max(1, len(s) // 5) + return [s[i * k:(i + 1) * k] for i in range(5)] + + +def main(): + alle, rows = lade() + print(f"\n {len(alle)} Buch-Schnappschuesse · bei LEBENDEM Broker verwertbar: " + f"{len(rows)} ({100*len(rows)/len(alle):.0f} %)") + print(f" Abtastung ~6 s · oekonomische Huerde: Spread ~{_SPREAD_BP} bp\n") + mid = len(rows) // 2 + haelften = (("H1", rows[:mid]), ("H2", rows[mid:])) + + for mi, name in enumerate(_MERKMALE, start=1): + print(f" ══ MERKMAL {name} " + "═" * 52) + for hor_s, schritt in ((60, 10), (300, 50)): + print(f" Horizont {hor_s} s (nicht ueberlappend, {schritt} Beob.)") + for lbl, teil in haelften: + pa = stichprobe(teil, mi, schritt, schritt) + if len(pa) < 100: + print(f" {lbl}: zu wenige Faelle ({len(pa)})"); continue + qs = quintile(pa, mi) + unten, oben = qs[0], qs[-1] + mv_u = sum(p[1] for p in unten) / len(unten) + mv_o = sum(p[1] for p in oben) / len(oben) + # RUECKWAERTS-Kontrolle: reagiert das Buch nur auf Vergangenes? + rb_u = sum(p[2] for p in unten) / len(unten) + rb_o = sum(p[2] for p in oben) / len(oben) + dif = [p[1] for p in oben] + [-p[1] for p in unten] + lo, hi = ci_mittel(dif) + spanne = (mv_o - mv_u) / 2 + sig = ("⚠ KI enthaelt 0" if lo is None or (lo <= 0 <= hi) + else ("✅" if lo > 0 else "❌ invers")) + print(f" {lbl} n={len(pa):>5} " + f"VORWAERTS unten {mv_u:>+6.2f} / oben {mv_o:>+6.2f} bp " + f"→ Spanne {spanne:>+5.2f} bp " + f"[{lo:+.2f} … {hi:+.2f}] {sig}") + print(f" RUECKWAERTS (Kontrolle) unten {rb_u:>+6.2f} / " + f"oben {rb_o:>+6.2f} bp → Spanne {(rb_o-rb_u)/2:>+5.2f} bp") + print() + + print(" ── LESEHILFE ──────────────────────────────────────────────────") + print(" · „Spanne\" = halber Abstand zwischen oberstem und unterstem") + print(" Imbalance-Quintil, in Basispunkten. Das ist das, was ein") + print(" Handelssignal maximal einbringen koennte.") + print(f" · Sie muss den Spread von ~{_SPREAD_BP} bp SCHLAGEN, nicht nur > 0 sein.") + print(" · Ist die RUECKWAERTS-Spanne aehnlich gross oder groesser, spiegelt") + print(" das Buch nur die schon geschehene Bewegung — dann ist es") + print(" REAKTIV, nicht praediktiv (Pepperstone fuehrt HL, s. 17.08.).") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())