Meldungen oben links im MT5-Chart (MS;<text>, Indikator v1.36)
User-Wunsch. Neue CSV-Zeile MS;<text>, im Indikator als gestapelte OBJ_LABEL an CORNER_LEFT_UPPER (oben rechts sind Kurs, G/V und HL belegt). Inhalt = dieselben Zeilen wie die Dashboard-Karte "Meldungen": Squeeze, Ueberdehnung, S/R-Ziel mit P(break), Stop-Seite, News-Blackout. NUR ZUSAMMENGESETZT, NICHT NEU GERECHNET -- alles aus bereits berechneten Snapshot-Teilen bzw. _last_sr_close_hint/_last_stop_approach; calendar.blackout() ist ein reiner Speicher-Zugriff. Der Konsens-Pfeil hat im 5-s-Export-Takt einmal ein komplettes zweites _verdict() gezogen. Zwei Felder vorher geprueft statt angenommen: _last_calendar und _export_meldungen gab es NICHT -- ohne die Pruefung haette das umgebende except Exception es still verschluckt und die Meldungen waeren dauerhaft leer geblieben (dieselbe Klasse wie der wave_snap-Fallstrick vom 04.08.). ASCII-SICHER, real noetig: der erste Lauf lieferte "MS; Kompression Ausbruch steht bevor" -- Emoji und Gedankenstrich waren zu Leerzeichen geworden. Der Indikator liest die CSV nicht als UTF-8 (deshalb steht dort auch "Unterstuetzung"). Jetzt Ersetzung + Filter auf 32-126. Verifiziert: MS;Squeeze-Ausbruch LONG @ 82.413, 0 Nicht-ASCII-Zeichen. Deckel 5 Zeilen a 70 Zeichen; eigener Praefix SRB_MSG_*, damit die Labels beim Redraw verschwinden. Abschaltbar per [trading] export_meldungen=false oder InpShowMeldungen. Kompiliert ins richtige Terminal (0 errors, 0 warnings), deployt und am laufenden Server verifiziert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
55dc69ef42
commit
204e80bb68
@@ -6144,6 +6144,38 @@ in der Lehrbuch- noch in der umgedrehten Lesart.
|
|||||||
⚠ Konsistent mit der Kachel-Entscheidung vom 31.07.: die Kerzen-Anatomie ist
|
⚠ Konsistent mit der Kachel-Entscheidung vom 31.07.: die Kerzen-Anatomie ist
|
||||||
bewusst **neutral** gefärbt und nennt die gemessene statt der Lehrbuch-Lesart.
|
bewusst **neutral** gefärbt und nennt die gemessene statt der Lehrbuch-Lesart.
|
||||||
|
|
||||||
|
### ✅ MELDUNGEN OBEN LINKS IM MT5-CHART (2026-08-17, Indikator v1.36)
|
||||||
|
|
||||||
|
User-Wunsch. Neue CSV-Zeile **`MS;<text>`**, im Indikator als gestapelte
|
||||||
|
`OBJ_LABEL` an `CORNER_LEFT_UPPER` (oben rechts sind Kurs, G/V und HL).
|
||||||
|
Inhalt = dieselben Zeilen wie die Dashboard-Karte „Meldungen": Squeeze-Zustand,
|
||||||
|
Überdehnung, S/R-Ziel mit P(break), Stop-Seite, News-Blackout.
|
||||||
|
|
||||||
|
⚠⚠ **NUR ZUSAMMENGESETZT, NICHT NEU GERECHNET.** Alles kommt aus bereits
|
||||||
|
berechneten Snapshot-Teilen bzw. `_last_sr_close_hint`/`_last_stop_approach`;
|
||||||
|
`calendar.blackout()` ist ein reiner Speicher-Zugriff. Der Konsens-Pfeil hat im
|
||||||
|
~5-s-Export-Takt einmal ein **komplettes zweites `_verdict()`** gezogen — doppelte
|
||||||
|
Last UND die Gefahr, dass Chart und Dashboard auseinanderlaufen.
|
||||||
|
✅ **Zwei Felder vorher geprüft statt angenommen:** `_last_calendar` und
|
||||||
|
`_export_meldungen` gab es **nicht** — ohne die Prüfung hätte das umgebende
|
||||||
|
`except Exception` es still verschluckt und die Meldungen wären dauerhaft leer
|
||||||
|
geblieben (dieselbe Klasse wie der `wave_snap`-Fallstrick vom 04.08.).
|
||||||
|
|
||||||
|
⚠⚠ **ASCII-SICHER — real nötig, nicht vorsorglich.** Der erste Lauf lieferte
|
||||||
|
`MS; Kompression Ausbruch steht bevor`: Emoji und Gedankenstrich waren zu
|
||||||
|
Leerzeichen geworden. Der Indikator liest die CSV **nicht** als UTF-8 — genau
|
||||||
|
deshalb steht dort auch „Unterstuetzung" statt „Unterstützung". Jetzt werden
|
||||||
|
Umlaute/Sonderzeichen ersetzt und alles ausserhalb 32–126 entfernt.
|
||||||
|
Verifiziert: `MS;Squeeze-Ausbruch LONG @ 82.413`, **0 Nicht-ASCII-Zeichen**.
|
||||||
|
|
||||||
|
⚠ Deckel **5 Zeilen** (der Chart soll lesbar bleiben), je 70 Zeichen; `;` im Text
|
||||||
|
wird zu `,`. Eigener Objekt-Präfix `SRB_MSG_*`, damit die Labels beim Redraw
|
||||||
|
verschwinden, wenn keine Meldung mehr ansteht (die Alt-Objekt-Falle der
|
||||||
|
HL-Pfeile). Abschaltbar: `[trading] export_meldungen=false` **oder**
|
||||||
|
`InpShowMeldungen=false`; Größe/Farbe über `InpMeldungSize`/`InpMeldungColor`.
|
||||||
|
✅ Kompiliert ins **richtige** Terminal (0 errors, 0 warnings), deployt und am
|
||||||
|
laufenden Server verifiziert.
|
||||||
|
|
||||||
### ✅ S/R-AUTO-CLOSE WIEDER AN (User-Entscheidung 2026-08-11)
|
### ✅ S/R-AUTO-CLOSE WIEDER AN (User-Entscheidung 2026-08-11)
|
||||||
|
|
||||||
Frage war: „sollten wir Trades bei einem S/R-Bounce automatisch schliessen?"
|
Frage war: „sollten wir Trades bei einem S/R-Bounce automatisch schliessen?"
|
||||||
|
|||||||
@@ -490,6 +490,10 @@ class TradingEngine:
|
|||||||
self._export_mql5 = self.cfg["trading"].get("export_mql5_levels", "true").lower() == "true"
|
self._export_mql5 = self.cfg["trading"].get("export_mql5_levels", "true").lower() == "true"
|
||||||
# Kegel im MT5-Chart: per Default AUS, seit die Pfeile ihn ersetzen (2026-07-31).
|
# Kegel im MT5-Chart: per Default AUS, seit die Pfeile ihn ersetzen (2026-07-31).
|
||||||
self._export_cone = self.cfg["trading"].get("export_cone", "false").lower() == "true"
|
self._export_cone = self.cfg["trading"].get("export_cone", "false").lower() == "true"
|
||||||
|
# Meldungen oben links im MT5-Chart (User-Wunsch 2026-08-17) — dieselben
|
||||||
|
# Zeilen wie die Dashboard-Karte, nur zusammengesetzt, nicht neu gerechnet.
|
||||||
|
self._export_meldungen = (
|
||||||
|
self.cfg["trading"].get("export_meldungen", "true").lower() == "true")
|
||||||
# Konsens-Pfeil (AR;K) — Default AUS, spiegelt `InpShowConsensus=false` im
|
# Konsens-Pfeil (AR;K) — Default AUS, spiegelt `InpShowConsensus=false` im
|
||||||
# Indikator. Bei `true` wird je Export ein zweites `_verdict()` gerechnet.
|
# Indikator. Bei `true` wird je Export ein zweites `_verdict()` gerechnet.
|
||||||
self._export_consensus_arrow = self.cfg["trading"].get(
|
self._export_consensus_arrow = self.cfg["trading"].get(
|
||||||
@@ -2801,6 +2805,68 @@ class TradingEngine:
|
|||||||
lines.append(f"PL;{_p:.2f};{_cur}")
|
lines.append(f"PL;{_p:.2f};{_cur}")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
# ── MELDUNGEN oben links (MS;<text>) — User-Wunsch 2026-08-17 ────
|
||||||
|
# Dieselben Zeilen wie die Dashboard-Karte „Meldungen" (`#card-pos`).
|
||||||
|
# ⚠⚠ NUR ZUSAMMENSETZEN, NICHT NEU RECHNEN. Der Konsens-Pfeil hat im
|
||||||
|
# ~5-s-Export-Takt ein komplettes zweites `_verdict()` gezogen —
|
||||||
|
# doppelte Last UND die Gefahr, dass Chart und Dashboard
|
||||||
|
# auseinanderlaufen. Alles hier kommt aus bereits berechneten
|
||||||
|
# Snapshot-Teilen bzw. den `_last_*`-Feldern.
|
||||||
|
# ⚠ Abschaltbar: `[trading] export_meldungen=false`.
|
||||||
|
if self._export_meldungen:
|
||||||
|
try:
|
||||||
|
_ms: list[str] = []
|
||||||
|
_ws2 = self.wave.snapshot() or {}
|
||||||
|
_sq2 = _ws2.get("squeeze") or {}
|
||||||
|
if _sq2.get("state") == "active" and _sq2.get("dir"):
|
||||||
|
_ms.append(f"🚀 Squeeze-Ausbruch {_sq2['dir']} "
|
||||||
|
f"@ {_sq2.get('level')}")
|
||||||
|
elif _sq2.get("state") == "armed":
|
||||||
|
_ms.append("🎯 Kompression — Ausbruch steht bevor")
|
||||||
|
_bo = _ws2.get("bounce") or {}
|
||||||
|
if _bo.get("state") in ("expected", "active") and _bo.get("dir"):
|
||||||
|
_pf = "aktiv" if _bo["state"] == "active" else "erwartet"
|
||||||
|
_ms.append(f"⚠ Ueberdehnung ({_pf}) — Reaktion "
|
||||||
|
f"{'nach oben' if _bo['dir'] == 'LONG' else 'nach unten'}"
|
||||||
|
f" moeglich [{_bo.get('tf') or ''}]")
|
||||||
|
_sh = self._last_sr_close_hint
|
||||||
|
if _sh and _sh.get("level"):
|
||||||
|
_pb2 = _sh.get("p_break")
|
||||||
|
_txt = ("unentschieden" if _pb2 is None or 45 <= _pb2 <= 55
|
||||||
|
else f"{_pb2}% Bruch" if _pb2 > 55
|
||||||
|
else f"{100 - _pb2}% Abprall")
|
||||||
|
_ms.append(f"S/R-Ziel {_sh['level']} · {_txt}"
|
||||||
|
+ (" · Bot wuerde schliessen" if _sh.get("close") else ""))
|
||||||
|
_st2 = self._last_stop_approach
|
||||||
|
if _st2 and _st2.get("level"):
|
||||||
|
_pb3 = _st2.get("p_break")
|
||||||
|
_ms.append(f"Stop-Seite {_st2['level']} · "
|
||||||
|
+ ("bricht wahrscheinlich" if (_pb3 or 0) >= 50
|
||||||
|
else "haelt wahrscheinlich"))
|
||||||
|
# ⚠ `self.calendar` ist das Objekt (kein `_last_*`-Feld) —
|
||||||
|
# `blackout()` ist ein reiner Speicher-Zugriff, kein Netz.
|
||||||
|
_bl = self.calendar.blackout()
|
||||||
|
if _bl:
|
||||||
|
_ms.append(f"News-Blackout: {_bl.get('title') or ''}")
|
||||||
|
# ⚠⚠ ASCII-SICHER. Der Indikator liest die CSV NICHT als
|
||||||
|
# UTF-8 — Emoji und Sonderzeichen kommen als Leerzeichen an
|
||||||
|
# (real gesehen: „🎯 Kompression — …" wurde „ Kompression
|
||||||
|
# …"). Genau deshalb steht im Indikator auch
|
||||||
|
# „Unterstuetzung" statt „Unterstützung". Ersetzen statt
|
||||||
|
# hoffen.
|
||||||
|
_ers = {"—": "-", "–": "-", "·": "-", "→": "->", "≥": ">=",
|
||||||
|
"≤": "<=", "ü": "ue", "ö": "oe", "ä": "ae",
|
||||||
|
"Ü": "Ue", "Ö": "Oe", "Ä": "Ae", "ß": "ss"}
|
||||||
|
for _z in _ms[:5]: # Deckel: der Chart soll lesbar bleiben
|
||||||
|
_t = str(_z)
|
||||||
|
for _a, _b in _ers.items():
|
||||||
|
_t = _t.replace(_a, _b)
|
||||||
|
_t = "".join(c for c in _t if 32 <= ord(c) < 127)
|
||||||
|
_t = " ".join(_t.split()) # Mehrfach-Leerzeichen weg
|
||||||
|
if _t:
|
||||||
|
lines.append("MS;" + _t.replace(";", ",")[:70])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
# Trade-Marker: TR;<O|C>;<broker_time> → der Indikator umrandet die Kerze,
|
# Trade-Marker: TR;<O|C>;<broker_time> → der Indikator umrandet die Kerze,
|
||||||
# in der eröffnet (hellgrün) bzw. geschlossen (dunkelgrün) wurde
|
# in der eröffnet (hellgrün) bzw. geschlossen (dunkelgrün) wurde
|
||||||
# (User-Vorgabe 2026-07-30). Offene Position + die letzten Trades des Tages.
|
# (User-Vorgabe 2026-07-30). Offene Position + die letzten Trades des Tages.
|
||||||
|
|||||||
+42
-1
@@ -12,7 +12,13 @@
|
|||||||
//| 4) Der Bot muss laufen (schreibt die CSV alle ~5 s). |
|
//| 4) Der Bot muss laufen (schreibt die CSV alle ~5 s). |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "Oil Trading Bot"
|
#property copyright "Oil Trading Bot"
|
||||||
#property version "1.35"
|
#property version "1.36"
|
||||||
|
// v1.36 (2026-08-17): MELDUNGEN oben links (MS;<text>) — dieselben Zeilen wie
|
||||||
|
// die Dashboard-Karte "Meldungen" (Squeeze, Ueberdehnung, S/R-Ziel,
|
||||||
|
// Stop-Seite, News-Blackout). Der Bot setzt sie nur ZUSAMMEN aus bereits
|
||||||
|
// berechneten Snapshot-Teilen, er rechnet nichts neu -- die Lehre aus dem
|
||||||
|
// Konsens-Pfeil, der im 5-s-Takt ein zweites _verdict() zog.
|
||||||
|
// Abschaltbar per InpShowMeldungen oder [trading] export_meldungen=false.
|
||||||
// v1.35 (2026-08-13): S/R-LABEL WORTGLEICH ZUR M15-KARTE (User: „die Beschriftung
|
// v1.35 (2026-08-13): S/R-LABEL WORTGLEICH ZUR M15-KARTE (User: „die Beschriftung
|
||||||
// fuer S/R im Chart stimmt nicht mit der Analyse in der M15-Karte ueberein").
|
// fuer S/R im Chart stimmt nicht mit der Analyse in der M15-Karte ueberein").
|
||||||
// Das Label trug seit v1.27 die NACKTE Zahl = P(Durchbruch); die Karte klappt
|
// Das Label trug seit v1.27 die NACKTE Zahl = P(Durchbruch); die Karte klappt
|
||||||
@@ -218,6 +224,12 @@ input color InpThemeText = C'139,148,158'; // Achsen/Text
|
|||||||
input color InpThemeBidLine = clrWhite; // aktuelle Kurslinie (Bid) — weiss
|
input color InpThemeBidLine = clrWhite; // aktuelle Kurslinie (Bid) — weiss
|
||||||
input double InpShiftPct = 12.0; // Platz rechts fuer Pfeile/Labels (% der Chartbreite)
|
input double InpShiftPct = 12.0; // Platz rechts fuer Pfeile/Labels (% der Chartbreite)
|
||||||
input bool InpShowTradeLevels = true; // MT5-Positionslinien+Labels (stehen immer LINKS)
|
input bool InpShowTradeLevels = true; // MT5-Positionslinien+Labels (stehen immer LINKS)
|
||||||
|
// Meldungen oben links (User-Wunsch 2026-08-17) — dieselben Zeilen wie die
|
||||||
|
// Dashboard-Karte „Meldungen". Der Bot deckelt auf 5; abschaltbar per ini
|
||||||
|
// (`[trading] export_meldungen=false`) ODER hier.
|
||||||
|
input bool InpShowMeldungen = true; // Meldungen oben links einblenden
|
||||||
|
input int InpMeldungSize = 10; // Schriftgroesse der Meldungen
|
||||||
|
input color InpMeldungColor = clrGainsboro; // Farbe der Meldungen
|
||||||
|
|
||||||
const string PFX = "SRB_"; // Präfix S/R-Linien (aus Datei)
|
const string PFX = "SRB_"; // Präfix S/R-Linien (aus Datei)
|
||||||
const string RPFX = "SRR_"; // Präfix dynamische Range (aus Chart)
|
const string RPFX = "SRR_"; // Präfix dynamische Range (aus Chart)
|
||||||
@@ -450,6 +462,7 @@ void Redraw()
|
|||||||
string rows[];
|
string rows[];
|
||||||
int nr = StringSplit(content, '\n', rows);
|
int nr = StringSplit(content, '\n', rows);
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
int msg_idx = 0; // Meldungs-Stapel oben links
|
||||||
// Kegel-Verkettung je Redraw zuruecksetzen (sonst haengt der Faecher am Stand
|
// Kegel-Verkettung je Redraw zuruecksetzen (sonst haengt der Faecher am Stand
|
||||||
// des vorherigen Durchlaufs)
|
// des vorherigen Durchlaufs)
|
||||||
g_coneT = 0; g_coneLo = 0.0; g_coneHi = 0.0; g_conePx = 0.0;
|
g_coneT = 0; g_coneLo = 0.0; g_coneHi = 0.0; g_conePx = 0.0;
|
||||||
@@ -886,6 +899,34 @@ void Redraw()
|
|||||||
ObjectSetInteger(0, pn, OBJPROP_COLOR, InpPriceColor);
|
ObjectSetInteger(0, pn, OBJPROP_COLOR, InpPriceColor);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// MELDUNGEN oben LINKS (MS;<text>) — User-Wunsch 2026-08-17.
|
||||||
|
// Dieselben Zeilen wie die Dashboard-Karte „Meldungen"; der Bot setzt sie
|
||||||
|
// zusammen und deckelt auf 5. Hier nur gestapelt darstellen.
|
||||||
|
// ⚠ Eigener Praefix MSPFX, damit sie beim Redraw sauber verschwinden, wenn
|
||||||
|
// der Bot keine MS-Zeile mehr schickt (sonst blieben Alt-Meldungen
|
||||||
|
// stehen — genau der Fehler, den die HL-Pfeile schon einmal hatten).
|
||||||
|
if(typ == "MS")
|
||||||
|
{
|
||||||
|
if(!InpShowMeldungen || k < 2) continue;
|
||||||
|
string mn = PFX + "MSG_" + IntegerToString(msg_idx);
|
||||||
|
if(ObjectFind(0, mn) < 0)
|
||||||
|
{
|
||||||
|
ObjectCreate(0, mn, OBJ_LABEL, 0, 0, 0);
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_XDISTANCE, 12);
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
|
||||||
|
ObjectSetString (0, mn, OBJPROP_FONT, "Arial");
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_FONTSIZE, InpMeldungSize);
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_SELECTABLE, false);
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_BACK, false);
|
||||||
|
}
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_YDISTANCE,
|
||||||
|
16 + msg_idx * (InpMeldungSize + 6));
|
||||||
|
ObjectSetString (0, mn, OBJPROP_TEXT, p[1]);
|
||||||
|
ObjectSetInteger(0, mn, OBJPROP_COLOR, InpMeldungColor);
|
||||||
|
msg_idx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// G/V der offenen Position — direkt UNTER dem Kurs (User-Wunsch 2026-07-30):
|
// G/V der offenen Position — direkt UNTER dem Kurs (User-Wunsch 2026-07-30):
|
||||||
// PL;wert;waehrung. Wert ist NETTO (Bot rechnet die WHT-Quellensteuer schon
|
// PL;wert;waehrung. Wert ist NETTO (Bot rechnet die WHT-Quellensteuer schon
|
||||||
// raus, wie im Dashboard). Gruen im Plus, rot im Minus. Ohne offene Position
|
// raus, wie im Dashboard). Gruen im Plus, rot im Minus. Ohne offene Position
|
||||||
|
|||||||
Reference in New Issue
Block a user