S/R-Beschriftung: Chart und M15-Karte nannten verschiedene Zahlen (v1.35, v=169)

User: "die Beschriftung fuer S/R im Chart stimmt nicht mit der Analyse in der
M15-Karte ueberein."

Die LEVEL stimmten -- nur die Zahl daneben nicht. Live gegengeprueft: die CSV
enthielt R;82.069;69, Gate 3 der Karte meldete res 82.069 / p_break 69. Beide
kommen aus _draw_levels(), sind also per Konstruktion identisch; auch die
Distanzen sind exakt (0,477~0,48 / 0,909~0,91 / 0,455~0,45).

DER DEFEKT: das Chart schrieb die NACKTE Zahl = P(Bruch), die Karte klappte
unter 45 % still auf P(Abprall) um und nennt 45-55 % "unentschieden".

  P(Bruch) 33 %  ->  Chart "33%"   Karte "67 % Abprall"
  P(Bruch) 46 %  ->  Chart "46%"   Karte "unentschieden"
  P(Bruch) 72 %  ->  Chart "72%"   Karte "72 % Bruch"

Beide Zahlen richtig, aber die Chart-Zahl sagte nicht, WAS sie ist.
GEMESSEN in 88,1 % der Zeit verschieden (1.797 Vorhersagen / 14 Tage: 66,3 %
unter 45 %, 21,9 % im unentschiedenen Band).

Behoben im Indikator v1.35, wortgleich zu app.js. Ueber 1.678 echte
P(break)-Werte gegengeprueft: Uebereinstimmung 0 % -> 100 %.
Ins RICHTIGE Terminal kompiliert (es gibt real zwei Ordner, nur D0E8209F...
bekommt die sr_levels.csv): 0 errors, 0 warnings, .ex5 frisch, Version im
Terminal gegengeprueft.

Zwei Verdachtsmomente ausgeschlossen statt vermutet: eine stehengebliebene
Alt-Linie (der Indikator ruft ObjectsDeleteAll bei jedem Redraw) und ein falsch
einsortiertes Level (_draw_levels waehlt seit 23.07. nach Lage zum Kurs).

ZWEITER Befund derselben Klasse, ebenfalls behoben: Gate 3 und 3b nannten Level
aus VERSCHIEDENEN Zeitebenen, beide nur als "xATR" --
  3   M30-Pivots, ATR_M15, im Chart gezeichnet
  3b  M5-Pivots,  ATR_M5,  NICHT gezeichnet
Real standen "0,48xATR" und "0,45xATR" nebeneinander, die nicht vergleichbar
sind, und die Karte nannte einen "Support 81,78", den man im Chart vergeblich
sucht (alle 10 M30-Pivots lagen ueber dem Kurs).
Die Quellen-Trennung BLEIBT -- entry_room_atr=0,6 ist ueber 80k Bars auf M5
kalibriert. Geaendert wurde nur die Beschriftung plus Tooltips.

