Hyperliquid-Kurs neben dem Broker-Kurs + G/V-Schaetzung bei geschlossenem Markt
User: "wenn Pepperstone closed ist trotzdem Kurs und Liquiditaet von
Hyperliquid einbinden" -> nachgeschaerft zu "blende den HL-Kurs NEBEN den
Pepperstone-Kurs ein" (ehrlicher als ein stiller Tausch) -> plus "bei
geschlossenem Markt auch den G/V mit HL berechnen".
Snapshot: hl_live {mid_mt5, hl_mid, basis, age_s, bid/ask, bid_sz/ask_sz,
imb5, trend, slope_per_h, vs_mt5} - IMMER befuellt. mid_mt5 = HL-Mid +
gemessene Basis, also direkt mit dem Broker-Kurs vergleichbar. Dazu
market_closed, tick_age_s, pnl_hl.
core/hl_walls.py liefert jetzt zusaetzlich hl_mid/mid_mt5/age_s.
Dashboard v=129: eigene Header-Box "HL" neben KURS mit Tooltip (Rohkurs,
Basis, Alter, Abweichung). Bei geschlossenem Markt: Label "KURS · ZU",
Session-Zeile "MARKT ZU", und das G/V wechselt auf die HL-Schaetzung, mit
"≈" markiert.
MT5 v1.34: HL;<mt5_aequiv>;<alter>;<bid>;<ask>;<U|D|-> -> bernsteinfarbenes
Label unter Kurs und G/V (InpShowHL/InpHLColor).
DREI SACKGASSEN dokumentiert, damit sie niemand wiederholt:
1) tick_local_ts ist die ABHOLZEIT, nicht das Tick-Alter.
2) tick_server_ts minus _broker_offset_s() ist ZIRKULAER - die
Offset-Funktion leitet den Versatz selbst aus dem letzten Tick ab und
misst bei geschlossenem Markt die Veraltung (-7,41 h statt +3 h); das
Alter hebt sich auf (-347 s).
3) pnl / Kursbewegung als EUR-je-Punkt ergab 155 statt ~86, weil
trader.pnl den Wochenend-Swap enthaelt.
Verwendet wird stattdessen: Markt zu = der Kurs hat sich seit 180 s nicht
BEWEGT (_last_bid/_last_bid_move_ts). Und der G/V nutzt die vorhandene,
korrekte trader.live_pnl(bid, ask) mit dem HL-Kurs +- halbem Spread.
Live verifiziert: market_closed=True nach 198 s, Broker 86.333 eingefroren,
HL 86.349 (7 s alt), Broker-P&L -15,02 -> HL-Schaetzung -14,37 EUR.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
35f9b567c8
commit
7427c36922
+104
@@ -81,6 +81,9 @@ _SQUEEZE_REENTRY_COOLDOWN_S = 180.0 # nach JEDEM Close eines Trades (Notfall/SL
|
||||
# gegen die Open→Instant-Close-Kaskade bei zu engem Stop
|
||||
# (real 2026-07-27 15:39: −3-€-Stop killte Entry #1 in 16 s,
|
||||
# Squeeze noch aktiv → sofortiger Re-Entry; 2026-07-28)
|
||||
_TICK_STALE_S = 180 # kein Tick seit X s → Markt gilt als geschlossen.
|
||||
# Absichtlich tick-basiert statt kalenderbasiert: deckt
|
||||
# Wochenende, Feiertage UND Broker-Ausfall mit einer Regel.
|
||||
_TRADE_MARKS = 6 # so viele letzte Trades im MQL5-Chart markieren
|
||||
# (Kerze umranden: Eröffnung hellgrün, Close dunkelgrün)
|
||||
_STARTUP_GRACE_S = 60.0 # nach Bot-Start schließt der Bot 60 s lang KEINEN
|
||||
@@ -321,6 +324,10 @@ class TradingEngine:
|
||||
self._open_pos_dir = None # Richtung der aktuell offenen Position (LONG/SHORT)
|
||||
self._pos_close_ts = 0.0 # Zeit + Richtung des letzten Positions-Close (JEDE
|
||||
self._news_block_logged = None # Dedup für die News-Blackout-Logzeile
|
||||
# Markt-zu-Erkennung über die letzte KURSBEWEGUNG (s. `snapshot`) — die
|
||||
# Tick-Zeitstempel taugen dafür nicht (Abholzeit bzw. zirkulärer Offset).
|
||||
self._last_bid = None
|
||||
self._last_bid_move_ts = 0.0
|
||||
# Auto-Flip-Close (User-Wunsch 2026-07-31) — ⚠ GEMESSEN NEGATIV in beiden
|
||||
# Hälften (`backtest_flipclose2.py`), s. `_check_flip_close`. Default-Schwelle
|
||||
# 0,5×ATR = die mildeste der gemessenen Varianten.
|
||||
@@ -2367,6 +2374,20 @@ class TradingEngine:
|
||||
f"Konsens {_b:+.2f}")
|
||||
except Exception:
|
||||
pass
|
||||
# ── HYPERLIQUID-ERSATZKURS bei geschlossenem Markt (User 2026-08-01):
|
||||
# HL;<mt5_aequivalent>;<alter_s>;<bid>;<ask>;<trend U|D|-> — der Indikator
|
||||
# zeigt ihn UNTER dem (eingefrorenen) MT5-Kurs, sobald kein Tick mehr
|
||||
# kommt. HL (`xyz:CL`) handelt 24/7, Pepperstone nicht; ohne das sieht man
|
||||
# am Wochenende einen Freitags-Kurs und merkt es nicht.
|
||||
try:
|
||||
_w = self.hl_walls.walls()
|
||||
if _w and _w.get("mid_mt5") is not None:
|
||||
_tr = (_w.get("trend") or {}).get("dir")
|
||||
lines.append(f"HL;{_w['mid_mt5']:.3f};{float(_w.get('age_s') or 0):.0f};"
|
||||
f"{_w.get('bid')};{_w.get('ask')};"
|
||||
f"{'U' if _tr == 'up' else 'D' if _tr == 'down' else '-'}")
|
||||
except Exception:
|
||||
pass
|
||||
# G/V der offenen Position, direkt unter dem Kurs (User-Wunsch 2026-07-30):
|
||||
# PL;wert;waehrung. **NETTO** wie im Dashboard — bei Gewinn abzüglich der
|
||||
# WHT-Quellensteuer, die der Broker einbehält (`[trading] wht_pct`); bei
|
||||
@@ -2999,6 +3020,74 @@ class TradingEngine:
|
||||
stop_approach = self._stop_approach_hint(market, position, wave_snap)
|
||||
# einmal holen — Verdict-Stimme UND Snapshot-Feld nutzen dasselbe Objekt
|
||||
_pat_snap = self.patterns.snapshot()
|
||||
# ── Marktstatus + Hyperliquid-Kurs (User 2026-08-01) ─────────────────
|
||||
# ⚠ ZWEI Sackgassen bei der Markt-zu-Erkennung, beide verworfen:
|
||||
# (1) `tick_local_ts` ist die lokale ABHOLZEIT — erneuert sich bei jedem
|
||||
# Abruf, auch wenn der Broker denselben alten Tick liefert.
|
||||
# (2) `tick_server_ts` minus `trader._broker_offset_s()` ist ZIRKULÄR: die
|
||||
# Offset-Funktion leitet den Zeitzonen-Versatz selbst aus dem letzten
|
||||
# Tick ab (`off = tick.time - now`). Bei geschlossenem Markt misst sie
|
||||
# damit die Tick-Veraltung statt der Zeitzone (real −7,41 h statt +3 h)
|
||||
# und das Alter hebt sich rechnerisch auf (Ergebnis: −347 s).
|
||||
# Verwendet wird daher der direkte Beleg: **wann hat sich der Kurs zuletzt
|
||||
# BEWEGT?** Kein Zeitzonen-, Kalender- oder Feiertagswissen nötig.
|
||||
_now = time.time()
|
||||
try:
|
||||
_b = (market or {}).get("bid")
|
||||
if _b is not None:
|
||||
if self._last_bid is None or abs(float(_b) - self._last_bid) > 1e-9:
|
||||
self._last_bid = float(_b)
|
||||
self._last_bid_move_ts = _now
|
||||
except Exception:
|
||||
pass
|
||||
_tick_age = (round(_now - self._last_bid_move_ts)
|
||||
if self._last_bid_move_ts else None)
|
||||
_mkt_closed = bool(_tick_age is not None and _tick_age > _TICK_STALE_S)
|
||||
|
||||
# HL-Kurs IMMER mitliefern (User: „blende den Hyperliquid-Kurs NEBEN den
|
||||
# Pepperstone-Kurs ein") — nicht nur bei geschlossenem Markt. So sieht man
|
||||
# laufend die Abweichung; am Wochenende ist es der einzige lebende Kurs.
|
||||
_hl_live = None
|
||||
try:
|
||||
_w = self.hl_walls.walls()
|
||||
if _w and _w.get("mid_mt5") is not None:
|
||||
_hl_live = {
|
||||
"mid_mt5": _w["mid_mt5"], "hl_mid": _w.get("hl_mid"),
|
||||
"basis": _w.get("basis"), "age_s": _w.get("age_s"),
|
||||
"bid": _w.get("bid"), "ask": _w.get("ask"),
|
||||
"bid_sz": _w.get("bid_sz"), "ask_sz": _w.get("ask_sz"),
|
||||
"imb5": _w.get("imb5"),
|
||||
"trend": (_w.get("trend") or {}).get("dir"),
|
||||
"slope_per_h": (_w.get("trend") or {}).get("slope_per_h"),
|
||||
"vs_mt5": (round(_w["mid_mt5"] - float(market["bid"]), 3)
|
||||
if (market or {}).get("bid") else None),
|
||||
}
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ── G/V mit HL-Kurs, wenn der Broker eingefroren ist (User 2026-08-01) ──
|
||||
# Bei geschlossenem Markt steht `position.pnl` still. Die Schätzung setzt den
|
||||
# HL-Kurs (basis-korrigiert, also MT5-Niveau) in `trader.live_pnl()` ein — die
|
||||
# BEREITS VORHANDENE, korrekte Umrechnung über `tick_size`/`tick_value` inkl.
|
||||
# Swap und Währungsumrechnung.
|
||||
# ⚠ Erster Versuch leitete den EUR-je-Punkt-Faktor aus `pnl / Kursbewegung`
|
||||
# ab — das ergab 155 statt ~86 EUR je 1,00 und Lot, weil `pnl` den über das
|
||||
# Wochenende aufgelaufenen SWAP enthält. Eine Kennzahl aus einer anderen
|
||||
# Kennzahl zurückzurechnen ist hier schlicht falsch, wenn zusätzliche Terme
|
||||
# drinstecken.
|
||||
# ⚠ Bleibt eine SCHÄTZUNG: HL ist ein anderer Kontrakt (Basis herausgerechnet,
|
||||
# aber nicht exakt), und der Spread am Montags-Open ist unbekannt.
|
||||
_pnl_hl = None
|
||||
try:
|
||||
if _mkt_closed and _hl_live and position and position.get("ticket"):
|
||||
_mid = float(_hl_live["mid_mt5"])
|
||||
_sp = float((market or {}).get("spread") or 0.0)
|
||||
_v = self.trader.live_pnl(_mid - _sp / 2.0, _mid + _sp / 2.0)
|
||||
if _v is not None:
|
||||
_pnl_hl = round(_v, 2)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
snap = {
|
||||
"ts": time.time(),
|
||||
"connected": self._connected,
|
||||
@@ -3085,6 +3174,21 @@ class TradingEngine:
|
||||
# Wirtschaftskalender: {blackout, next, enabled, n} — Anzeige + Grund,
|
||||
# warum der Bot gerade keine autonome Order eröffnet.
|
||||
"calendar": self.calendar.snapshot(),
|
||||
# ── MARKT ZU + HYPERLIQUID-ERSATZKURS (User-Wunsch 2026-08-01) ──────
|
||||
# Pepperstone handelt WTI nicht am Wochenende; der Snapshot zeigt dann
|
||||
# den EINGEFRORENEN Freitags-Kurs, ohne dass man es sieht (der grüne
|
||||
# Punkt im Header ist die VERBINDUNG, nicht der Marktstatus). Hyperliquid
|
||||
# (`xyz:CL`) läuft dagegen 24/7 weiter.
|
||||
# `market_closed` wird NICHT aus dem Kalender abgeleitet, sondern aus dem
|
||||
# ALTER DES LETZTEN TICKS — das deckt Wochenende, Feiertage und
|
||||
# Broker-Ausfälle mit derselben Regel ab, ohne Kalenderpflege.
|
||||
# `hl_live.mid_mt5` = HL-Mid + gemessene Basis (HL notiert ~0,45 $ unter
|
||||
# dem CFD, anderer Kontrakt) → direkt mit dem MT5-Kurs vergleichbar.
|
||||
"market_closed": _mkt_closed,
|
||||
"tick_age_s": _tick_age,
|
||||
"hl_live": _hl_live,
|
||||
# G/V-Schaetzung auf HL-Basis, nur bei geschlossenem Markt (sonst None)
|
||||
"pnl_hl": _pnl_hl,
|
||||
}
|
||||
# ── Entry-Checkliste je Richtung (User-Vorgabe 2026-07-30: „blende einen
|
||||
# Hinweis ein, wenn die Checkliste gegen meine Eröffnung ist"). Wird im
|
||||
|
||||
Reference in New Issue
Block a user