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
@@ -2139,6 +2139,48 @@ dort bereits nachvalidiert, ØR +0,305.) **Eine** Oberfläche:
|
||||
+ Chart-`fontSize` in `app.js`. Bei künftigen globalen Font-Änderungen die
|
||||
Shorthand nicht vergessen.
|
||||
|
||||
## Hyperliquid-Kurs neben dem Broker-Kurs (2026-08-01)
|
||||
|
||||
**User-Wunsch:** „wenn Pepperstone geschlossen ist trotzdem den aktuellen Kurs und die
|
||||
Liquidität von Hyperliquid einbinden" → nachgeschärft zu „blende den HL-Kurs **neben**
|
||||
den Pepperstone-Kurs ein" (ehrlicher: man sieht die Abweichung, statt dass still
|
||||
getauscht wird) → 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 befüllt, nicht nur am Wochenende.
|
||||
`mid_mt5` = HL-Mid + gemessene Basis (HL `xyz:CL` notiert wegen anderem Kontrakt
|
||||
~0,45 $ unter dem CFD; die Basis kommt serverseitig aus dem HL-Projekt als Median
|
||||
über 60 Snapshots) → direkt mit dem Broker-Kurs vergleichbar.
|
||||
Dazu `market_closed`, `tick_age_s`, `pnl_hl`.
|
||||
- **Dashboard (v=129):** eigene Header-Box **HL** neben KURS; Tooltip nennt HL-Rohkurs,
|
||||
Basis, Alter und Abweichung. Bei geschlossenem Markt heißt das Kurs-Label
|
||||
„KURS · ZU", die Session-Zeile zeigt „🔒 MARKT ZU", und das **G/V wechselt auf die
|
||||
HL-Schätzung** (mit `≈` markiert, Tooltip nennt den eingefrorenen Broker-Wert).
|
||||
- **MT5 (Indikator v1.34):** `HL;<mt5_aequiv>;<alter_s>;<bid>;<ask>;<U|D|->` →
|
||||
bernsteinfarbenes Label unter Kurs und G/V (`InpShowHL`/`InpHLColor`).
|
||||
|
||||
⚠ **DREI Sackgassen bei der „Markt zu"-Erkennung — dokumentiert, damit sie niemand
|
||||
wiederholt:**
|
||||
1. **`tick_local_ts`** ist die lokale **ABHOLZEIT**, nicht das Tick-Alter — sie
|
||||
erneuert sich bei jedem Abruf, auch wenn der Broker denselben alten Tick liefert.
|
||||
2. **`tick_server_ts` − `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 die Tick-Veraltung
|
||||
statt der Zeitzone (real **−7,41 h** statt +3 h) — das Alter hebt sich rechnerisch
|
||||
auf (Ergebnis: **−347 s**).
|
||||
3. **`pnl / Kursbewegung`** als EUR-je-Punkt-Faktor ergab **155 statt ~86 EUR** je
|
||||
1,00 und Lot, weil `trader.pnl = profit + swap` den über das Wochenende
|
||||
aufgelaufenen Swap enthält.
|
||||
**Verwendet wird stattdessen:** Markt zu = **der Kurs hat sich seit `_TICK_STALE_S`
|
||||
(180 s) nicht BEWEGT** (`_last_bid`/`_last_bid_move_ts`) — kein Zeitzonen-, Kalender-
|
||||
oder Feiertagswissen nötig, deckt Wochenende, Feiertag und Broker-Ausfall gleich ab.
|
||||
Und der G/V nutzt die vorhandene, korrekte Umrechnung **`trader.live_pnl(bid, ask)`**
|
||||
(`tick_size`/`tick_value` inkl. Swap und Währung), gefüttert mit dem HL-Kurs ± halbem
|
||||
Spread. ⚠ Bleibt eine **Schätzung** (anderer Kontrakt, Montags-Open-Spread unbekannt) —
|
||||
deshalb das `≈` in der Anzeige.
|
||||
⚠ Nach einem Server-Neustart braucht die Erkennung 180 s, bis sie greift (der
|
||||
Bewegungs-Zeitstempel startet beim ersten Snapshot).
|
||||
|
||||
## Web-API (server.py)
|
||||
`GET /api/snapshot` (inkl. `verdict`-Aggregat) `/api/health` `/api/logs` `/api/stats` `/api/news` `/api/bars?tf=&n=` (Charts, read-only) `/api/squeeze_monitor` (B4-Monitor, read-only, Engine-Cache 60 s) · `WS /ws` ·
|
||||
`POST /api/order|auto|trail|emergency|takeprofit|sltp|srclose|srclose_min|autosqueeze|autosignal|auth/check`.
|
||||
|
||||
+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
|
||||
|
||||
+15
-1
@@ -79,7 +79,21 @@ class HLWalls:
|
||||
# gewichteten Wand-Schwerpunkt): {t1,p1,t2,p2,dir,slope_per_h}
|
||||
# — Zeiten sind LOKALE Epoch, der Aufrufer rechnet sie in
|
||||
# Broker-Zeit um (MT5-Charts brauchen Broker-Zeit).
|
||||
"trend": d.get("trend")}
|
||||
"trend": d.get("trend"),
|
||||
# ── Ergänzt 2026-08-01 (User: „blende den Hyperliquid-
|
||||
# Kurs neben den Pepperstone-Kurs ein"): der HL-MITTELKURS
|
||||
# auf MT5-Niveau. HL `xyz:CL` notiert wegen anderem
|
||||
# Kontrakt/Contango ~0,45 $ unter dem CFD — `basis` ist die
|
||||
# serverseitig gemessene Differenz (Median über 60
|
||||
# Snapshots), `mid_mt5` also direkt mit dem Broker-Kurs
|
||||
# vergleichbar. Nützlich vor allem am Wochenende: HL
|
||||
# handelt 24/7, Pepperstone nicht.
|
||||
"hl_mid": (float(d["hl_mid"])
|
||||
if d.get("hl_mid") is not None else None),
|
||||
"mid_mt5": (round(float(d["hl_mid"])
|
||||
+ float(d.get("basis") or 0.0), 3)
|
||||
if d.get("hl_mid") is not None else None),
|
||||
"age_s": round(age, 1)}
|
||||
self._fail_logged = False
|
||||
except Exception as e:
|
||||
if not self._fail_logged: # nur 1× melden, nicht jeden Tick
|
||||
|
||||
+41
-1
@@ -12,7 +12,11 @@
|
||||
//| 4) Der Bot muss laufen (schreibt die CSV alle ~5 s). |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Oil Trading Bot"
|
||||
#property version "1.33"
|
||||
#property version "1.34"
|
||||
// v1.34 (2026-08-01): HYPERLIQUID-KURS (HL;...) unter Kurs und G/V oben rechts,
|
||||
// bernstein. HL handelt 24/7, Pepperstone nicht - am Wochenende der einzige
|
||||
// lebende Kurs; die Basis (~0,45 $ Kontrakt-Differenz) ist herausgerechnet,
|
||||
// der Wert also direkt mit dem Broker-Kurs vergleichbar. InpShowHL/InpHLColor.
|
||||
// v1.33 (2026-07-31): Konsens-Pfeil (K) per Default AUS + Pfeile kuerzer (8 statt
|
||||
// 14 Bars). Grund: L und K starten am selben Punkt und zeigten oft in
|
||||
// ENTGEGENGESETZTE Richtungen - zwei divergierende Linien aus einem Punkt
|
||||
@@ -185,6 +189,8 @@ input color InpArrConsensus = C'139,148,158'; // Konsens der Module (NICHT kali
|
||||
input bool InpShowConsensus = false; // Konsens-Pfeil zusaetzlich zeichnen
|
||||
input int InpArrBars = 8; // Pfeil-Laenge in Bars (kuerzer = Spitze sichtbar)
|
||||
input color InpConeColor = C'139,148,158'; // Kegel-Farbe (neutral grau - bewusst KEINE Richtungsfarbe)
|
||||
input bool InpShowHL = true; // Hyperliquid-Kurs unter dem Broker-Kurs
|
||||
input color InpHLColor = C'232,160,0'; // HL-Kurs (bernstein, klar unterscheidbar)
|
||||
input bool InpShowPnL = true; // G/V der offenen Position unter dem Kurs
|
||||
input color InpPnLUpColor = C'0,255,127'; // G/V im Plus (neongruen)
|
||||
input color InpPnLDownColor = C'255,69,0'; // G/V im Minus (rot)
|
||||
@@ -798,6 +804,40 @@ void Redraw()
|
||||
ObjectSetString(0, atn, OBJPROP_TEXT, " " + a_txt);
|
||||
continue;
|
||||
}
|
||||
// HYPERLIQUID-KURS unter dem Broker-Kurs: HL;<mt5_aequiv>;<alter_s>;<bid>;<ask>;<U|D|->
|
||||
// HL (`xyz:CL`) handelt 24/7, Pepperstone nicht - am Wochenende der einzige
|
||||
// lebende Kurs. Bereits basis-korrigiert, also direkt vergleichbar.
|
||||
if(typ == "HL")
|
||||
{
|
||||
if(k < 6) continue;
|
||||
if(!InpShowHL) continue;
|
||||
double hlp = StringToDouble(p[1]);
|
||||
if(hlp <= 0) continue;
|
||||
int hage = (int)StringToInteger(p[2]);
|
||||
string htr = p[5];
|
||||
string hn = PFX + "HLPX";
|
||||
if(ObjectFind(0, hn) < 0)
|
||||
{
|
||||
ObjectCreate(0, hn, OBJ_LABEL, 0, 0, 0);
|
||||
ObjectSetInteger(0, hn, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
|
||||
ObjectSetInteger(0, hn, OBJPROP_XDISTANCE, 12);
|
||||
// unter Kurs (14) und G/V (14+PriceSize+6) einreihen
|
||||
ObjectSetInteger(0, hn, OBJPROP_YDISTANCE, 14 + InpPriceSize + 6 + InpPriceSize - 4);
|
||||
ObjectSetInteger(0, hn, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
|
||||
ObjectSetInteger(0, hn, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetString (0, hn, OBJPROP_FONT, "Arial");
|
||||
}
|
||||
ObjectSetInteger(0, hn, OBJPROP_FONTSIZE, (int)MathMax(10, InpPriceSize - 7));
|
||||
ObjectSetInteger(0, hn, OBJPROP_COLOR, InpHLColor);
|
||||
ObjectSetString (0, hn, OBJPROP_TEXT,
|
||||
"HL " + DoubleToString(hlp, (int)_Digits)
|
||||
+ (htr == "U" ? " ^" : htr == "D" ? " v" : ""));
|
||||
ObjectSetString (0, hn, OBJPROP_TOOLTIP,
|
||||
"Hyperliquid xyz:CL, basis-korrigiert auf MT5-Niveau - "
|
||||
+ IntegerToString(hage) + " s alt. Waende "
|
||||
+ p[3] + " / " + p[4]);
|
||||
continue;
|
||||
}
|
||||
// AKTUELLER KURS oben rechts, fett (User-Wunsch): PX;bid
|
||||
if(typ == "PX")
|
||||
{
|
||||
|
||||
+50
-4
@@ -429,9 +429,15 @@ function render(d) {
|
||||
const storm = (d.news_storm || {}).level;
|
||||
if (storm === "storm") stxt = `📰 NEWS-STURM · ${stxt}`;
|
||||
else if (storm === "elevated") stxt = `📰 viele News · ${stxt}`;
|
||||
// Marktstatus VOR die Session-Zeile: bei geschlossenem Markt ist die Phase
|
||||
// ("Wochenende") allein zu leise — der eingefrorene Kurs sah live aus.
|
||||
if (d.market_closed) {
|
||||
stxt = `🔒 MARKT ZU · ${stxt}`; // HL-Kurs steht jetzt im Header
|
||||
}
|
||||
$("session").textContent = stxt;
|
||||
$("session").className = "session-line " +
|
||||
(storm === "storm" ? "warn"
|
||||
(d.market_closed ? "warn"
|
||||
: storm === "storm" ? "warn"
|
||||
: (_h === 21 || _h === 22) ? "warn"
|
||||
: ses.just_opened ? "warn" : (ses.active && ses.active.length) ? "ok" : "dim");
|
||||
|
||||
@@ -464,16 +470,56 @@ function render(d) {
|
||||
}
|
||||
|
||||
// ── Header: Kurs (färbt sich nahe S/R) + G/V der offenen Position (netto) ──
|
||||
// ⚠ MARKT ZU (User 2026-08-01): Pepperstone handelt WTI nicht am Wochenende, der
|
||||
// Kurs friert dann auf dem Freitags-Stand ein — sichtbar war das NICHT (der grüne
|
||||
// Punkt im Header ist die VERBINDUNG, nicht der Marktstatus). Hyperliquid läuft
|
||||
// 24/7 weiter, also zeigen wir dessen Kurs (basis-korrigiert = MT5-vergleichbar)
|
||||
// statt des eingefrorenen — deutlich als „HL" gekennzeichnet, damit niemand ihn
|
||||
// für einen Broker-Kurs hält.
|
||||
// ⚠ Der BROKER-Kurs bleibt der Hauptkurs (erster Entwurf ersetzte ihn bei
|
||||
// geschlossenem Markt durch den HL-Kurs — der User wollte stattdessen BEIDE
|
||||
// nebeneinander, was ehrlicher ist: man sieht die Abweichung statt einer
|
||||
// stillen Vertauschung).
|
||||
$("hdr-price").textContent = m.bid != null ? fmt(m.bid) : "—";
|
||||
$("hdr-price").className = priceCls;
|
||||
$("hdr-price-lbl").textContent = d.market_closed ? "KURS · ZU" : "KURS";
|
||||
$("hdr-price-lbl").title = d.market_closed
|
||||
? `Pepperstone geschlossen — letzter Tick vor ${Math.round((d.tick_age_s || 0) / 60)} min`
|
||||
: "";
|
||||
|
||||
// Hyperliquid daneben: basis-korrigiert (= MT5-Niveau), mit Abweichung im Tooltip.
|
||||
const hl = d.hl_live || null;
|
||||
const hlEl = $("hdr-hl");
|
||||
if (hl && hl.mid_mt5 != null) {
|
||||
const arr = hl.trend === "up" ? "▲" : hl.trend === "down" ? "▼" : "";
|
||||
hlEl.textContent = fmt(hl.mid_mt5) + (arr ? " " + arr : "");
|
||||
const dv = hl.vs_mt5;
|
||||
hlEl.className = d.market_closed ? "hl-price"
|
||||
: (dv != null && Math.abs(dv) >= 0.15) ? "hl-price" : "";
|
||||
hlEl.title = `Hyperliquid xyz:CL ${fmt(hl.hl_mid)} + gemessene Basis `
|
||||
+ `${hl.basis >= 0 ? "+" : ""}${fmt(hl.basis, 3)} = ${fmt(hl.mid_mt5)} · `
|
||||
+ `${fmt(hl.age_s, 0)} s alt`
|
||||
+ (dv != null ? ` · ggü. Broker ${dv >= 0 ? "+" : ""}${fmt(dv, 3)}` : "");
|
||||
} else {
|
||||
hlEl.textContent = "—"; hlEl.className = ""; hlEl.title = "";
|
||||
}
|
||||
|
||||
const hpos = d.position || {};
|
||||
if (hpos.ticket) {
|
||||
const wht = d.wht_pct || 0;
|
||||
const raw = hpos.pnl || 0;
|
||||
// ⚠ Bei geschlossenem Markt steht der Broker-P&L still (der Kurs ist eingefroren).
|
||||
// Dann die HL-SCHÄTZUNG zeigen (User 2026-08-01) — klar als Schätzung markiert:
|
||||
// Swap/Kommission der Wochenendtage fehlen und HL ist ein anderer Kontrakt.
|
||||
const useHl = d.market_closed && d.pnl_hl != null;
|
||||
const raw = useHl ? d.pnl_hl : (hpos.pnl || 0);
|
||||
const netHdr = raw > 0 ? raw * (1 - wht / 100) : raw;
|
||||
$("hdr-pnl").textContent = (netHdr >= 0 ? "+" : "") + cs + fmt(netHdr, 2);
|
||||
$("hdr-pnl").textContent = (useHl ? "≈" : "") + (netHdr >= 0 ? "+" : "") + cs + fmt(netHdr, 2);
|
||||
$("hdr-pnl").className = netHdr > 0 ? "up" : netHdr < 0 ? "down" : "";
|
||||
} else { $("hdr-pnl").textContent = "—"; $("hdr-pnl").className = ""; }
|
||||
$("hdr-pnl").title = useHl
|
||||
? `Schätzung auf Basis des Hyperliquid-Kurses — der Broker-Kurs ist eingefroren `
|
||||
+ `(Broker-P&L ${fmt(hpos.pnl || 0, 2)} ${cs}). Ohne Swap/Kommission des Wochenendes.`
|
||||
: "";
|
||||
} else { $("hdr-pnl").textContent = "—"; $("hdr-pnl").className = ""; $("hdr-pnl").title = ""; }
|
||||
|
||||
// ── S/R-Annäherungs-Warnung (Position-Kachel) — NUR wenn kein reicherer
|
||||
// Positions-Hint (pos-srhint) läuft, sonst doppeltes „nähert sich Widerstand".
|
||||
|
||||
+7
-3
@@ -6,7 +6,7 @@
|
||||
<meta name="theme-color" content="#0d1117">
|
||||
<title>Oil · MT5</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="style.css?v=126">
|
||||
<link rel="stylesheet" href="style.css?v=129">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Modul-Menü (ganz oben) -->
|
||||
@@ -34,7 +34,11 @@
|
||||
<div class="px"><label>BALANCE</label><span id="balance">—</span></div>
|
||||
<div class="px"><label>TAG P/L</label><span id="day-pl">—</span></div>
|
||||
<div class="px"><label>EQUITY</label><span id="equity">—</span></div>
|
||||
<div class="px"><label>KURS</label><span id="hdr-price">—</span></div>
|
||||
<div class="px"><label id="hdr-price-lbl">KURS</label><span id="hdr-price">—</span></div>
|
||||
<!-- Hyperliquid-Kurs NEBEN dem Broker-Kurs (User 2026-08-01). HL handelt 24/7,
|
||||
Pepperstone nicht — am Wochenende der einzige lebende Kurs. Basis-korrigiert,
|
||||
also direkt vergleichbar. -->
|
||||
<div class="px" id="px-hl"><label>HL</label><span id="hdr-hl">—</span></div>
|
||||
<div class="px"><label>G/V</label><span id="hdr-pnl">—</span></div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -244,6 +248,6 @@
|
||||
<div id="toast" class="toast hidden"></div>
|
||||
|
||||
<script src="lightweight-charts.standalone.production.js?v=114"></script>
|
||||
<script src="app.js?v=126"></script>
|
||||
<script src="app.js?v=129"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -484,3 +484,8 @@ main{padding-bottom:74px} /* Platz für die fixe Leiste */
|
||||
.sqm-row b.up{ color:var(--up); } .sqm-row b.down{ color:var(--down); }
|
||||
.sqm-exp{ font-size:15px; color:var(--dim); margin-top:6px; }
|
||||
.sqm-note{ font-size:16px; color:var(--dim); margin-top:8px; line-height:1.4; }
|
||||
|
||||
/* Kurs aus Hyperliquid (Markt bei Pepperstone geschlossen) - bewusst ANDERS
|
||||
gefaerbt als der Broker-Kurs, damit man ihn nicht verwechselt. */
|
||||
#hdr-price.hl-price{color:var(--accent)}
|
||||
#hdr-price-lbl{letter-spacing:.3px}
|
||||
|
||||
Reference in New Issue
Block a user