Reine Anzeige: an Gates, Gewichten und Order-Logik nichts geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-13 16:06:06 +02:00
co-authored by Claude Opus 5
parent 95521d041c
commit 77ed1d5572
4 changed files with 107 additions and 14 deletions
+54 -1
View File
@@ -4315,7 +4315,7 @@ Trader wäre sie nie abgelaufen. Latte unverändert: Verhältnis < 1,0 ODER PF <
(„⚠ die Welle (steuert die Order) schweigt"). („⚠ die Welle (steuert die Order) schweigt").
Live gegengerechnet, beide Zeilen erscheinen wie beabsichtigt. Live gegengerechnet, beide Zeilen erscheinen wie beabsichtigt.
⚠ Reine Anzeige — an Gewichten, Gates und Order-Logik ist nichts geändert. ⚠ Reine Anzeige — an Gewichten, Gates und Order-Logik ist nichts geändert.
- Asset-Version aktuell **v=168** (in `web/index.html` hochzählen, siehe Workflows). - Asset-Version aktuell **v=169** (in `web/index.html` hochzählen, siehe Workflows).
- **✅ SCHRIFT SKALIERT MIT DEM FENSTER (2026-08-13, v=167).** User: „die Größe der - **✅ SCHRIFT SKALIERT MIT DEM FENSTER (2026-08-13, v=167).** User: „die Größe der
Schriftarten im Dashboard auf em einstellen, damit auf jedem Gerät oder je nach Schriftarten im Dashboard auf em einstellen, damit auf jedem Gerät oder je nach
Fenstergröße die Schriftgröße automatisch angepasst wird." Fenstergröße die Schriftgröße automatisch angepasst wird."
@@ -5405,6 +5405,59 @@ nicht führbar — und Schritt 4 ist der EINZIGE belastbare Nachweis, dass neuer
Python-Code läuft. Jetzt mit **Punktpfaden**; ein Feld mit Wert `None` zählt als Python-Code läuft. Jetzt mit **Punktpfaden**; ein Feld mit Wert `None` zählt als
vorhanden (geprüft wird der Schlüssel, nicht der Inhalt). vorhanden (geprüft wird der Schlüssel, nicht der Inhalt).
### ⚠⚠ CHART UND M15-KARTE NANNTEN FÜR DASSELBE LEVEL VERSCHIEDENE ZAHLEN (Fix 2026-08-13, v1.35 / v=169)
User: „die Beschriftung für S/R im Chart stimmt nicht mit der Analyse in der
M15-Karte überein."
**Die LEVEL stimmten — nur die Zahl daneben nicht.** Live gegengeprüft: die
CSV, die der Indikator liest, enthielt `R;82.069;69`, und Gate ③ der Karte
meldete `nah: res 82.069, p_break 69`. Beide kommen aus `_draw_levels()`, sind
also per Konstruktion identisch. Auch die Distanzen sind exakt gerechnet
(nachgerechnet 0,477≈0,48 · 0,909≈0,91 · 0,455≈0,45).
⚠⚠ **DER DEFEKT: das Chart schrieb die NACKTE Zahl, die Karte klappte still auf
den Gegenwert um.**
| P(Bruch) | Chart (v1.34) | M15-Karte (`app.js` `lesart()`) |
|---|---|---|
| 33 % | `Widerstand 82.069 · **33%**` | `Widerstand 82.069 → **67 % Abprall**` |
| 46 % | `… · **46%**` | `… → **unentschieden**` |
| 72 % | `… · **72%**` | `… → **72 % Bruch**` |
Beide Zahlen waren **richtig** — die eine P(Bruch), die andere P(Abprall) — aber
die Chart-Zahl sagte nicht, WAS sie ist. **Gemessen betraf das 88,1 % der Zeit**
(1.797 Vorhersagen/14 Tage: 66,3 % lagen unter 45 %, 21,9 % im unentschiedenen
Band; nur 11,9 % über 55 %, wo beide dieselbe Zahl zeigen).
**Behoben im Indikator (v1.35), wortgleich zu `app.js`:** `69% Bruch` /
`unentschieden` / `67% Abprall`. Über **1.678 echte** P(break)-Werte gegengeprüft:
Übereinstimmung **0 % → 100 %**.
⚠ Die Formulierung lebt jetzt an ZWEI Stellen (MQL5 + `app.js`) — wer eine
ändert, muss die andere mitziehen; beide tragen einen Hinweis darauf. Ein
gemeinsamer Text aus dem CSV wäre sauberer, hätte aber das Format gebrochen.
**Kompiliert ins RICHTIGE Terminal** (der dokumentierte Fallstrick): es gibt
real **zwei** Ordner, nur `D0E8209F…` bekommt die `sr_levels.csv`
(`0BA5CADA…` nicht). `MetaEditor64.exe /compile`**0 errors, 0 warnings**,
`.ex5` frisch, `#property version "1.35"` im Terminal gegengeprüft.
**Zwei Verdachtsmomente ausgeschlossen, statt sie zu vermuten:** (a) eine
stehengebliebene Alt-Linie — der Indikator ruft `ObjectsDeleteAll(0, PFX)` bei
jedem Redraw; (b) ein falsch einsortiertes Level — `_draw_levels` wählt seit dem
Fix vom 23.07. nach **Lage zum Kurs**, nicht nach Entstehungstyp. ⚠ Nebenbefund:
82.069 stammt aus `pl` (einem Pivot-**Tief**) und wird korrekt als Widerstand
geführt, weil der Kurs darunter steht — das sieht im Chart nur ungewohnt aus.
**ZWEITER, unabhängiger Befund derselben Klasse — behoben:** Gate ③ und ③b
nannten Level aus **verschiedenen Zeitebenen**, beide nur als „×ATR":
| | Level-Quelle | ATR | im Chart gezeichnet? |
|---|---|---|---|
| **③** | M30-Pivots (`_draw_levels`) | **ATR_M15** | **ja** |
| **③b** | M5-Pivots (`room_info`) | **ATR_M5** | **nein** |
Real standen damit „0,48×ATR" und „0,45×ATR" nebeneinander, die **nicht
vergleichbar** sind — und die Karte nannte einen „Support 81,78", den man im
Chart vergeblich sucht. ⚠ Verschärfend: zum Prüfzeitpunkt lagen **alle 10
M30-Pivots über dem Kurs**, es gab also gar keine Support-Linie im Chart.
✅ Die Quellen-Trennung **bleibt**`entry_room_atr=0,6` ist über 80k Bars auf
M5 kalibriert, sie umzustellen wäre eine Strategie-Änderung. Geändert wurde nur
die Beschriftung: `③ Widerstand M30 82.069 (Chart · 0,48×ATR_M15)` gegen
`③b … Raum ▲ 0,91×ATR_M5 / ▼ 0,45×ATR_M5`. Die Tooltips nennen den Unterschied
ausdrücklich. **Reine Anzeige — an Gates, Gewichten und Order-Logik nichts.**
### ✅ 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?"
+27 -5
View File
@@ -12,7 +12,15 @@
//| 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.34" #property version "1.35"
// 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").
// Das Label trug seit v1.27 die NACKTE Zahl = P(Durchbruch); die Karte klappt
// unter 45 % auf P(Abprall) um und nennt 45-55 % „unentschieden". Dasselbe
// Level stand damit im Chart als „33%" und in der Karte als „67 % Abprall" —
// beide Zahlen richtig, aber die Chart-Zahl sagte nicht, WAS sie ist.
// GEMESSEN in 88,1 % der Zeit verschieden (1.797 Vorhersagen/14 Tage).
// Jetzt: „69% Bruch" / „unentschieden" / „67% Abprall" — identisch zu app.js.
// v1.34 (2026-08-01): HYPERLIQUID-KURS (HL;...) unter Kurs und G/V oben rechts, // 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 // bernstein. HL handelt 24/7, Pepperstone nicht - am Wochenende der einzige
// lebende Kurs; die Basis (~0,45 $ Kontrakt-Differenz) ist herausgerechnet, // lebende Kurs; die Basis (~0,45 $ Kontrakt-Differenz) ist herausgerechnet,
@@ -472,13 +480,27 @@ void Redraw()
double price = StringToDouble(p[1]); double price = StringToDouble(p[1]);
if(price <= 0) continue; if(price <= 0) continue;
// Feld 3 (optional) = P(Durchbruch) in % aus dem kalibrierten Modell des // Feld 3 (optional) = P(Durchbruch) in % aus dem kalibrierten Modell des
// Bots. Niedrig = Level haelt eher, hoch = bricht eher. Im LABEL steht nur // Bots. Niedrig = Level haelt eher, hoch = bricht eher.
// die nackte Zahl („Widerstand 84.536 · 34%", User-Wunsch 2026-07-30); // ⚠⚠ WORTGLEICH ZUR M15-KARTE (Fix 2026-08-13, v1.35, User: „die
// der ausgeschriebene Hinweis bleibt im Tooltip der Linie. // Beschriftung fuer S/R im Chart stimmt nicht mit der Analyse in der
// M15-Karte ueberein"). Hier stand bis dahin die NACKTE Zahl = P(Bruch).
// Die Karte (`app.js` lesart()/pTxt()) klappt unter 45 % aber auf den
// GEGENWERT P(Abprall) um und nennt 4555 % „unentschieden" — dasselbe
// Level trug damit im Chart „33%" und in der Karte „67 % Abprall".
// Beide Zahlen waren richtig, aber die Chart-Zahl sagte nicht, WAS sie
// ist. GEMESSEN betraf das 88,1 % der Zeit (1.797 Vorhersagen/14 Tage:
// 66,3 % lagen unter 45 %, 21,9 % im unentschiedenen Band).
// ➜ Wer die Formulierung hier aendert, muss `lesart()` in app.js
// mitaendern — sonst laufen sie wieder auseinander.
string lbl = (typ=="R" ? "Widerstand " : "Unterstuetzung ") string lbl = (typ=="R" ? "Widerstand " : "Unterstuetzung ")
+ DoubleToString(price, (int)_Digits); + DoubleToString(price, (int)_Digits);
if(InpShowPBreak && k > 2 && StringLen(p[2]) > 0) if(InpShowPBreak && k > 2 && StringLen(p[2]) > 0)
lbl += " · " + p[2] + "%"; // nur die Zahl (User-Wunsch 2026-07-30) {
int pb = (int)StringToInteger(p[2]);
if(pb >= 45 && pb <= 55) lbl += " · unentschieden";
else if(pb > 55) lbl += " · " + IntegerToString(pb) + "% Bruch";
else lbl += " · " + IntegerToString(100-pb) + "% Abprall";
}
color col = (typ=="R" ? InpResColor : InpSupColor); color col = (typ=="R" ? InpResColor : InpSupColor);
string nm = PFX + typ + "_" + IntegerToString(idx); string nm = PFX + typ + "_" + IntegerToString(idx);
if(ObjectCreate(0, nm, OBJ_HLINE, 0, 0, price)) if(ObjectCreate(0, nm, OBJ_HLINE, 0, 0, price))
+24 -6
View File
@@ -219,11 +219,22 @@ function renderM15(s) {
const q = bricht ? `${p} % Bruch` : `${100 - p} % Abprall`; const q = bricht ? `${p} % Bruch` : `${100 - p} % Abprall`;
return `${q}, eher ${auf ? "aufwärts ▲" : "abwärts ▼"}`; return `${q}, eher ${auf ? "aufwärts ▲" : "abwärts ▼"}`;
}; };
// ⚠⚠ ZEITEBENE MIT IM TEXT (Fix 2026-08-13). ③ liest M30-Level und misst in
// ATR_M15, ③b liest M5-Level und misst in ATR_M5. Beide standen vorher nur als
// „×ATR" da — zwei Zahlen nebeneinander (0,48 und 0,45), die vergleichbar
// AUSSAHEN und verschiedene Bezugsgroessen hatten. Die Quellen-Trennung ist
// Absicht (`entry_room_atr=0,6` ist auf M5 kalibriert), die stumme
// Beschriftung war es nicht.
// ⚠ „(Chart)" markiert, dass GENAU diese Linie im MT5-Chart gezeichnet wird —
// die M5-Level aus ③b werden dort NICHT gezeichnet.
$("m15-zone").textContent = z.length $("m15-zone").textContent = z.length
? "③ " + z.map(x => `${x.seite === "res" ? "Widerstand" : "Support"} ` ? "③ " + z.map(x => `${x.seite === "res" ? "Widerstand" : "Support"} M30 `
+ `${f(x.level, 3)} (${f(x.gap_atr15)}×ATR)${lesart(x)}`).join(" · ") + `${f(x.level, 3)} (Chart · ${f(x.gap_atr15)}×ATR_M15)${lesart(x)}`).join(" · ")
: "③ kein Level in Sicht"; : "③ kein Level in Sicht";
$("m15-zone").title = "Richtungs-Lesart BEDINGT auf das Level, keine freie " $("m15-zone").title = "GENAU diese Linie wird im MT5-Chart gezeichnet (M30-Pivots, "
+ "geclustert) — der Chart nennt seit v1.35 dieselbe Zahl mit denselben Worten. "
+ "⚠ Die Level in ③b stammen dagegen aus M5 und stehen NICHT im Chart. "
+ "Richtungs-Lesart BEDINGT auf das Level, keine freie "
+ "Prognose: eine solche ist gemessen unmöglich (AUC 0,50 out-of-sample und " + "Prognose: eine solche ist gemessen unmöglich (AUC 0,50 out-of-sample und "
+ "nur 0,52 in-sample — es steckt keine Richtungsinformation in den Daten). " + "nur 0,52 in-sample — es steckt keine Richtungsinformation in den Daten). "
+ "P(break) fragt stattdessen „hält diese Struktur?“ und ist out-of-sample " + "P(break) fragt stattdessen „hält diese Struktur?“ und ist out-of-sample "
@@ -275,7 +286,7 @@ function renderM15(s) {
const seite = (o, lbl) => { const seite = (o, lbl) => {
if (!o) return null; if (!o) return null;
if (o.level == null) return `${lbl} frei`; if (o.level == null) return `${lbl} frei`;
return `${lbl} ${o.dist_atr}×ATR${o.frei ? "" : " ⚠"}`; return `${lbl} ${o.dist_atr}×ATR_M5${o.frei ? "" : " ⚠"}`;
}; };
if (mo.block) { if (mo.block) {
// Der Motor blockt — das ist die Information, die gefehlt hat. // Der Motor blockt — das ist die Information, die gefehlt hat.
@@ -300,14 +311,21 @@ function renderM15(s) {
moEl.className = "m15-item"; moEl.className = "m15-item";
moEl.textContent = "③b Motor —"; moEl.textContent = "③b Motor —";
} }
// ⚠ „M5" und „×ATR_M5" ausgeschrieben: diese Level stammen aus einer ANDEREN
// Zeitebene als ③ (M30) und werden im Chart NICHT gezeichnet. Ohne den Zusatz
// sucht man die genannte Linie dort vergeblich.
const teile = [seite(rm.long, "▲"), seite(rm.short, "▼")].filter(Boolean); const teile = [seite(rm.long, "▲"), seite(rm.short, "▼")].filter(Boolean);
if (teile.length) { if (teile.length) {
moEl.textContent += ` · Raum ${teile.join(" / ")}` moEl.textContent += ` · Raum ${teile.join(" / ")}`
+ (rm.gate ? ` (Gate ${rm.gate})` : ""); + (rm.gate ? ` (Gate ${rm.gate})` : "");
} }
moEl.title = "Was der Signal-Motor GERADE blockt, plus der Raum zum nächsten " moEl.title = "Was der Signal-Motor GERADE blockt, plus der Raum zum nächsten "
+ "Gegenlevel je Richtung (M5 — dieselbe Rechnung wie das Gate selbst, kein " + "Gegenlevel je Richtung. ⚠ Quelle sind M5-Pivots und ATR_M5 — eine ANDERE "
+ "Nachbau). Unter 0,6×ATR ist der Ertrag am Level gedeckelt: gemessen " + "Zeitebene als ③ (M30-Level, ATR_M15), und diese Linien werden im Chart NICHT "
+ "gezeichnet. Das ist Absicht: entry_room=0,6 ist über 80k Bars auf M5 "
+ "kalibriert. Die beiden ×ATR-Zahlen sind deshalb NICHT vergleichbar. "
+ "Dieselbe Rechnung wie das Gate selbst, kein "
+ "Nachbau. Unter 0,6×ATR ist der Ertrag am Level gedeckelt: gemessen "
+ "ØR 0,119/0,067 bei PF 0,42/0,66 — Trefferquote hoch und trotzdem " + "ØR 0,119/0,067 bei PF 0,42/0,66 — Trefferquote hoch und trotzdem "
+ "Verlust. ⚠ Gate ③ liest dieselbe Nähe als GUT (ruhende Order AM Level), " + "Verlust. ⚠ Gate ③ liest dieselbe Nähe als GUT (ruhende Order AM Level), "
+ "entry_room als SCHLECHT (Markt-Einstieg mit dem Level als Hindernis). " + "entry_room als SCHLECHT (Markt-Einstieg mit dem Level als Hindernis). "
+2 -2
View File
@@ -6,7 +6,7 @@
<meta name="theme-color" content="#0d1117"> <meta name="theme-color" content="#0d1117">
<title>Oil · MT5</title> <title>Oil · MT5</title>
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="style.css?v=168"> <link rel="stylesheet" href="style.css?v=169">
</head> </head>
<body> <body>
<!-- Modul-Menü (ganz oben) --> <!-- Modul-Menü (ganz oben) -->
@@ -356,6 +356,6 @@
</div> </div>
<div id="toast" class="toast hidden"></div> <div id="toast" class="toast hidden"></div>
<script src="app.js?v=168"></script> <script src="app.js?v=169"></script>
</body> </body>
</html> </html>