Gate 4 der M15-Karte: Ziel nur noch in der ERLAUBTEN Richtung

User-Fund: Karte zeigte "verboten SHORT" (= LONG erlaubt) UND ein Ziel
0,15 $ UNTER dem Kurs. Die Arithmetik war korrekt - aber fuer die
verbotene Richtung.

Ursache: das Ziel war schlicht das entferntere der beiden Level
(max nach gap), ohne Richtungspruefung. Strukturell steckte dahinter
ein Fade-Trade (Gegenlevel als Ziel = Mean Reversion) in einer Kette,
deren Gate 2 ein Trendfilter ist - zwei unvereinbare Konzepte. Damit
derselbe Fehler, wegen dem die Gesamtempfehlung entfernt wurde: aus
einem VERBOT wird ueber die Hintertuer wieder eine RICHTUNG.

Fix nach der gemessenen Population (backtest_m15_gates.py): Einstieg
am naechstgelegenen Level, Richtung = die vom HTF erlaubte. Ein Ziel
nur, wenn es jenseits dieses Einstiegs in der erlaubten Richtung
liegt; sonst "kein Ziel" mit Grund statt einer erfundenen Zahl.
Richtung steht jetzt im Anzeigetext.

- tests/test_m15_ziel.py (6 Tests, Invariante ueber 32 Konstellationen)
- Mutationsprobe: alte Zeile zurueck -> 4 von 6 Tests fallen
- deploy.py --feld unterstuetzt jetzt Punktpfade (m15_setup.ziel_grund)
- v=159

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-10 06:36:02 +02:00
co-authored by Claude Opus 5
parent b8705e297f
commit 5474c2be61
6 changed files with 293 additions and 30 deletions
+28 -10
View File
@@ -224,25 +224,43 @@ function renderM15(s) {
+ "Quote ist also eher noch etwas optimistisch. 4555 % bleibt ohne Richtung.";
// ── Reichweite (Kegel) — sagt WIE WEIT, nicht wohin ──────────────────
// ⚠ REINE GEOMETRIE: passt das Gegenlevel (= das Ziel) noch in das 80-%-Band
// des jeweiligen Horizonts? Keine Bruch-Annahme — die wäre nicht belegt.
// ⚠ REINE GEOMETRIE: passt das Ziel noch in das 80-%-Band des jeweiligen
// Horizonts? Keine Bruch-Annahme — die wäre nicht belegt.
// ⚠⚠ Die Richtung steht seit dem Fix vom 2026-08-10 MIT im Text. Vorher war
// das Ziel rein geometrisch das entferntere Level und stand real GEGEN das
// Veto aus ② („verboten SHORT" + Ziel 0,15 $ unter dem Kurs). Ein Ziel ohne
// genannte Richtung lässt sich still wieder verdrehen — mit genannter nicht.
const zi = s.ziel;
const r = s.reichweite || [];
const spanne = r.length
? " · Spanne " + r.map(x => `${x.minutes} ${f(x.lo, 2)}${f(x.hi, 2)}`).join(" · ")
: "";
const rEl = $("m15-reich");
if (zi && zi.horizonte && zi.horizonte.length) {
const drin = zi.horizonte.filter(x => x.drin).map(x => x.minutes);
const el = $("m15-reich");
el.className = "m15-item " + (drin.length ? "ok" : "warn");
el.textContent = drin.length
? `④ Ziel ${f(zi.level, 3)} erreichbar ab ${Math.min(...drin)} `
+ `(${zi.strecke} $ vom Kurs)`
: `④ Ziel ${f(zi.level, 3)} liegt AUSSERHALB des 120-Kegels `
const pfeil = zi.richtung === "LONG" ? "▲" : "▼";
rEl.className = "m15-item " + (drin.length ? "ok" : "warn");
rEl.textContent = drin.length
? `④ Ziel ${pfeil} ${f(zi.level, 3)} erreichbar ab ${Math.min(...drin)} `
+ `(${zi.strecke} $ vom Kurs, Einstieg ${f(zi.von, 3)})`
: `④ Ziel ${pfeil} ${f(zi.level, 3)} liegt AUSSERHALB des 120-Kegels `
+ `(${zi.strecke} $) — CRV zeitlich nicht gedeckt`;
} else if (s.ziel_grund) {
// Kein berechenbares Ziel ist ein EIGENER Zustand, keine Lücke —
// deshalb wird der Grund genannt statt eine Zahl erfunden.
rEl.className = "m15-item";
rEl.textContent = `④ kein Ziel — ${s.ziel_grund}${spanne}`;
} else {
$("m15-reich").className = "m15-item";
$("m15-reich").textContent = r.length
rEl.className = "m15-item";
rEl.textContent = r.length
? "④ erwartete Spanne · " + r.map(x => `${x.minutes} ${f(x.lo, 2)}${f(x.hi, 2)}`).join(" · ")
: "④ erwartete Spanne —";
}
rEl.title = "Reine Geometrie auf dem Kegel: liegt das Ziel im 80-%-Band des "
+ "Horizonts? Das Ziel wird NUR in der von ② erlaubten Richtung gebildet — "
+ "ein rein geometrisches Ziel zeigte am 10.08. auf die verbotene Seite. "
+ "Beim Ausbruchs-Einstieg gibt es kein berechenbares Ziel: _draw_levels "
+ "liefert bewusst nur die nächste Linie je Seite.";
// ── Veto: die eigene Bilanz, JE LOT ──────────────────────────────────
const v = s.veto || {};
+2 -2
View File
@@ -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=158">
<link rel="stylesheet" href="style.css?v=159">
</head>
<body>
<!-- Modul-Menü (ganz oben) -->
@@ -347,6 +347,6 @@
</div>
<div id="toast" class="toast hidden"></div>
<script src="app.js?v=158"></script>
<script src="app.js?v=159"></script>
</body>
</html>