From c5190e77fda5906ad7c3ead2416514d8abaf375e Mon Sep 17 00:00:00 2001 From: Axel Hocks Date: Wed, 19 Aug 2026 18:10:07 +0200 Subject: [PATCH] M15-Auto-Entry: Richtung aus dem Veto + Abbruchregel verankert (1) Der Auto-Entry nimmt die Richtung jetzt aus bias.verboten (= die ERLAUBTE Richtung), also genau das, was die Karte anzeigt (app.js:504 nimmt erl). Kein Veto -> kein Entry, weil die Karte dort ausdruecklich keine Richtung gibt. Gegenprobe an der Live-Lage: verboten=SHORT, lesart=ab -> alt SHORT (die verbotene!), neu LONG = identisch zur Anzeige. Damit entspricht der Pfad der gemessenen Kontrolle C (-0,085/-0,030), der am wenigsten schlechten Variante -- aber weiterhin negativ. Die Korrektur behebt den Widerspruch, nicht den fehlenden Edge. (2) measurement_reminder.py: neue Messung m15_abbruch (>=20 AUTOM15_*-Trades, Latte Verhaeltnis < 1,0 ODER PF < 1) und Config-Anker auto_m15 (validiert false), dazu der Helfer _zaehle_setup(). Der Zaehler zaehlt nur geschlossene Trades. Damit kann die vorab fixierte Regel nicht mehr unbemerkt verfallen -- genau das war bei B5 wochenlang der Fall. Aktivierung steht aus: Backend-Aenderung, braucht einen Neustart. auto_m15 ist aus, also keine Eile -- der Neustart wartet, bis das Konto flat ist. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 25 +++++++++++++++++++++++++ core/engine.py | 22 ++++++++++++++++++++-- measurement_reminder.py | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 35bb412..cd52fbb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7615,6 +7615,31 @@ vorab fixiert wurde** — also wird sie NICHT gesenkt, sondern als **durch User-Entscheidung überstimmt** vermerkt. Wer sie ersetzen will, fixiert eine NEUE Latte **vor** der Beobachtung, auf einem NEUEN Zählfenster ab heute. +## ✅ M15-AUTO-ENTRY KORRIGIERT + ABBRUCHREGEL VERANKERT (2026-08-19, abends) + +**(1) Richtung kommt jetzt aus dem VETO, nicht aus der Lesart.** Der Auto-Entry +liest damit genau das, was die Karte **anzeigt** (`app.js:504` nimmt `erl`, die +erlaubte Richtung). Kein Veto → **kein Entry** (die Karte sagt dort +ausdrücklich „gibt hier keine Richtung“). +**Gegenprobe an der Live-Lage:** `verboten=SHORT, lesart=ab` → alt **SHORT** +(die verbotene!), **neu LONG** — identisch zur Anzeige. +⚠ Damit entspricht der Pfad der gemessenen **Kontrolle C** (HTF-Richtung, +ØR **−0,085 / −0,030**) — der **am wenigsten schlechten** der vier Varianten, +aber weiterhin **negativ**. Die Korrektur behebt den Widerspruch, nicht den +fehlenden Edge. + +**(2) Abbruchregel verankert** — `measurement_reminder.py`: neue Messung +`m15_abbruch` (≥ 20 `AUTOM15_*`-Trades, Latte Verhältnis < 1,0 ODER PF < 1) und +neuer Config-Anker `auto_m15` (validiert = `false`). Dazu der Helfer +`_zaehle_setup()`. ⚠ Der Zähler zählt nur **geschlossene** Trades — der eine +Trade vom 18:03 läuft noch, deshalb steht er korrekt auf 0. +**Damit kann die Regel nicht mehr unbemerkt verfallen** — genau das war bei B5 +wochenlang der Fall. + +⚠ **Aktivierung steht aus:** die Änderung ist Backend und braucht einen +Neustart. `auto_m15` ist **aus**, es besteht also keine Eile — der Neustart +wartet auf User-Wunsch, bis das Konto flat ist. + ## ⚠⚠⚠ M15-AUTO-ENTRY HANDELTE DIE VERBOTENE RICHTUNG — ABGESCHALTET (2026-08-19, 18:05) User: „der auto trader hat short eröffnet obwohl long angezeigt wurde“. diff --git a/core/engine.py b/core/engine.py index 2a3508e..36c0d08 100644 --- a/core/engine.py +++ b/core/engine.py @@ -1241,11 +1241,28 @@ class TradingEngine: if les not in ("auf", "ab"): self._m15_last_entry_sig = None return + # ⚠⚠ RICHTUNG AUS DEM VETO, NICHT AUS DER LESART (Korrektur 19.08.). + # Der erste Bau nahm `lesart` (= Backtest-Variante A) und eroeffnete + # am 18:03 SHORT, waehrend die Karte LONG anzeigte -- also die + # VERBOTENE Richtung. Die Anzeige (`app.js:504`) nimmt `erl`, die vom + # Veto ERLAUBTE Richtung; das ist die einzige beidhaelftig robuste + # Aussage der Karte (gegen das Signal -6,60 EUR/Lot ueber 1.216 + # Trades). Ein Auto-Entry auf eine ANGEZEIGTE Empfehlung muss lesen, + # was angezeigt wird -- sonst sind es zwei Quellen fuer eine Aussage. + # ⚠ Damit entspricht der Pfad jetzt am ehesten der gemessenen + # KONTROLLE C (HTF-Richtung, OeR -0,085/-0,030) -- der am wenigsten + # schlechten der vier Varianten, aber weiterhin NEGATIV. + verb = ((s.get("bias") or {}).get("verboten") or "").upper() + if verb not in ("LONG", "SHORT"): + # Kein Veto -> die Karte gibt ausdruecklich KEINE Richtung + # ("kein Trend-Veto", app.js:495). Dann auch kein Entry. + self._m15_last_entry_sig = None + return nah = s.get("nah") or {} lvl = nah.get("level") if lvl is None: return - d = 1 if les == "auf" else -1 # wie im Backtest + d = -1 if verb == "LONG" else 1 # = die ERLAUBTE Richtung sig = (d, round(float(lvl), 3)) if sig == self._m15_last_entry_sig: return # dieselbe Episode @@ -1278,7 +1295,8 @@ class TradingEngine: return self._m15_entry_count += 1 log.info(f"AUTO-M15-ENTRY: {want.upper()} auf gruene Karte " - f"(Lesart {les}, Level {lvl}) — selbstaendig eroeffnet") + f"(erlaubt, verboten={verb}, Lesart {les}, Level {lvl}) " + f"— selbstaendig eroeffnet") except Exception as e: log.warning(f"_check_auto_m15: {e}") diff --git a/measurement_reminder.py b/measurement_reminder.py index 914430a..d61ded9 100644 --- a/measurement_reminder.py +++ b/measurement_reminder.py @@ -48,6 +48,19 @@ def _days_since(iso: str) -> float: # ── Die offenen Messungen ──────────────────────────────────────────────────── # have = aktueller Stand · need = Schwelle · unit = Anzeigeeinheit # cmd = was zu tun ist, wenn fällig +def _zaehle_setup(muster: str) -> int: + """Geschlossene Trades mit `setup LIKE muster` (fuer die Abbruchregeln).""" + try: + import sqlite3 + with sqlite3.connect(DB) as c: + return c.execute( + "SELECT COUNT(*) FROM trades WHERE setup LIKE ?" + " AND exit_time IS NOT NULL AND pnl IS NOT NULL", (muster,) + ).fetchone()[0] + except Exception: + return 0 + + CHECKS = [ { # ⚠⚠ WIEDERVORLAGE aus dem Backtest vom 2026-08-12 @@ -213,6 +226,25 @@ CHECKS = [ "Ziel ist ein HINWEIS im Order-Dialog ('deine Trades in dieser " "Konstellation: X % WR, n=Y'), ausdrücklich KEIN Auto-Entry.", }, + { + # Diese Regel MUSS hier stehen: sie wurde am 19.08. vorab fixiert, und + # genau so eine Regel blieb bei B5 wochenlang unbemerkt, weil der Zaehler + # nirgends lief. Ohne Ueberwachung ist eine Abbruchregel keine Regel. + "key": "m15_abbruch", + "title": "M15-Auto-Entry: Abbruchpruefung (Latte vorab fixiert)", + "why": "Am 19.08. auf User-Wunsch GEGEN die Messung gebaut. " + "backtest_m15_auto.py: die Karte ist in BEIDEN Halbjahren negativ " + "(Lesart -0,162/-0,094; die jetzt gehandelte ERLAUBTE Richtung " + "entspricht Kontrolle C mit -0,085/-0,030). Zusaetzlich ist der " + "gebaute MARKT-Einstieg schlechter als der gemessene " + "Level-Einstieg. Erwartung: die Latte greift.", + "have": lambda: _zaehle_setup("AUTOM15%"), + "need": 20, "unit": "AUTOM15_*-Trades", + "cmd": "LATTE (vorab fixiert, NICHT verschiebbar): Verhaeltnis " + "(OeGewinn/OeVerlust) < 1,0 ODER PF < 1 -> auto_m15 = false " + "(Knopf M15). Dieselbe Latte wie squeeze_b5. Rechnung analog, " + "nur setup LIKE 'AUTOM15%'.", + }, { # ⚠ VORAB festgelegte Abbruchregel (User-Zustimmung 2026-08-01) — bewusst VOR # der Beobachtung fixiert, damit die Latte hinterher nicht verschoben wird. @@ -436,6 +468,13 @@ CONFIG_DEPS = [ "gelesen — Reaktivieren ginge nur über die Git-Historie bzw. " ".removed_backup/auto_signal_2026-08-12.py.", }, + { + "key": "auto_m15", "test": "backtest_m15_auto.py", "soll": "false", + "why": "Gemessen negativ (Lesart -0,162/-0,094; die gehandelte erlaubte " + "Richtung entspricht Kontrolle C, -0,085/-0,030 -- ebenfalls " + "negativ). Steht er auf 'true', laeuft ein gemessen negativer " + "Auto-Entry auf echtem Geld. Das soll sichtbar bleiben.", + }, { "key": "auto_squeeze", "test": "backtest_breakout_squeeze.py", # ⚠⚠ ERWARTUNG GEDREHT 2026-08-17: stand auf "true" und meldete deshalb