Commit Graph
204 Commits
Author SHA1 Message Date
Axel HocksandClaude Opus 5 cdee6eced7 Kosten-Gate gegen Stunden-Gate gemessen: Nachtsperre ist auf falscher Population begruendet
backtest_cost_gate.py — echte _squeeze_one, kanonischer Exit, Echtkosten,
80k M5, 2 Halbjahre, geteilte Entry-Liste + sequentielle 1-Slot-Sim.

(a) Kein Kosten-Gate ersetzt das Stunden-Gate nach der vorab fixierten Regel.
(b) Das Stunden-Gate selbst kostet in BEIDEN Haelften: sequentiell SigmaR
    -42 (H1) / -243 (H2) gegen "kein Gate". Die geblockten Ausbrueche sind
    in beiden Haelften positiv (OeR +0,496/+0,589).

Mechanismus belegt: die Nacht-Kostenfalle ist echt (alle Nacht-Bars Median
0,333 / Mittel 0,387 xATR, reproduziert backtest_realcosts), gilt aber nicht
fuer Squeeze-Ausbrueche (0,183/0,191 = Tag-Niveau). Der Squeeze verlangt
anziehenden ATR und selektiert sich damit aus der Falle heraus. Gemessen am
Wellensignal, angewandt auf den Squeeze = Deployment-Drift Fall 6.

KEINE Aenderung vorgenommen: Slippage ist nicht modelliert (groesste
Bedrohung des Befunds), die duenne Live-Stichprobe sagt das Gegenteil, und
der Beaufsichtigungs-Grund ist eine Praeferenz. auto_squeeze_skip_night
bleibt true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:17:03 +02:00
Axel HocksandClaude Opus 5 c9f1e8d039 Zeitzonen-Bug in analyze_tageszeit.py behoben + Squeeze-Nachtsperre 05.08. dokumentiert
Zeitzone: datetime.fromtimestamp(rates["time"], UTC+3) behandelt den MT5-
Bar-Zeitstempel als echten UTC-Epoch - MT5 liefert dort aber bereits die
Broker-Wallclock. Jede Stunde war 3 h zu spaet einsortiert. Empirisch gegen
die Wallclock geprueft (letzte Bar 11:00 statt real 08:00). Helfer _berlin()
mit korrekter Konvention; Rest des Projekts war nicht betroffen (geprueft).

Neu gerechnet: ALLE VIER Tagesbloecke kippen zwischen den Haelften - es gibt
gar kein Tageszeit-Muster. Der zuvor gemeldete "Nachmittag robust negativ"
war der um 3 h verschobene Abend. Plausibilitaetstest, der es entlarvt haette:
die duennen Stunden (n~650) muessen am Marktschluss liegen, nicht nachts.

Squeeze 05.08.: 5 active-Ausbrueche zwischen 02:00 und 07:30 Berlin, alle von
auto_squeeze_skip_night geblockt; Bot war ab 01:15 flat, also alleiniger
Blocker. Mit kanonischem Exit + Echtkosten Sigma +3,56 R (~+95 EUR), davon
92 % in zwei Trades - n=5 an einem Tag ist kein Gegenbeleg zum Guard.
Messbarer Ansatz notiert: kosten- statt stundenbasiertes Gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:07:25 +02:00
Axel HocksandClaude Opus 5 d75789ac72 Tageszeit-Drift gemessen: Morgens-runter/Nachmittags-rauf widerlegt
analyze_tageszeit.py misst die ROHE Kursdrift je Berliner Stunde (nicht den
Signal-Edge). 80k M5-Bars, DST-korrekt, 2 Halften, Ueberschuss gegen den
Tagesschnitt.

Ergebnis: Vormittag 08-12 kippt zwischen den Halften, Nachmittag 14-18 ist
robust NEGATIV - beide Halften der Vermutung fallen durch. Groessenordnung
ohnehin unter dem Spread (staerkste robuste Stunde ~0,03 $/h vs 0,0225 $
Spread).

Korrektur am eigenen Skript: der erste Entwurf hatte einen ATR-Filter
(< 0,06 uebersprungen) plus ATR-Normierung. Der Filter verwarf ausgerechnet
die ruhigen Morgenstunden der aelteren Periode (n 138-391 statt 1740) und
erzeugte so den vermeintlichen Befund. Beides entfernt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 18:08:22 +02:00
Axel HocksandClaude Opus 5 6af4c868bc Feste Einsatz-Margin (UI-Feld) + lokale Sprachausgabe via Piper
EINSATZ-FELD (User-Wunsch): Laufzeitwert MANUAL_MARGIN in core/config.py
(set/get_manual_margin, Muster wie set_margin_buffer). 0 = automatisch wie bisher
(margin_buffer_pct % der freien Margin), > 0 = Position wird auf genau diesen
Margin-Einsatz gerechnet.
- calc_lots setzt es um und DECKELT auf freie Margin x Buffer; ein zu hoher
  Wunschwert wird begrenzt und geloggt statt an den Broker durchgereicht. Reicht
  der Betrag nicht fuers Mindestlot -> 0.0 + Warnung, Trade sauber abgelehnt.
- Vorrang vor dem Risiko-Modus in trader._send_locked: eine ausdrueckliche
  Groessenvorgabe schlaegt die Rechenregel.
- Wirkt auf ALLE neuen Positionen, auch die autonomen.
- UI-Feld "Einsatz" in der ORDER-Leiste (nicht in der Trade-Leiste: die ist nur
  bei offener Position sichtbar, der Einsatz muss vorher einstellbar sein),
  bernstein umrandet solange gesetzt. Enter blurrt nur, change sendet einmal.
- POST /api/manualmargin, Snapshot manual_margin, neustart-fest ueber
  runtime_state.json. Ende-zu-Ende getestet (250 -> Snapshot -> 0 -> persistiert).
- Lot-Logik isoliert geprueft: 200 EUR -> 0,58 Lots; 5000 EUR -> gedeckelt.

SPRACHAUSGABE: Piper lokal (tools/speak.py). Windows-TTS funktioniert zwar, aber
es ist KEINE deutsche Stimme installiert - weder SAPI5 noch OneCore (nur
David/Zira/Mark, en-US); deutscher Text kaeme mit englischer Aussprache.
Add-WindowsCapability scheitert ohne Adminrechte.
Piper gewaehlt: laeuft lokal (passt zum Rest - WireGuard-only, Secrets in der
ini, keine Cloud), kostet nichts, aus PowerShell/Python aufrufbar. Stimme
thorsten-medium (de_DE), Real-Time-Faktor 0,08 (4,3 s Audio in 0,36 s).

Das ZIP entpackt eine Ebene tiefer als erwartet (tools/piper/piper/piper.exe) -
speak.py SUCHT Binary und Modell statt Pfade fest zu verdrahten. Der erste
Entwurf scheiterte daran; der Fail-safe meldete die Pfade sauber statt stumm zu
bleiben. Drei Modi getestet (Argument, Pipe, --wav).

tools/piper/ ist gitignored (Binaries + 60-MB-Modell), speak.py versioniert.
v=136.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 17:31:58 +02:00
Axel HocksandClaude Opus 5 33b6b8f629 Letzte Trades: 5 -> 10 (User-Wunsch)
Zwei unabhaengige Begrenzungen mussten mitgezogen werden:
- engine.snapshot -> history.last_closed_trades(5) -> (10)
- app.js -> slice(0, 5) -> slice(0, 10)
Nur eine davon zu aendern haette still weiter 5 gezeigt; beide sind jetzt
gegenseitig im Kommentar vermerkt.

Verifiziert: Snapshot liefert 10 Trades, v=135 ausgeliefert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 17:10:31 +02:00
Axel HocksandClaude Opus 5 1c976cc8fd M30-Level-Umstellung live gegengeprueft — bestaetigt, Normierung war entscheidend
Faellige Messung aus dem Reminder (28/30 erreicht). S/R-Auto-Closes vor/nach der
Umstellung der Level-Quelle M5 -> M30 am 30.07.

  Zeitraum              n   Med.Lots   EUR/Lot   O Move
  vorher (M5-Level)    89     0,81     +17,53    0,202 $
  nachher (M30-Level)  28     0,53     +36,92    0,427 $

Ertrag je Lot mehr als verdoppelt, O-Kursbewegung je Trade ebenfalls - deckt sich
mit der Backtest-Erwartung und mit dem Mechanismus (M30-Level liegen 1,95xATR
auseinander statt 0,61xATR, der Trade laeuft laenger).

DIE NORMIERUNG WAR ENTSCHEIDEND, sonst waere der Schluss falsch gewesen:
unnormiert sah der 04.08. wie der Treiber aus (O +55,41 EUR je Trade gegen
+19,30 im Rest). Je Lot ist heute aber praktisch identisch zum Rest (+38,81 vs
+35,87) - der Unterschied war reine Positionsgroesse (Median 1,36 statt 0,46
Lots, weil das Konto an dem Tag von ~800 auf ~1.400 EUR wuchs). O-EUR-Vergleiche
ueber Zeitraeume mit unterschiedlicher Positionsgroesse sind ungueltig.

NICHT der Level-Quelle allein zuzuordnen: am 31.07. kamen P(break)-Nachtraining
und Schwelle 0,55->0,35 dazu. Getrennt: 30.07. (nur M30-Level, altes Modell)
n=8, +19,88 EUR/Lot; ab 31.07. (M30 + neues Modell) n=20, +43,73 EUR/Lot. Das
Fenster mit nur der Umstellung ist zu klein. Der kombinierte Effekt ist
bestaetigt, die Ursachenaufteilung nicht.

Messung im measurement_reminder ausgetragen (mit Ergebnis als Kommentar).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 16:59:12 +02:00
Axel HocksandClaude Opus 5 e558a8dd5b Reminder: Stufe 2 "Manuelle Trades" eingetragen
Neue Messung manual_ctx im measurement_reminder: faellig bei >=300 manuellen
Trades mit gefuelltem ctx_*-Kontext (Sammlung laeuft seit 04.08.).

Die Faelligkeitsbedingung ist pruefbar (Zeilenzahl), nicht nur ein Datum - wie
alle anderen Eintraege auch. Der cmd-Text haelt die Methode fest (Fit auf der
ersten Haelfte, validiert auf der zweiten, AUC + Kalibrierung wie bei
backtest_pbreak_retrain.py) UND die Einschraenkung: 300 reichen fuer eine ERSTE
SICHTUNG, nicht fuer ein Urteil - mit ~150 je Haelfte und mehreren Merkmalen ist
die Overfit-Gefahr hoch. Ziel bleibt ein Hinweis im Order-Dialog, ausdruecklich
kein Auto-Entry.

Ohne diesen Eintrag waere die Sammlung genau so liegen geblieben wie die
P(break)-Genauigkeit, die 2213 auswertbare Zeilen hatte bevor jemand hinsah.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 16:42:29 +02:00
Axel HocksandClaude Opus 5 da7d8f5b90 Stufe 1: voller Entscheidungskontext beim Einstieg + Karte "Manuelle Trades"
Frage: kann der Bot aus den manuellen Trades lernen? Vorpruefung: noch NICHT.
1) Die entscheidenden Merkmale wurden nie gespeichert - beim Einstieg nur 5
   Felder, davon ai_sentiment in 1,4 % und news_score in 34 % befuellt.
2) Das naive Lernziel ("wann steigt er ein") braucht unbeschriftete Negative;
   brauchbar ist nur "welche Einstiege liefen gut" (Labels ueber P&L).
3) Die scheinbaren Muster sind Einzeltage: Stunde 13:00 zeigt +478 EUR ueber
   n=69, davon +382 EUR (80 %) aus den fuenf Trades des 04.08.

Gebaut wurde Stufe 1 - reine Telemetrie, kein Verhalten:
- trades um 16 ctx_*-Spalten erweitert (DB-Backup .bak-2026-08-04, 1.148 Zeilen
  unveraendert): p_break_target/-stop, dist_res_atr/dist_sup_atr, structure,
  squeeze, htf_trend/h1_trend, spread_atr, session, block_reason, conf_pct,
  atr_m5, bias, cone_pos, hour
- log_trade_open haengt die Spalten dynamisch an und ignoriert unbekannte
  Schluessel -> aeltere DB ohne Migration laeuft weiter (fail-open)
- Kette: engine._run_analysis -> trader.set_open_context(ctx=) -> log_trade_open

Fallstrick beim Bau: wave_snap existiert in _run_analysis NICHT (nur in
snapshot()). Der erste Entwurf haette einen NameError erzeugt, den das umgebende
except still geschluckt haette - der Kontext waere dauerhaft leer geblieben ohne
dass es auffaellt. Jetzt self.wave.snapshot(); vd zusaetzlich per locals()-Guard.

Verifiziert auf einer DB-KOPIE: alle 16 Spalten korrekt geschrieben, unbekannter
Schluessel ignoriert, Basisfelder unberuehrt. Snapshot liefert manual_stats.

Dashboard-Karte "Manuelle Trades" (#card-manual, v=134): heute / 30 Tage /
gesamt / Bot-Vergleich plus Split mit vs ohne Signal-Deckung. Backend
history.manual_stats(30) mit ~120-s-Cache wie _alignment_cached. Bewusst neutral
gefaerbt und deskriptiv; eine Reifegrad-Zeile nennt die ctx-Abdeckung (heute
0 %), damit die Karte nicht ueberschaetzt wird.

Stufe 2 NICHT gebaut: erst bei ausreichender ctx-Abdeckung messen, was Gewinner
von Verlierern unterscheidet (Fit H1, validiert H2, AUC + Kalibrierung). Ergebnis
waere ein Hinweis im Order-Dialog, ausdruecklich KEIN Auto-Entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 16:34:26 +02:00
Axel HocksandClaude Opus 5 7432be0e8c M30-Filter nach Vola-Regime geprueft — Hypothese invertiert, keine Aenderung
Anlass: Am 04.08. fiel WTI -4,12 $ (davon -4,16 $ in EINER Stunde), der Bot stand
zu 93 % auf WARTEN, htf_counter blockte 160-mal. Hypothese: die nachlaufende
M30-EMA sperrt in schnellen Umkehrungen das Richtige.

Die Messung invertiert die Hypothese. Geblockte Signale, kanonischer Exit,
Echtkosten, nach ATR-Terzil x 2 Halbjahre:

  Terzil    geblockt H1  geblockt H2  durchgel. H1  durchgel. H2
  niedrig      -0,086       +0,107       -0,136        -0,134
  mittel       -0,172       +0,067       -0,198        -0,069
  hoch         -0,625       -0,329       -0,061        +0,014

Im HOHEN Terzil sind die geblockten Signale mit Abstand die schlechtesten des
gesamten Datensatzes (PF 0,15 / 0,42) - der Filter ist dort am wertvollsten,
nicht am schaedlichsten. Die durchgelassenen Hoch-Vola-Signale in H2 sind das
einzige positive Feld der ganzen Tabelle. In den unteren Terzilen kippen die
geblockten Signale zwischen den Haelften = Rauschen.

Den Filter in schnellen Bewegungen zu lockern waere die schlechtestmoegliche
Aenderung gewesen. 22. verworfener Eingriff.

Auflösung des scheinbaren Widerspruchs: die 160 geblockten Signale und die 17
manuellen Gewinn-Trades desselben Tages sind VERSCHIEDENE Grundgesamtheiten. Die
manuellen Trades liefen alle auf rec=WARTEN, stammen also gar nicht aus der
Signal-Logik - der Filter hat den User nie gebremst. "Das Gate blockte X" und
"der Mensch verdiente Y" gehoeren nur zusammen, wenn Y aus X stammt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 16:20:18 +02:00
Axel HocksandClaude Opus 5 20137a3dd1 SL-Breite gemessen: Confounder bestaetigt, aber keine Aenderung (Regel greift)
Anlass: analyze_manual_close.py fand +1.229 EUR auf der Verlustseite, mit dem
explizit benannten Confounder, dass simulate() 2,0xATR_M5 ansetzt waehrend live
ATR_M15 gilt. backtest_sl_width.py trennt beides: gegatete Live-Population
(1.224 Entries, Reversal aus, k=0,3), kanonischer Exit, variiert wird
ausschliesslich die SL-Breite.

ATR_M15 / ATR_M5 = 1,80 im Median -> der Live-SL ist rund 3,6xATR_M5 breit,
nicht 2,0. Genau daraus entstanden die 1.229 EUR. Confounder bestaetigt.

  SL-Basis            H1 OR/SR        H2 OR/SR        Worst H1/H2
  2,0xATR_M5        -0,092 / -44    -0,024 / -18     -2,33 / -2,29
  2,0xATR_M15 LIVE  -0,145 / -69    +0,064 / +48     -4,77 / -5,64
  1,5xATR_M5        -0,081 / -38    -0,038 / -28     -1,83 / -1,85
  2,5xATR_M5        -0,121 / -58    -0,013 / -10     -2,83 / -2,79
  3,0xATR_M5        -0,130 / -62    +0,018 / +13     -3,33 / -3,29

KEINE engere Variante schlaegt den Live-SL in BEIDEN Haelften - H2 bevorzugt den
weiten Stop klar. Die vorab fixierte Regel ist nicht erfuellt: keine Aenderung.
Das reproduziert backtest_sl_tf_mismatch.py (23.07., dort auf Squeeze-Entries mit
eigenem Exit-Nachbau) jetzt auf der gegateten Population mit kanonischem Exit -
der alte Schluss war korrekt.

Der echte Unterschied ist das TAIL-RISIKO und damit eine SIZING-Frage:
Worst-Case -5,64xATR (live) gegen -1,85xATR (bei 1,5xATR_M5), Faktor 3. Bei
ATR 0,30 sind das ~1,7 $; unter 95 %-Margin auf ~800 EUR Konto ist ein solcher
Trade ~19 % des Kontos. Der weite Stop kauft die H2-Performance mit genau diesem
Tail. Wer ihn begrenzen will, senkt margin_buffer_pct - nicht die SL-Breite,
die kostet gemessen H2.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 13:28:49 +02:00
Axel HocksandClaude Opus 5 3ec4d53022 Frueh-Kappen kontrafaktisch geprueft — Hypothese widerlegt, Leckage liegt woanders
analyze_manual_close.py simuliert fuer jeden real geschlossenen Trade ab dem
echten Einstieg den kanonischen Exit und vergleicht gegen das tatsaechliche
Ergebnis. EUR-Faktor 87,6 EUR/$/Lot, robust aus 251 Trades geschaetzt (trader.pnl
enthaelt Swap, direkte Rueckrechnung waere verfaelscht).

  Schliessgrund        n     IST   Bot-Exit      Delta
  manual   Gewinn    143   +1428      +962       -467
  sr_close Gewinn    106   +1591     +1060       -530
  emergency Verlust   98   -1750     -1235       +515
  sl        Verlust   69   -1926      -697      +1229

Die Frueh-Kappen-Hypothese ist WIDERLEGT: das diskretionaere Schliessen kostet
nichts, es bringt +467 EUR MEHR als der kanonische Exit; in 62 % der Faelle war
der manuelle Close besser. Dasselbe gilt fuer den S/R-Auto-Close (-530). Beide
realisieren Gewinne besser als reines Trailing.

Die Leckage liegt auf der VERLUSTSEITE: die 69 per Broker-SL geschlossenen
Trades haetten mit dem kanonischen Exit 1.229 EUR weniger verloren, die 98
Notfall-Closes 515 EUR weniger. Ueber alle Trades waere der kanonische Exit rund
+700 EUR besser gewesen, praktisch vollstaendig aus der Verlustseite.

Confounder benannt: simulate() setzt den Initial-SL auf 2,0xATR_M5, live kommt er
aus ATR_M15 und ist oft deutlich weiter - unter Margin-Sizing schlaegt das voll
auf den EUR-Verlust durch. Der +1.229-Wert misst also erheblich SL-BREITE, nicht
Exit-Logik. backtest_sl_tf_mismatch.py hat die M5-Umstellung schon geprueft und
wegen H2 verworfen; dieser Befund gibt Anlass, das mit dem kanonischen Exit zu
wiederholen.

Zweite Grenze: Vergleich gilt pro Trade, nicht als Kontostand-Hochrechnung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 13:25:01 +02:00
Axel HocksandClaude Opus 5 b376619663 Mini-Trades untersucht: Mindestgewinn-Gate erneut verworfen, Praemisse korrigiert
User-Frage: "es gibt immer noch Mini-Trades mit geringen Gewinnen, wie
verhindern wir das?"

1) Mindestgewinn-Gate mit dem NACHTRAINIERTEN P(break)-Modell nachgemessen -
   Ablehnung bestaetigt, deutlicher als zuvor. Delta SR gegen minR=0:
     0,1xATR   -6 / +10
     0,2xATR  -720 /  -42
     0,3xATR -1136 / -157
     0,5xATR -1998 / -683
     0,8xATR -2887 /-1577
   Monoton schlechter in BEIDEN Haelften. Uebersprungene Klein-Closes prallen am
   haltenden Level ab und enden schlechter.

2) Die Praemisse stimmt so nicht. 295 Trades seit 20.07.: die 28 Gewinne <=2 EUR
   bringen zusammen +21,11 EUR = 0,8 % der Brutto-Gewinne (2.770 EUR). Kein
   Ertragsproblem. Entscheidend ist die Herkunft:
     sr_close (Bot)  n=81  Median +14,65  davon <=2EUR: 10 (+7,65)
     manual  (User)  n=64  Median  +6,37  davon <=2EUR: 18 (+13,46)
   Zwei Drittel der Mini-Gewinne sind MANUELLE Closes, und der manuelle
   Median-Gewinn ist weniger als die Haelfte des Bot-Medians. Die Klein-Closes
   des Bots sind gemessen richtig; die Asymmetrie liegt im diskretionaeren
   Frueh-Kappen. Ein Code-Gate am Bot-Exit adressiert das falsche Ende.

Keine Codeaenderung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 13:21:58 +02:00
Axel HocksandClaude Opus 5 a172353cee Fibonacci-Retracements gemessen — verworfen (21. Signal-Eingriff)
Anlass: USOIL-Kommentar "ein Fibonacci-Retracement sollte den Kurs auf 79 $
druecken". Fib-Level waren im Projekt nie gemessen worden. Aufbau wie beim
P(break)-Training: Schwuenge aus M15-Pivots, Beruehrung <=0,15xATR, Ausgang
+/-0,5xATR in 12 M5-Bars, 80k Bars, 2 Halbjahre, ZWEI Kontrollgruppen.

Haltequote:
                          H1       H2
  Fibonacci             54,3 %   54,5 %
  (a) Zufalls-Level     55,7 %   53,8 %
  (b) M30-Pivots        56,6 %   55,4 %

Handelbarkeit (Bounce, kanonischer Exit, Echtkosten):
  H1 OR -0,168 / PF 0,71     H2 OR -0,082 / PF 0,85

Der aufschlussreichste Wert ist die Zufalls-Kontrolle: ~55 % Haltequote. Ein
BELIEBIGES Level haelt in diesem Markt in gut der Haelfte der Faelle - das ist
die Basisrate kurzfristiger Mean-Reversion, keine Eigenschaft von Fibonacci.
Damit ist auch das Selbsterfuellungs-Argument entkraeftet: dann muesste Fib
ueber der Zufallslinie liegen; es liegt darunter bzw. gleichauf.

Bestaetigt umgekehrt die Struktur-These: M30-Pivots - Stellen, an denen real
gehandelt wurde - halten in BEIDEN Haelften besser als beide gerechneten Linien.
Dieselbe Trennlinie wie beim Regressionskanal und beim P(break)-Modell:
"Linie im Chart" ist nicht "Struktur im Markt".

Zur konkreten Aussage: 79,00 ist beim aktuellen M15-Schwung (78,808 -> 82,680)
gar kein Fib-Level, sondern ein Retracement von 95 %. Die naechsten echten
Marken sind 80,29 (61,8 %) und 79,64 (78,6 %). Der kalibrierte Kegel legt 79,00
in allen drei Horizonten ausserhalb des 80-%-Bandes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 13:10:57 +02:00
Axel HocksandClaude Opus 5 3dc56e8571 breakout_k mit vollem Live-Gate-Stack gemessen
Nachgeholt, was in der Vollpruefung offen blieb: die ungegatete Messung zeigte
k=0,5/0,8/1,0 besser als den Live-Wert 0,3 - aber ohne min_conf, HTF-Filter und
Entry-Raum. backtest_breakout_gated.py schliesst die Luecke mit den ECHTEN
Methoden (_build, _confirm_breakout-Mechanik, _room_gate mit kausalen M5-Pivots).

  k=0,0  H1 -0,173/-193   H2 +0,003/  +7
  k=0,2  H1 -0,185/-149   H2 -0,012/ -16
  k=0,3  H1 -0,160/-122   H2 -0,036/ -47   (LIVE)
  k=0,5  H1 -0,127/ -85   H2 -0,041/ -47
  k=0,8  H1 -0,101/ -54   H2 -0,012/ -11
  k=1,0  H1 -0,096/ -45   H2 -0,016/ -12

Bestaetigt: k=0,5/0,8/1,0 schlagen 0,3 in BEIDEN Haelften, die Nachbarn halten
mit, und die OR verbessert sich in H1 monoton - also nicht nur
Handelsvermeidung. Die vorab fixierte Regel ist erfuellt.

TROTZDEM keine Umstellung empfohlen, und der Grund ist kein Messfehler sondern
eine Zweckfrage: alle Werte bleiben negativ (PF 0,70-1,01), das Gate begrenzt
Schaden statt Edge zu erzeugen; der Auto-Signal-Pfad ist ohnehin aus, das Signal
ist ein Vorschlag fuer den Menschen, und dessen gemessener Vorteil entstand auf
der k=0,3-Population; k=0,8 kuerzt die Empfehlungen um ~39 % und treibt den
WARTEN-Anteil weiter hoch, der mit 93 % ohnehin im Fokus steht.

Zwei benannte Abweichungen der Simulation:
- _confirm_breakout misst seinen Timeout mit time.time() gegen 3600 s. Im
  Bar-Loop vergeht keine Wall-Clock-Zeit, der Timeout wuerde nie feuern. 3600 s
  sind auf M5 exakt 12 Bars, so wird gezaehlt. Merke: jede time.time()-Messung
  im Live-Code ist in einer Bar-Simulation stumm.
- hour=None, weil die EIA-Pruefung in _build ueber datetime.now(_BERLIN) laeuft -
  mit Bar-Stunde wuerde ein Lauf am Mittwoch 15:30-16:30 alle Bars blocken.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 12:34:09 +02:00
Axel HocksandClaude Opus 5 80a5be7fe5 Vollpruefung aller 87 Skripte + Nachrechnung der verworfenen Modelle
Phase 1 - Lauffaehigkeit: 87 von 87 Skripten laufen fehlerfrei (8000 Bars,
Timeout 900 s). Kein Defekt durch die heutigen wave_rec-Aenderungen. Werkzeug:
run_all_backtests.py, probiert die uneinheitlichen Aufruf-Signaturen adaptiv
durch (Bar-Zahl / TF+Bars / zwei TFs+Bars).

Phase 2a - breakout_k: die dokumentierte Begruendung REPRODUZIERT NICHT.
k=0,3 war mit dem LEGACY_BE10-Exit (Breakeven 1,0) validiert. Erstmals mit dem
kanonischen Exit nachgerechnet (backtest_breakout_canon.py, echte
_confirm_breakout-Mechanik, 80k M5, 2 Halbjahre, Echtkosten):
  k=0,0  H1 -0,180/-569   H2 -0,054/-250
  k=0,3  H1 -0,170/-356   H2 -0,069/-217   (LIVE)
  k=0,5  H1 -0,142/-262   H2 -0,074/-208
  k=0,8  H1 -0,112/-166   H2 -0,032/ -73
  k=1,0  H1 -0,101/-130   H2 -0,004/  -8
k=0,5/0,8/1,0 schlagen den Live-Wert in BEIDEN Haelften (bis +226/+209 SR).

TROTZDEM keine Aenderung empfohlen: (a) alle Werte negativ (PF 0,70-0,99), es
ist eine Wahl zwischen Verlusten; (b) Optimum lag am Rand -> Gegenprobe bis
k=3,0 zeigt kein sauberes Optimum (H2: -8 -> -17 -> -20 -> -19); (c) gemessen
wurde das UNGEGATETE Signal, live laufen min_conf/HTF/Entry-Raum davor. Naechster
Schritt waere eine gegatete Neumessung, bevor ein Gate angefasst wird, das 63 %
der WARTEN erzeugt.

Phase 2b - verworfene Modelle bei vollen Bars: ALLE bleiben verworfen.
14 Klassen (ORB, Doppeltop, Volume Profile, Liquidity Sweeps, Konsolidierung,
Handbuch-Level, Marktstruktur, Momentum, Inter-Market, Chop-Gate,
Reversal-Lockout, S/R-Close-Signal, MACD/ADX/RSI, HTF-Winkel) - keine kippt
ins Positive. Bei ~14 Tests waere bei 5 % Fehlalarmquote ein falsch-positives
Ergebnis zu erwarten gewesen; es gab keins. Regel vorab fixiert.

Kein Freibrief fuer regelmaessiges Nachrechnen - die Begruendung gegen
woechentliche Laeufe steht unveraendert. Anlass war die einmalige
Signalaenderung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 12:15:33 +02:00
Axel HocksandClaude Opus 5 9e6e81dd34 Backtest-Audit: alle 87 Skripte geprueft
Lauffaehigkeit in Ordnung: alle 87 kompilieren, 12 repraesentative (alle die
WaveRecommender konstruieren) laufen fehlerfrei. Die heutigen wave_rec-
Aenderungen brechen nichts - der Modul-Default _reversal_enabled=True haelt die
Altmessungen stabil. Drei Skripte nehmen [TF] [N] statt einer Bar-Zahl als
erstes Argument (signal/pullback/htf_filter); mit einer Zahl als TF gibt es
KeyError. Kein Defekt, nur die Signatur beachten.

angle=-Befund: 11 Skripte, NICHT 26.
Methodik-Fehler bei mir selbst, korrigiert: die erste Pruefung per Regex
(_build\([^)]*angle\s*=) meldete 26 Treffer - die Zeichenklasse [^)]* bricht an
der ersten Klammer ab, sodass Aufrufe wie
w._build(..., htf_trend=m30s(T[i]), angle=ang) faelschlich als "ohne Winkel"
galten. Die AST-Pruefung ergibt 11 echte Faelle und erkennt zusaetzlich
positional uebergebene angle-Argumente. Regex ist fuer Aufruf-Analysen das
falsche Werkzeug.

Wirkung, gemessen ueber 37.577 M5-Bars:
                        mit Reversal   ohne Reversal (live seit heute)
  Signal weicht ab        19,1 %          1,1 %
  Konfidenz-Differenz     +7,7           -4,4
  ueber dem 55%-Gate      79,4->90,6 %   79,4->78,5 %

Das Reversal-Abschalten von heute hat die Luecke nebenbei fast geschlossen.
Solange das Reversal aktiv war, sahen die 11 Skripte eine Signal-Population,
die sich in jedem fuenften Bar unterschied - das betrifft den Grossteil der
Projekt-Historie. Ab jetzt sind sie naeherungsweise gueltig.

Bewusst NICHT getan: die 11 Skripte "repariert". Ein angle= zu ergaenzen aendert
ihre Zahlen - das waere laut Migrations-Regel keine Refaktorierung, sondern eine
Neumessung. Sie bleiben unveraendert und reproduzierbar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 11:55:36 +02:00
Axel HocksandClaude Opus 5 81c4c195da Auto-Signal nach dem Reversal-Abschalten gemessen — immer noch nicht tragfaehig
Frage: liefert der Auto-Signal-Entry mit den heutigen Aenderungen positive
Ergebnisse? Antwort: nein, aber deutlich naeher dran.

LIVE-Konfiguration (Reversal aus, Winkel modelliert), conf>=75:
  H1  OR -0,047  PF 0,94  n=678
  H2  OR +0,120  PF 1,17  n=710
H1 bleibt negativ -> 2-Stichproben-Regel weiterhin NICHT erfuellt. Kein
Konfidenz-Schwellwert rettet das (55: -0,103 - 65: -0,111 - 75: -0,047).

Das Reversal-Abschalten wirkt aber konsistent. Delta OR:
  conf 55  +0,015 / +0,099
  conf 65  +0,001 / +0,047
  conf 75  +0,099 / +0,087
An der Live-Schwelle verbessern sich BEIDE Haelften um ~+0,09; H1 geht von
-0,145 auf -0,047, PF von 0,82 auf 0,94. Erste Bestaetigung der gestrigen
Entscheidung auf dem GESAMTEN Signal statt nur dem isolierten Trigger.

DABEI GEFUNDEN - die Messung vom 30.07. war strukturell unvollstaendig:
backtest_auto_signal.py ruft _build OHNE angle= auf. Der Default 90,0 macht
ad = 0, damit konnte dort weder der Reversal-Zweig feuern noch der
Winkel-Konfidenzterm (+/-15 Punkte) greifen - obwohl die Docstring "echte
_build-Logik inkl. Reversal-Zweig" behauptet. Der Winkelterm allein hebt H1 bei
conf 75 von -0,123 auf -0,047. Deployment-Drift Fall 5.

Die Originaldatei bleibt unveraendert (ihre Zahlen sind dokumentiert); die
live-treue Variante steht als backtest_auto_signal_norev.py daneben und sollte
kuenftig die Referenz sein.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 11:49:10 +02:00
Axel HocksandClaude Opus 5 dcdd53b703 Winkel-Beschriftung korrigiert (Zahlen unveraendert) + Spiegeltest bestanden
Anlass: "pruefe die Logik im umgekehrten Fall, fallender Kurs".

1) Spiegeltest bestanden. Mit reversal_enabled=false ist das Verhalten ueber die
   ganze Ueberdehnungs-Spanne exakt symmetrisch (steigend/LONG <-> fallend/SHORT):
   gleiche Signale, gleiche Konfidenz, gleicher Anti-Ueberdehnungs-Schnitt bei 3,5.

2) Dabei gefunden: die Winkel-Beschriftung war ueberall invertiert.
   calc_trend_angle liefert 0 Grad = AUFWAERTS ... 180 = ABWAERTS, also ist
   ad = angle-90 NEGATIV bei steigendem Kurs. Ein LONG in einem steigenden Markt
   bekam daher "Winkel gegen EMA" (-10), ein LONG in einem fallenden
   "Winkel bestaetigt" (+5).

   ABER: backtest_angle.py benutzt DIESELBE verdrehte Beschriftung
   (a5_dis = a5 < 90-dead fuer LONG heisst "dagegen", ist aber STEIGEND).
   Der dokumentierte Befund "dafuer/neutral +0,055 vs dagegen +0,025" bedeutet
   richtig gelesen: LONG bei FALLENDEM Kurzfrist-Winkel (= Pullback) traegt
   doppelt so gut. Das ist der mehrfach belegte Pullback-Effekt.

   => Die Gewichtung war von Anfang an NUMERISCH RICHTIG. Nicht umgedreht.
   Geaendert wurden nur die Reason-Texte und Kommentare.
   Verifiziert: Konfidenzwerte vorher/nachher identisch (60/70/75 je Richtung).

Lehre: der erste Verdacht "systematisch invertierte Logik" war falsch - die
Zahlen stimmten, die Sprache log. Bei einer verdrehten Konvention erst pruefen,
ob die MESSUNG dieselbe Verdrehung teilt, bevor man den Code "repariert".
Beim Reversal war es anders: dort wies die eigenstaendige Messung das Setup
unabhaengig von der Beschriftung als negativ aus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 11:28:38 +02:00
Axel HocksandClaude Opus 5 1a67944842 Reversal-Setup abgeschaltet (User-Entscheidung nach der Messung)
backtest_reversal_angle.py hat den Trigger in JEDER Variante beidhaelftig
negativ gemessen (IST -0,122/-0,031 - vorzeichenkorrigiert -0,173/-0,061 -
ohne Winkelbedingung -0,099/-0,023). Ausschlag gab aber nicht nur die Zahl:
das Setup hebelt ZWEI gemessen POSITIVE Schutzmechanismen aus - die
Anti-Ueberdehnung und den M30-Gegen-Trend-Filter (Edge x2). Ein Setup ohne
eigenen Edge, das validierte Filter umgeht, ist der unguenstigste Fall.

Umsetzung: neuer Schalter [trading] reversal_enabled (Config-Default im Engine
false). WICHTIG: der Modul-Default in wave_rec bleibt True - saemtliche
Backtests rufen dasselbe _build, ein False-Default haette alle bestehenden
Messungen still veraendert. Abgeschaltet wird ausschliesslich im Live-Pfad.

Verhaltensaenderung nur im Band |stretch| 3,0-3,5: dort kam vorher ein
antizyklisches REV-Signal, jetzt das normale Trendsignal; ab 3,5 greift wie
gehabt die Anti-Ueberdehnung.

Verifiziert:
- 3 Szenarien: ueberkauft+steigend SHORT/WAVE_REV_SHORT -> LONG/WAVE_LONG,
  ueberverkauft+fallend LONG/WAVE_REV_LONG -> SHORT/WAVE_SHORT, normaler
  Trend unveraendert
- Live nach Neustart: bei 3,18xATR Ueberdehnung jetzt WARTEN/setup=WAVE/
  reversal=None statt REV_SHORT; Log "Reversal-Setup AUS"
- measurement_reminder CONFIG_DEPS ergaenzt, 11 Werte alle korrekt

Die Winkelbedingung wurde bewusst NICHT vorzeichenkorrigiert - die korrigierte
Variante misst sich schlechter. Die irrefuehrenden Kommentare sind jetzt als
solche markiert. Bounce-Anzeige bleibt unveraendert (nur Warn-Kontext).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 11:19:48 +02:00
Axel HocksandClaude Opus 5 d052905319 Reversal-Winkelbedingung gemessen: alle drei Varianten fallen durch
Anlass: User-Frage "warum SHORT im starken M5-Aufwaertstrend?". Antwort war ein
WAVE_REV_SHORT (3,25xATR ueberdehnt). Beim Nachrechnen kam heraus, dass die
Winkelbedingung gegen ihre eigene Dokumentation laeuft:

calc_trend_angle liefert 0 Grad = starker AUFWAERTStrend, 180 = ABWAERTS.
ad = angle-90 heisst also: ad<0 = STEIGEND. Der Code triggert
stretch>=+3.0 and ad<=-2 -> SHORT, kommentiert als "Winkel ab" - feuert also bei
ueberkauft UND WEITER STEIGENDEM Winkel, waehrend CLAUDE.md "Einstieg IN
Winkel-Richtung" beschreibt. Dasselbe Vorzeichen im Konfidenz-Block: ein SHORT
bekommt "Winkel bestaetigt" (+5), waehrend der Kurs steigt. Mit synthetischen
Reihen direkt nachgestellt.

Erklaert zwei dokumentierte Befunde: ~50 % Richtungstreffer der Bounce-Anzeige
und "blutet in starken Trends".

Statt das Vorzeichen blind zu drehen (alle Messungen beruhen auf dem
IST-Verhalten): backtest_reversal_angle.py, 80k M5, kanonischer Exit,
Echtkosten, 2 Halbjahre, drei Varianten.

  IST         -0,122 / -0,031  PF 0,79/0,94  n=1100/1615
  KORRIGIERT  -0,173 / -0,061  PF 0,68/0,89  n= 106/ 163
  KONTROLLE   -0,099 / -0,023  PF 0,82/0,96  n=1153/1693

(a) Die Vorzeichenkorrektur ist SCHLECHTER - gut, dass sie nicht blind eingebaut
    wurde. Sie feuert zudem kaum, weil bei 3xATR Ueberdehnung die 14-Bar-
    Regression fast immer noch steigt.
(b) Die Kontrolle OHNE Winkel ist die beste der drei - die Winkelbedingung
    entfernt Trades, die im Schnitt besser waren als die behaltenen.
(c) Der Trigger ist in jeder Variante beidhaelftig negativ.

Gemessen wurde der ROHE Trigger ohne Konfidenz-/Raum-Gate; der Legacy-Recheck
der gegateten Variante kam auf ~Breakeven (PF 0,93/1,06), dieselbe Richtung.
Keine Messung stuetzt die dokumentierten "+0,185 / PF 1,35" mehr.

Noch KEINE Strategieaenderung - das Abschalten ist eine User-Entscheidung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 11:15:21 +02:00
Axel HocksandClaude Opus 5 94fbde1dba News-Sentiment war gesaettigt — Beweismengen-Gewichtung eingebaut
Anlass: Frage nach X-Anbindung fuer den Copiloten. Vorher geprueft, ob der
vorhandene Textstrom ueberhaupt traegt. Er trug nichts, weil der Score kaputt war.

calc_news_sentiment bildete ein REINES VERHAELTNIS (bull-bear)/total, ohne Bezug
zur Beweismenge. Eine einzige bullische Schlagzeile bei null baerischen ergab
+1,00. Diagnose:
- 173 von 173 Log-Eintraegen auf +/-1,00 gesaettigt (100 %)
- in 100 % der Faelle eine Seite exakt 0
- Median-Beweismenge nur 2,8 gewichtete Headlines
- ueber die DB (54.548 Zeilen): 63,9 % auf exakt +1,00
Real am 03.08.: +1,00 waehrend WTI -5,9 % stand. Der Wert trug ein Bit und
loeste im Entry-Check dauerhaft falsche "News-Konflikt"-Warnungen aus.
Die Keyword-Listen sind NICHT die Ursache (56/48, keine Ueberschneidung).

Fix: Shrinkage score = raw * total/(total+4,0). Die 4,0 ist begruendet, nicht
optimiert: bei der realen Median-Beweismenge 2,8 bleibt eine einseitige
3-Headline-Lage unter der 0,5-Warnschwelle, ~10 Headlines ergeben 0,71.
Zusaetzlich raw_score und evidence im Rueckgabewert, damit unterscheidbar wird
ob "ausgewogene Lage" oder "kaum Daten". Leer-Fall liefert dieselben Felder.
6 Szenarien getestet, live verifiziert: bei identischer Beweislage
(bull=1.8, bear=0.0) +1,00 -> +0,31.

EHRLICH: das repariert die Kalibrierung, nicht die Aussagekraft. Parallel
gemessen (Forward-Return 120 min, 38.213 Paare, 84 Tage, 2 Haelften, gegen die
Regime-Drift gelesen): der stark-bullische Bucket liegt in BEIDEN Haelften bei
null bis negativ, der baerische kippt das Vorzeichen. News-Sentiment ist nicht
robust praediktiv. Bleibt Kontext-Chip ohne Verdict-Stimme.

Methodik-Falle dokumentiert: der erste Messlauf nutzte candles_m1 (nur ~14 Tage)
-> bisect lieferte fuer aeltere Zeitstempel denselben Randwert, alle
Forward-Returns exakt 0,0000. Erst der Lauf mit MT5-M5-Bars plus
Deckungspruefung war gueltig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 19:25:47 +02:00
Axel HocksandClaude Opus 5 fe7a1acb97 Kurslueckenerkennung: zwei Fehler behoben
User-Meldung "die Kurslueckenerkennung funktioniert nicht richtig". Zwei Fehler
gefunden:

1) Die groesste Luecke des Jahres wurde um 3 Cent verfehlt. Die Definition
   verlangte ein lueckenloses Vakuum zwischen den TAGESSPANNEN. Am Wochenende
   31.07.->03.08. fiel WTI von Schluss 86,33 auf Eroeffnung 79,76 = -6,57 $ -
   unsichtbar, weil Montags Hoch (81,67) das Freitags-Tief (81,64) um 0,03 $
   ueberlappte. In einem 24/5-Markt ueberlappen die Tagesspannen fast immer;
   die strenge Regel fand im ganzen Jahr nur 5 Gaps.

2) Alle Gap-Datumsangaben waren einen Tag zu frueh: int(b["time"]) minus
   _BROKER_OFFSET_S zog 3 h von einer Bar-Zeit ab, die MT5 bereits als naive
   Broker-Zeit liefert. Die gemeldete Luecke "2026-07-26" war real der 27.07.
   Am Jahreswechsel haette es zusaetzlich den year-Filter verschoben.

Fix: zwei getrennte Gap-Begriffe (kind).
- vacuum     = alte strenge Definition. NUR diese speisen zone_lines() ->
               _sr_levels -> Wellen-Konfidenz, denn nur auf ihnen wurde
               gemessen (backtest_gaps.py). Strategie-Eingang bitgenau
               unveraendert: zone_lines() liefert vorher wie nachher [88.288].
- close_open = Schluss->Eroeffnung, das was ein Mensch "Kurslucke" nennt.
               REINE ANZEIGE, ab 0,50 $, fuellt auch am selben Tag.

Live: 4 offene Luecken statt 1 (1 Vakuum + 3 Eroeffnungsluecken), darunter
endlich die -6,57-$-Wochenendluecke mit Fill bei 86,33. Frontend kennzeichnet
beide Arten mit Tooltip. v=133.

Bewusst NICHT getan: close_open in die Konfidenz einspeisen - das waere ein
ungemessener Strategie-Eingriff, und der vorhandene Befund beruht auf der
Vakuum-Definition.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 18:19:48 +02:00
Axel HocksandClaude Opus 5 5f94917014 Kanal-Pullback ueber alle Zeitebenen gemessen — 24/24 negativ
Anlass: User-Beobachtung im M5-Chart "der Kurs folgt dem Marktstrukturkanal und
bricht die untere Linie nicht — koennen wir das nutzen?". Die vorhandene Messung
(backtest_structure.py, 20.07.) lief NUR auf M30; M5 war ungetestet.

Neues Skript backtest_structure_tf.py — bewusst mit dem KANONISCHEN Live-Exit
(exit_model.LIVE: Trail 1,0 + Time-Stop + TP) statt der Exit-Kopie der alten
Datei (Trail 1,5, kein Time-Stop). Die alte Datei bleibt unveraendert, weil die
Migrations-Regel eine Umstellung nur bei identischen Zahlen erlaubt.

Getestet: M5/M15/M30 x zwei Lesarten des M5-Kanals (60 Bars = 5 h "was man im
Chart sieht" und 360 Bars = 30 h zeitgleich zu M30) x drei Regel-Varianten,
80k Bars je Zeitebene, 2 Haelften, Echtkosten.

Ergebnis: 24 Zellen, ALLE negativ, PF 0,66-0,99.
- Trefferquote 37-43 % ueber 1200-2400 Beruehrungen je Haelfte: der Kanalrand
  haelt in WENIGER als der Haelfte der Faelle. Die im Chart sichtbaren "Halter"
  sind Selektion.
- M5 ist die SCHLECHTESTE Zeitebene (-0,201 vs -0,103 auf M30).
- Keine Parameterfrage: 60-Bar- und 360-Bar-Kanal liefern identische Zahlen.

Legacy-Recheck-Bonus: die M30-Zeile reproduziert den Befund vom 20.07.
(-0,103/-0,019 gegen damals -0,05...-0,11) — der alte Schluss war NICHT durch
das abweichende Exit-Modell verzerrt.

Mechanismus: hinter einer Regressionslinie liegt nichts — keine Order, kein
Pivot. Darin liegt der Unterschied zu P(break) auf einem echten S/R-Level.
19. verworfener Signal-Eingriff.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 16:37:52 +02:00
Axel HocksandClaude Opus 5 00c78201fa KI-Copilot: zwei Prompt-Fehler behoben + kalibrierte Groessen ergaenzt
Diagnose zur Frage "Bias fast immer neutral": es ist NICHT der Prompt, es ist
der Provider. Bruch exakt am 20.07. (DeepSeek-Wechsel) - bis 19.07. war der
Copilot zu 42-90 % gerichtet, ab 21.07. nur noch zu 1,5-9,3 %. Der Prompt war
unveraendert. Und er hedged aus KORREKTER Schlussfolgerung: ~90 % WARTEN-Signal,
negativer Track-Record, plus die Prompt-Anweisung, genau dann NEUTRAL zu sagen.

Gemessen, ob mehr Meinung ueberhaupt Wert haette: KI-LONG n=286 +0,29 $ / 76 %
Treffer, KI-SHORT n=93 -0,02 $ / 55 %. ABER die 286 sind 20 Episoden an 5 Tagen
(Minutentakt-Logger), die 93 sind 16 Episoden -> effektiv n~20 gegen n~16, ein
Regime. Kein Beleg. Deshalb BEWUSST nicht am Prompt gedreht, um Meinung zu
erzwingen; Verdict-Gewicht unveraendert.

Zwei echte Prompt-Fehler behoben (Korrektheit, keine Meinungsmache):
- _SYS beschrieb das Wellen-Signal als "ATR-ZigZag" - es ist EMA12 vs EMA50
- _SYS nannte "TradersUnion-Tachos" als Input - TU ist seit 19.07. raus

Kalibrierte Groessen ergaenzt: _tool_market gab dem Copiloten NUR Wellen-Signal
und Session. Neu: p_break_target / p_break_stop (AUC 0,65 bzw. 0,68-0,72) und
cone (80%-Baender mit der REAL gemessenen Abdeckung 77 %), plus Lese-Anleitung
im Prompt (45-55 % explizit als Muenzwurf markiert).
Zwei Fallen an Live-Daten korrigiert: p_break steht bereits in PROZENT (die
zuerst gebaute x100-Umrechnung haette 300 erzeugt), und die Engine-Felder plus
die engine-Referenz im Agent existierten gar nicht - der Fail-safe haette still
nichts geliefert. Snapshot weist die Werte jetzt nur zu, rechnet sie nicht neu.

DeepSeek max_tokens 4000 -> 8000: das JSON brach regelmaessig mitten im Text ab
("Unterminated string"), real 2x in ~14 Zyklen = ~14 % stille Ausfaelle.

Kerzen/Muster bewusst NICHT eingespeist - die Lehrbuch-Lesart ist hier gemessen
invertiert (langer Koerper im Trend -0,132/-0,042; 2x Volumen -0,117/-0,204;
Muster-Kursziel trifft nur 13-38 %). Roh eingespeist wuerden sie schaden.

Verifiziert: Stub-Test von _tool_market (Werte unveraendert durchgereicht, nur
80%-Baender, ohne Engine kein Absturz); Prozess juenger als beide Dateien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 23:44:35 +02:00
Axel HocksandClaude Opus 5 20cd04caa7 Review-Durchlauf: Telemetrie-Epochen, doppeltes Verdict, Doku-Korrektur
Erster vollstaendiger Durchlauf von docs/review-prompt.md. KEINE
Strategie-Aenderung - alles Telemetrie, Doku und toter Code.

1) analyze_divergence.py kannte keine Epochen und war damit selbst
   driftanfaellig. D0 mischte Vorhersagen des alten und des am 31.07.
   nachtrainierten P(break)-Modells und meldete dessen Fehlkalibrierung als
   aktuellen Alarm (das neue Modell hat n=0, Markt seit Fr zu). B las die
   Prae-Migrations-NULLs von block_reason als blinden Fleck. C druckte bei
   0 Zeilen ein "OK", obwohl es fehlende Daten waren. Neu: _EPOCHS + _clamp().

2) Konsens-Pfeil AR;K: der MQL5-Export rechnete im ~5-s-Takt ein komplettes
   zweites _verdict(), obwohl der Indikator die Zeile seit v1.33 per Default
   verwirft. Neu [trading] export_consensus_arrow (Default false).
   Verifiziert ueber die exportierte CSV: AR;K weg, AR;L und AR;S bleiben.

3) /api/autosqueeze loggt jetzt die Herkunft ([WEB] ...) wie /api/autosignal.
   Vorher war ein Zustandswechsel nicht als Nutzeraktion belegbar.

4) CLAUDE.md: die Reversal-Kennzahl "OR +0,185 / PF 1,35 / 70 %" stand
   unkorrigiert an der Fundstelle, die Widerlegung 2000 Zeilen weiter im
   Legacy-Recheck. Korrektur an die Fundstelle geholt.

5) core/notify.py: zwei tote "import datetime" entfernt (beide Funktionen
   nutzen _time), funktional nachgetestet.

Geprueft und sauber: 0 fehlende Frontend-IDs von 86, nur 2 Config-Schluessel
ohne Leser (beide dokumentiert dormant), Snapshot-Median 13 ms und alle
DB-Abfragen <13 ms -> keine Performance-Massnahme, 124 Datei- und 83
Funktionsreferenzen in CLAUDE.md stimmen.

Zwischenverdacht zurueckgezogen: "block_reason erklaert nur 33 % der WARTEN"
war ein Migrations-Artefakt; seit 01.08. 100 % Abdeckung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 23:29:58 +02:00
Axel HocksandClaude Opus 5 89e4af4561 HL-Kurs: Rohkurs anzeigen + Basis bei stehendem Broker einfrieren
User-Fund: app.hyperliquid.xyz zeigt WTIOIL-USDC bei 81,392, das Dashboard
86,424. Dahinter steckten zwei Fehler.

(1) Falsches Label (vom 01.08.): angezeigt wurde mid_mt5 = HL + Basis, also
der auf Pepperstone-Niveau umgerechnete Wert - unter der Beschriftung
"HYPERLIQUID KURS". Jetzt steht dort der ROHE HL-Kurs (exakt die Zahl von der
HL-Seite); das CFD-Aequivalent ist in den Tooltip gewandert.

(2) Die Basis-Korrektur war bei geschlossenem Markt ZIRKULAER. Gegenstueck im
HL-Projekt (eigener Commit): die Basis wird jetzt auf dem letzten Stand mit
lebendem Broker eingefroren und als basis_stale durchgereicht.
Belegt aus leadlag.db: Basis bei lebendem Broker konstant +0,42...+0,58, nach
dem Freeze +5,03. Der Wochenend-Move war echt (So 03:00->05:00 von 85,51 auf
80,84, danach 13 h stabil um 81 bei ~600 Messungen/h).

Materielle Folge: die offene SHORT-Position (0,57 ab 86,163, TP 84,123) wurde
mit -15,02 EUR angezeigt; mit eingefrorener Basis sind es +211 EUR, und der TP
liegt 2,3 $ ueber dem echten Niveau. Vorbehalt bleibt (Oracle-Perp) -> weiter "≈".

Ausserdem dokumentiert: restart_server.bat hat zweimal still NICHT neu
gestartet. Eine korrekt ausgelieferte app.js?v=N belegt NICHTS ueber den
geladenen Python-Code (statische Dateien werden je Request von der Platte
gelesen). Zuverlaessig nur: Prozess killen, direkt starten, danach an einem
NEUEN Snapshot-Feld pruefen.

v=132.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:42:28 +02:00
Axel HocksandClaude Opus 5 d18d8712db Auto-Signal abgeschaltet + B5-Abbruchregel fuer Auto-Squeeze fixiert
Auto-Signal AUS (auto_signal=false via Toggle -> runtime_state.json). Gruende
sind NICHT die Live-Bilanz (n=4 sagt nichts):
- gemessen in H1 durchgehend negativ (backtest_auto_signal.py, alle 8 Varianten)
- beide Auto-Pfade konkurrieren um den EINEN Positions-Slot -> solange beide
  laufen, ist die B5-Pruefung des Auto-Squeeze nicht sauber messbar

B4-Befund Auto-Squeeze (Anlass: negative Auto-Trades vom 31.07.):
  Mechanik (isolierter Einstieg): WR 46 %, OR +0,102, PF 1,15
  Live (n=31, 17.-31.07.)       : WR 45 %, OR -0,242, PF 0,49
Die Trefferquote stimmt ueberein - der Einstieg ist intakt. Die Luecke von
0,34 R/Trade entsteht im EXIT (O-Gewinn +11,02 vs O-Verlust -19,83). Alle drei
Ursachen wurden am 31.07. behoben (P(break) nachtrainiert, 15-Min-Regel aus,
Trail einheitlich 1,0), der Live-Zeitraum liegt also VOR den Reparaturen.
Deshalb kein Rueckbau, sondern vorab fixierte Latte:
  >=20 Squeeze-Trades ab 01.08., dann Verhaeltnis < 1,0 ODER PF < 1 -> aus.

measurement_reminder.py:
- neue Messung squeeze_b5 (loest autosig_b4 ab)
- CONFIG_DEPS um auto_signal (soll false) und auto_squeeze (soll true) ergaenzt
- ⚠ _cfg_now() liest jetzt AUCH runtime_state.json und bildet dessen Vorrang ab.
  Vorher verglich der Waechter nur die ini -> er meldete "alles auf dem
  gemessenen Stand", waehrend auto_signal per persistiertem UI-Toggle lief.
  Mit Szenario verifiziert (runtime true gegen validiert false -> gemeldet).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 17:52:51 +02:00
Axel HocksandClaude Opus 5 d0f3b78796 Muster-Verdict-Gewicht 1,0 -> 0,25 (5%) + Korrektur der adverse15-Anekdote
Muster-Stimme (User-Vorgabe "geben wir dem Muster doch 5%"):
_PAT_W = 0.25 statt fest 1,0; "forming" weiter die Haelfte. Empirisch gesetzt:
ueber die letzten 4.000 verdict_votes liegt die Gewichtssumme der uebrigen
Module im Median bei 4,50 -> Anteil 5,3 % (vorher 18,2 %). Muster hat in 24,7 %
der Verdicts ueberhaupt eine Richtung, max. Nadel-Verschiebung 0,053.
Reine Anzeige - der Bias steuert keine Order.

Korrektur in CLAUDE.md: Die Anekdote zum Abschalten der 15-Minuten-Regel war
falsch. "+19,28/+17,60 moeglich" und "32 EUR weiter dagegen" waren MAXIMALE
AUSLENKUNG, nicht das, was der Exit gefangen haette. Mit core/exit_model.py
nachgerechnet waere der 11:44-Trade OHNE Regel besser gewesen (-21,43 statt
-26,31) und der 20:00-Squeeze schlechter (-23,27 statt -13,77). Ueber alle 7
Bot-Trades des 31.07. haette das Abschalten -16,42 EUR gekostet.
Die Entscheidung bleibt richtig - sie ruht auf backtest_adverse15_squeeze.py
(16/16 Kombinationen in beiden Haelften negativ), nicht auf einem Tag mit n=3.
Der Tagesgewinn kam aus Trail 1,5 -> 1,0 (+24,86 EUR auf denselben Trades).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 17:42:25 +02:00
Axel HocksandClaude Opus 5 7d68dfc4db Doku: restart_server.bat nicht mit Output-Umleitung aus PowerShell aufrufen
Der Batch startet das Oil-Backend im Vordergrund. Mit `& .\restart_server.bat
*>&1 | ...` blockiert der Aufruf bis zum Timeout und der abgeschnittene Tail
zeigt ein irrefuehrendes "===== Server beendet =====", obwohl der Server laeuft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 17:31:33 +02:00
Axel HocksandClaude Opus 5 b8bb1d260f Fix: Broker-Offset bei geschlossenem Markt (-9,5 h statt +3 h)
`_broker_offset_s()` leitete die Zeitzone aus `tick.time - now` ab. Das misst
die Zeitzone nur bei FRISCHEM Tick; steht der Markt, misst es die Veraltung.
Real am 01.08. (letzter Tick Fr 23:54): -34210 s -> gerundet -34200 (-9,5 h)
statt +10800. Die Pruefung [-12h,+14h] liess das durch.

Folgen (die Laufzeit-Uhr war nur das Sichtbare):
- open_time 12,5 h in der Zukunft -> Laufzeit 0:00
- Time-Stop-Alter (trailing.py:504) negativ -> 120-min-Stop haette nicht ausgeloest
- deal.time-Umrechnung beim externen Close, alle MQL5-Chart-Anker

Fix: Offset nur noch aus frischem Tick bestimmen, sonst letzter gueltiger Wert
(vorbelegt UTC+3 = dieselbe Konstante wie engine.broker_utc_offset). Frische am
bereits bekannten Offset gemessen -> nicht zirkulaer. Schwelle 900 s < halbes
Rundungsraster. Zeitzonen-Wechsel wird uebernommen und geloggt.

Ausserdem:
- market_closed greift sofort nach Neustart: _last_bid_move_ts wird aus dem
  echten Tick-Alter vorbelegt statt bei null zu starten (vorher 180 s blind)
- pollSnapshot: der stille catch umschloss render() -> Render-Fehler wurden
  lautlos verschluckt, das Dashboard fror ohne Konsolen-Fehler ein. Jetzt ist
  nur noch der fetch im try.
- Header-Labels ausgeschrieben: "PEPPERSTONE KURS" / "HYPERLIQUID KURS"
- v=131, CLAUDE.md (Deployment-Drift Fall 4)

Verifiziert: market_closed sofort True, tick_age gegen die Rohwerte 0 s
Abweichung, open_time -> 31.07. 22:54 (Laufzeit +15,8 h).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 14:44:25 +02:00
Axel HocksandClaude Opus 5 2ea17ce3e0 Dashboard fror bei gecachter alter HTML ein - neue Elemente jetzt null-sicher
User: "ich sehe die Aenderungen nicht im dashboard". Server war korrekt:
v=129 samt #hdr-hl ausgeliefert, Cache-Control: no-store gesetzt, kein
Service-Worker, hl_live im Snapshot vorhanden.

Ursache: index.html und app.js werden vom Browser UNABHAENGIG gecacht.
Trifft neue JS auf eine alte, gecachte HTML, wirft
$("hdr-price-lbl").textContent = ... eine TypeError - und weil das mitten in
render() passiert, bricht der GESAMTE Render ab. Das Dashboard friert ein
und zeigt Altwerte, obwohl alles andere stimmt. Genau das Symptom.

Fix: neue Elemente ueber const el = $("id"); if (el) { ... } ansprechen.
Dann laeuft der Rest weiter und nur das neue Feld fehlt, bis die HTML
nachgeladen ist. Betrifft hdr-price-lbl und hdr-hl.

Regel in CLAUDE.md aufgenommen - das ?v=N-Bump bustet nur app.js/style.css,
NICHT die index.html selbst.

v=130.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 11:13:53 +02:00
Axel HocksandClaude Opus 5 7427c36922 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>
2026-08-01 09:31:01 +02:00
Axel HocksandClaude Opus 5 35f9b567c8 Pfeile: Konsens-Pfeil per Default aus - er erzeugte wieder einen Trichter (v1.33)
User: "trichter anstatt pfeil wird angezeigt". Der Kegel war korrekt raus
(keine CN-Zeile mehr in der CSV) - was zu sehen war, waren MEINE zwei
Pfeile:
    AR;L;85.233;85.110;63% Abprall     blau, nach UNTEN
    AR;K;85.233;85.479;Konsens +1.00   grau, nach OBEN
Beide starten am aktuellen Kurs und liefen auseinander - optisch exakt der
Kegel, den sie ersetzen sollten. Gefragt war EIN Pfeil, gebaut waren drei.

Behoben:
  InpShowConsensus per Default FALSE (der Konsens steht ohnehin als
  Bias-Nadel im Dashboard)
  InpArrBars 14 -> 8 (kuerzer, Pfeilspitze im sichtbaren Bereich)
Normalfall jetzt: EIN Pfeil (L, der kalibrierte). S kommt nur beim
Squeeze-Ausbruch dazu. InpShowConsensus=true holt K zurueck.

Lehre fuer die Doku: "sie messen Verschiedenes, also duerfen sie
auseinanderzeigen" ist logisch richtig und als BILD trotzdem falsch - zwei
Linien aus einem Ursprung liest niemand als zwei Aussagen.

v1.33 ins richtige Terminal kompiliert und dort gegengeprueft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 22:01:32 +02:00
Axel HocksandClaude Opus 5 00ca2406f1 15-Minuten-Regel ganz abgeschaltet (adverse_15min_atr = 0)
User-Frage "vielleicht die auto close auf 30 min setzen?" -> Zeit-Achse
mitgemessen (backtest_adverse15_squeeze.py um Zeitpunkt und zweite
Population erweitert): 15/30/45/60 min x 0,5/0,8xATR, Squeeze- UND
Wave-Signal-Entries, kanonischer Exit, Echtkosten, 2 Halbjahre.

    Zeit  Schwelle   Squeeze H1/H2    Wave H1/H2
    15    0,5        -18 / -34        -25 / -41    (war live)
    30    0,5        -20 / -35        -22 / -13
    45    0,8        -12 / -18         -3 /  -7
    60    0,8         -8 / -10         -3 /  -3

ALLE 16 Kombinationen sind in BEIDEN Haelften negativ. Die Regel wird nur
monoton weniger schaedlich, je spaeter und lockerer sie prueft - die
"beste" Variante ist praktisch die, die nie feuert. 30 min haette den
Schaden halbiert, nicht beendet.

Damit ist auch meine Einschaetzung von vor einer Stunde korrigiert ("auf
dem Auto-Signal-Pfad ~neutral"): sie stuetzte sich auf
backtest_auto_signal.py mit eigenem Exit-Modell (+0,001 vs +0,026); mit dem
kanonischen Exit sind es -25/-41. Sechster Fall desselben Musters an einem
Tag.

Schutz-Stack bleibt vollstaendig: Broker-SL 2xATR + Trailing + Time-Stop
120 min. Die Squeeze-Ausnahme bleibt im Code, falls die Regel je wieder
eingeschaltet wird.

Config-Waechter-Anker auf 0 gezogen, mit Begruendung im Eintrag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 21:58:23 +02:00
Axel HocksandClaude Opus 5 6cf2730dc3 15-Min-Regel: Squeeze-Trades ausgenommen (gemessen schaedlich)
Analyse der negativen Autotrader-Trades. Von den drei heute per adverse15
geschlossenen Bot-Trades hat die Regel bei EINEM gerettet (Auto-Signal
11:44, -26,31 EUR; danach lief der Kurs 32 EUR weiter dagegen) und bei den
beiden SQUEEZE-Trades zu frueh gekappt (20:15 / 20:36, -13,77 / -28,09 EUR;
danach waeren +19,28 bzw. +17,60 EUR moeglich gewesen - aus candles_m1
nachgerechnet).

Verdacht bestaetigt: die Schwelle 0,5xATR wurde in backtest_auto_signal.py
auf WAVE-SIGNAL-Entries kalibriert und dann auf ALLE Bot-Trades angewandt.
Wieder ein Kalibrierungs-Bruch.

backtest_adverse15_squeeze.py (NEU, 80k M5, 2 Halbjahre, Echtkosten,
Exit-Kern): auf SQUEEZE-Entries schadet die Regel bei JEDER Schwelle in
BEIDEN Haelften:
    0,3 -> -25/-38 · 0,5 -> -18/-34 · 0,8 -> -12/-39 · 1,2 -> -5/-18
Monoton, also ist die Regel selbst das Problem, nicht ihre Einstellung.
Ohne Regel H1 -54 / H2 +220, mit 0,5 H1 -72 / H2 +186.
Grund: der Squeeze ist runner-abhaengig (43 % Treffer, Ertrag im Tail) -
ein Schnitt nach 15 min trifft genau den Tail.

Umsetzung: _bot_open_source merkt beim Oeffnen, WOMIT eroeffnet wurde;
_check_adverse15 steigt bei auto_squeeze aus. Mit 7 Szenarien getestet.

Fuer den Auto-Signal-Pfad bleibt die Regel aktiv - dort gemessen ~neutral
(OeR +0,001 mit vs +0,026 ohne), also eine Versicherung mit kleiner Praemie.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 21:52:28 +02:00
Axel HocksandClaude Opus 5 be2c318745 CLAUDE.md: Richtungs-Pfeile dokumentiert (im vorigen Commit gescheitert)
Die Doku-Ergaenzung war im letzten Commit an einem deutschen
Anfuehrungszeichen im Python-Heredoc gescheitert (SyntaxError), waehrend der
Code durchging. Jetzt nachgeholt: die drei Pfeil-Arten mit ihrer jeweiligen
Beleglage, das 45-55-%-Totband und der ALBL_-Namensraum-Fallstrick.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 19:26:49 +02:00
Axel HocksandClaude Opus 5 365a0584e5 Prognose-Kegel war unsichtbar: Indikator landete im falschen MT5-Terminal
Der Kegel wurde heute frueh gebaut, exportiert (CN;30/60/120 stehen korrekt
in der CSV) und kompiliert - war aber nie zu sehen. Ursache: unter
%APPDATA%\MetaQuotes\Terminal\ liegen VIER Instanz-Ordner. Meine
Kopier-Zeile bestimmte das Ziel ueber "hat MQL5\Indicators" +
Select-Object -First 1 und traf 0BA5CADA..., waehrend der Bot nach
D0E8209F... schreibt und der Chart dort laeuft.

Folge: der Chart lief seit heute frueh weiter auf v1.29 - ohne
Prognose-Kegel UND ohne die Konsolidierungs-Beschriftung (v1.30), obwohl
beide "gebaut und mit 0 Fehlern kompiliert" gemeldet waren.

Behoben: v1.31 in das Terminal kopiert und kompiliert, das die CSV
schreibt. Verifiziert: #property version 1.31, ex5 frisch, CN-Handler und
TCONSOL-Label im Terminal-Quelltext vorhanden.

CLAUDE.md: Fallstrick dokumentiert samt der richtigen Ziel-Ermittlung (ueber
die vom Bot geschriebene CSV, nicht ueber die blosse Existenz von
MQL5\Indicators) und der Gegenprobe nach jedem Kompilieren.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 18:39:06 +02:00
Axel HocksandClaude Opus 5 3314b6e9b1 Flip-Close bekommt Nachrang gegenueber dem S/R-Close (gemessen)
User-Frage "sollten wir den S/R close auch deaktivieren?" -> nein, die
beiden sind gegensaetzlich gemessen. Aber sie konkurrieren seit dem Einbau
um dieselben Trades, und die S/R-Freigabe lief OHNE Flip-Close.

backtest_exit_combo.py (NEU, 80k M5, 2 Halbjahre, Echtkosten, Exit-Kern aus
core/exit_model.py, 5 Varianten auf IDENTISCHEN Entries):
    nur S/R-Close            H1 +59 · H2 -14   (535/284 S/R-Closes)
    nur Flip-Close           H1  -1 · H2 -43
    BEIDE                    H1 +56 · H2 -50   (507/252)
    BEIDE, Flip nachrangig   H1 +62 · H2 -49   (516/260)

KOLLISION BELEGT: der Flip nahm dem S/R-Close 28 bzw. 32 Trades weg
(5-11 %) - genau die, fuer die dieser validiert ist. Mit Nachrang ist es in
BEIDEN Haelften besser als ohne.

Umsetzung: liegt ein S/R-ZIEL <=0,6xATR entfernt (dieselbe Schwelle wie der
Live-Hinweis), haelt der Flip sich zurueck.
[trading] auto_flip_close_subordinate (Default true).
Mit 4 Szenarien getestet: in Reichweite, ausser Reichweite, kein Level,
Nachrang aus.

EHRLICH DAZU: auch mit Nachrang kostet der Flip in H2 rund 35 R gegenueber
"nur S/R-Close" (-49 vs -14). Der Nachrang begrenzt den Schaden, er dreht
ihn nicht um.

METHODIK-FEHLER BEIM BAU, KORRIGIERT: der erste Lauf liess die sequentielle
Sim nach dem Exit bei xb+1 weiterlaufen - dadurch hatte JEDE Variante eine
ANDERE Trade-Folge und die Zahlen waren nicht vergleichbar. Jetzt feste,
geteilte Entry-Liste wie in backtest_pbreak_rvalue.py. (Die zunaechst
gemeldeten Deltas -195/-144 stammten aus diesem konfundierten Lauf.)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 18:15:09 +02:00
Axel HocksandClaude Opus 5 fea91fddb3 Auto-Flip-Close gebaut (User-Wunsch) - trotz erneut negativer Messung
User: "schliesse den trade automatisch beim close signal". Dreht die
Empfehlung gegen die offene Position und steht sie >=0,5xATR im Plus ->
close(reason="flip_close").

VORHER NEU GEMESSEN, weil das alte Urteil (backtest_flipclose.py,
16.07.) auf einem VIERTEN Exit-Modell fusste: Trail fest 1,5 (live jetzt
1,0), keine Lock-Phase, kein Time-Stop, kein Initial-TP, _MAXH 288 statt
200, Phasen ueber den Bar-Close statt ueber das High-Water.

backtest_flipclose2.py (80k M5, 2 Halbjahre, Echtkosten, Exit aus
core/exit_model.py) bestaetigt das alte Urteil - deutlicher:
    Basis ohne Flip      H1 SigmaR -537 · H2 -140
    Flip ab 0,0xATR      Delta H1 -126 · H2 -221
    Flip ab 0,3xATR      Delta H1  -77 · H2 -216
    Flip ab 0,5xATR      Delta H1  -92 · H2 -160   <- mildeste, Default
    Flip auch im Minus   Delta H1 -205 · H2 -364
JEDE Variante ist in BEIDEN Haelften schlechter. Trefferquote steigt
39 -> 45 %, Ertrag faellt = Gewinner-Kappen (die nachlaufende EMA dreht
oft mitten im Pullback).

Gebaut wurde die mildeste Variante (0,5xATR Mindestgewinn), abschaltbar
ueber [trading] auto_flip_close.

Fuer die Neumessung bekam exit_model.simulate() einen stop_when-Hook
(+ ret_bar), damit die Phasen-Mechanik nicht zum fuenften Mal kopiert
werden musste. Rueckwaertskompatibilitaet verifiziert: ohne Hook bitgenau
identisch (die zunaechst gemeldeten Abweichungen kamen allein aus
LIVE.mult 1,5 -> 1,0, gegengeprueft mit mult=1.5 -> identisch).

Mit 10 synthetischen Szenarien getestet: beide Richtungen, aus, unter
Schwelle, gleichgerichtet, WARTEN, im Minus, flat, Startup-Schonfrist,
Ticket-Dedup - alle korrekt.

B4/B5-Pflicht: Live-Ertrag gegen die Erwartung halten, bei Drift
auto_flip_close=false.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 17:55:06 +02:00
Axel HocksandClaude Opus 5 f1cc3775f9 Gesamtempfehlung zeigt jetzt, WARUM sie wartet (v=126)
User-Fund: "WARTEN · M15" neben "Modul-Konsens: stark LONG" liest sich wie
ein Widerspruch. Ist keiner - die Welle HAT eine Richtung und haengt nur an
einem Gate. Der Grund stand aber nur als Textzeile in der Meldungen-Karte,
also weit weg von der Stelle, an der die Frage aufkommt.

wave.breakout {pending, dir, level, need} wurde berechnet und im Snapshot
gespeichert, vom Frontend aber NIRGENDS gerendert. Jetzt haengt es direkt
an der Headline:
    "◌ WARTEN · M15 · LONG, noch 0.02 bis zur Bestaetigung"

Erste Auswertung der gestern eingebauten block_reason-Telemetrie (3 h):
    breakout_pending  63 %
    entry_room        20 %
    min_conf          18 %
    Totband / HTF-Gegen-Trend:  KEIN EINZIGES MAL

Das beantwortet die offene Frage aus dem TF-Churn-Fix: die 93 % WARTEN
kommen nicht daher, dass die Welle richtungslos waere, sondern von den
Gates - allen voran der Breakout-Bestaetigung, die bis zum Fix desselben
Tages rechnerisch gar nicht fertig werden konnte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 16:29:55 +02:00
Axel HocksandClaude Opus 5 df092674cb Konsens-Zeile korrigiert: falscher Bezug + Nenner passte nicht zu den Chips
User-Fund: "Modul-Konsens: stark LONG · 4/4 Module fuer WARTEN" - dabei sind
9 Module sichtbar. Zwei echte Fehler.

(a) FALSCHER BEZUG: der Text lautete "... Module fuer ${sig}" mit der
HEADLINE als Bezug. Seit dem ref-Fix vom 30.07. zaehlt `agree` bei WARTEN
aber die Uebereinstimmung mit der BIAS-Richtung - deshalb stand dort
"stark LONG ... fuer WARTEN". Die Richtung kommt jetzt als verdict.ref_dir
vom Backend, statt im Frontend aus `bias` nachgebaut zu werden (dort galt
ein +-0,05-Totband, im Backend `bias > 0` - die Nachbildung waere am Rand
auseinandergelaufen; dieselbe Sorte Divergenz wie die fuenf
Deployment-Drift-Faelle desselben Tages).

(b) ANDERER NENNER ALS DIE CHIPS: `total` zaehlt nur Module MIT Aussage
(Gewicht>0, ohne die Welle). Nach den Gewichts-Fixes des Tages schweigen
deutlich mehr Module -> "4/4" bei 9 sichtbaren Chips. Neu ist
verdict.silent (Module mit Gewicht 0) dabei, sodass die Summe aufgeht.

Live verifiziert: "Modul-Konsens: leicht LONG · 3 von 5 stimmberechtigten
fuer LONG (4 ohne Aussage)" - 5 + 4 = 9. Sonderfall "kein Modul mit klarer
Aussage" abgedeckt. v=125.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 15:37:37 +02:00
Axel HocksandClaude Opus 5 a1f471f163 Timer-Erinnerung fuer den zweiten Modul-Audit angelegt
measurement_reminder.py: neuer Punkt "Modul-Audit: zweiter Durchgang",
faellig 28 Tage nach dem ersten (also ab 2026-08-28).

Begruendung im Eintrag: am 31.07. wurden an EINEM Tag 5 Deployment-Drift-
Faelle UND 5 Modul-Inkonsistenzen gefunden - bei gezielter Suche in wenigen
Stunden. Die Trefferquote spricht dafuer, dass weitere existieren.
analyze_divergence.py meldet die Klasse "Betrieb != Messung" inzwischen
selbst; die Klasse "Modul-Inkonsistenz" (Gewichte, stale Quellen, tote
Config, Sonderfaelle) braucht dagegen einen bewussten Durchgang.

Kein neuer Windows-Task noetig - OilMeasurementReminder laeuft bereits
taeglich 18:00 und prueft alle Eintraege. Task testweise ausgeloest:
LastTaskResult 0, Arbeitsverzeichnis korrekt gesetzt. (Ein
Erinnerungssystem, das still scheitert, waere schlimmer als keins - genau
dafuer gibt es das Ding.)

CLAUDE.md-Tabelle auf den Stand 31.07. gebracht; erledigte Punkte
ausgetragen (P(break)-Genauigkeit -> analyze_pbreak_live.py, Modell
daraufhin nachtrainiert; Chartmuster-Kontrolltest -> 30.07.).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 15:29:33 +02:00
Axel HocksandClaude Opus 5 367d70eb7a Modul-Audit: 5 Inkonsistenzen behoben + Secret-Luecke in .gitignore geschlossen
Systematische Pruefung aller Verdict-Module gegen die Regel "keine Aussage
-> Gewicht 0", dazu Config-, Frontend- und Level-Quellen.

(1) KI-COPILOT - der groesste Rest des Musters. Ein explizites "NEUTRAL"
zaehlte als echte Stimme mit Gewicht 1,0. Gemessen (verdict_votes, n=7.084):
das ist in 93,1 % der Faelle der Zustand (Elliott: 1,3 %) - also der
Normalzustand des Copiloten, kein abgewogenes Urteil. Damit hatte
ausgerechnet das Modul mit der schwaechsten Beleglage
(analyze_verdict_calibration.py: nicht robust praediktiv) den GROESSTEN
daempfenden Einfluss auf die Bias-Nadel.

(2) ELLIOTT analog: Gewicht nur bei gerichtetem Ziel.

Kumulierte Wirkung aller Gewichts-Fixes des Tages:
    Oe|bias|  0,370 -> 0,441 -> 0,569  (= 1,54x), betrifft 79,5 % der Zeilen
Live verifiziert: KI "NEUTRAL" -> Gewicht 0,00, bias 2,5/4,5 = 0,556
statt 2,5/5,5 = 0,455.

(3) STALE [zones] SPEISTEN DIE WELLEN-KONFIDENZ - entfernt. _sr_levels zog
beide Kanten jeder [zones]-Zone als S/R-Linien heran: 16 Kanten aus einem
~10 $ TIEFEREN Regime (72,90-77,00 bei Kurs 85,3). Aus dem Chart waren sie
am 14.07. schon entfernt worden, WEIL sie stale sind - in die Konfidenz
liefen sie weiter. Realer Audit-Fall: market.sr hatte gar keine
Widerstaende (M15-Cluster sind in frischen Trends oft leer) -> der
"naechste Widerstand" kam aus der fvg-Zone bei 88,00 (2,66 $ weg), der
echte lag bei 85,315 (0,03 $ weg). Der Abzug "dicht unter Widerstand"
(-12) greift nur innerhalb 0,5xATR und feuerte deshalb NIE.

(4) TOTE CONFIG entfernt: [trading] trail_timeframe (nirgends gelesen, Name
suggeriert faelschlich die Trailing-TF) und die komplette [setups]-Sektion
(11 Schluessel).

(5) raise StopIteration als Sprung in einem breiten except durch ein if
ersetzt - funktionierte, waere aber fragil sobald dort Logging dazukommt.

SICHERHEIT: beim Anlegen des Config-Backups fiel auf, dass .gitignore nur
"oil_widget_config.ini" abdeckt, NICHT "...ini.bak-<datum>". Das Backup lag
ungeschuetzt als untracked im Repo und enthaelt dieselben Live-Keys.
Muster ergaenzt. Gegenprobe: die .example-Datei enthaelt 10 secret-artige
Felder, davon 0 identisch mit der echten ini - alles Platzhalter.

Sauber geblieben: Frontend<->Backend (0 verwaiste Element-IDs), alle
uebrigen Verdict-Gewichte, alle anderen Config-Schluessel.

OFFEN (messpflichtig): die Wellen-Konfidenz aus _draw_levels speisen statt
aus dem Misch-Set - wuerde den -12-Abzug tatsaechlich ausloesen, also die
Konfidenz senken und das 55%-Gate verschieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 15:26:15 +02:00
Axel HocksandClaude Opus 5 23c68e8837 Verdict: M30/H1 bekommen Gewicht 0 ohne Aussage (Bias-Fix Teil 3)
Anlass war die User-Frage "H1 aus der Gesamtempfehlung entfernen, da wir
jetzt mit M30 arbeiten?". Antwort NEIN, aber die Frage hat einen echten
Defekt freigelegt.

Zur Praemisse: auf M30 umgestellt wurde die S/R-LEVEL-QUELLE, nicht die
Zeitebenen-Logik. H1 war nie Basis-TF (tf_max=M30), sondern immer Kontext.

Zur vermuteten Doppelzaehlung - gemessen an verdict_votes (n=7.074):
bei gerichteter Welle stimmt M30 nur zu 14,9 % mit ihr ueberein, H1 zu
47 %, M30 und H1 untereinander nur zu 33,8 %. Keine redundanten Stimmen
(Reversals heben den M30-Filter bewusst auf, und M30 ist meist gar nicht
gerichtet). H1 fliesst zwar auch als Konfluenz-Bonus in die Konfidenz -
aber in eine ANDERE Kennzahl (Ring vs. Nadel), nicht zweimal in dieselbe.

DER ECHTE DEFEKT: add("M30", ...) und add("H1", ...) hatten Gewicht 1,5
UNBEDINGT, auch bei Stimme 0. Damit derselbe Fehler wie beim Wellen-Modul
(Bias-Fix Teil 2 vom 30.07.), hier uebersehen. Eine 0-Stimme heisst
"EMA-Abstand im Totband" = keine Aussage, nicht "neutral" - mit vollem
Gewicht im Nenner zog sie die Bias-Nadel dauerhaft zur Mitte.

Gemessen an 7.074 Verdicts: M30 ist in 57,9 % der Faelle ohne Aussage
(H1 nur 1,8 %). Oe-Bias-Betrag 0,371 -> 0,441, Median-Verstaerkung 1,30x,
in 33,3 % der Zeilen deutlich staerkere Nadel.

Fix: 1.5 if vote != 0 else 0.0 fuer beide. `others` filtert bereits auf
weight>0, die "x/y einig"-Zaehlung zieht damit automatisch mit.

Live verifiziert: M30 "flach" -> Gewicht 0,00, bias -1,5/4,5 = -0,333
statt -1,5/6,0 = -0,250 (genau die gemessene 1,33x-Verstaerkung),
agree 3/5 statt 3/6.

REINE ANZEIGE - die Order-Logik haengt an der Wellen-Headline, nicht am
Bias.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 13:43:38 +02:00
Axel HocksandClaude Opus 5 fe5c2aae0a Legacy-Recheck vervollstaendigt: Bounce und ER-Chop-Gate nachgerechnet
backtest_legacy_recheck.py um zwei Abschnitte erweitert (Reversal-Flag und
Efficiency Ratio je Trade), damit alle vier Befunde abgedeckt sind, die auf
dem vereinfachten Legacy-Exit ruhten.

BOUNCE / REVERSAL - relative Aussage haelt, absolute NICHT:
    H1  Reversal -0,034 (PF 0,93)  vs  Trend -0,174 (PF 0,68)
    H2  Reversal +0,029 (PF 1,06)  vs  Trend -0,073 (PF 0,86)
Reversal schlaegt Trend in BEIDEN Haelften (+0,140/+0,102) - robust. Aber
die dokumentierte Kennzahl "OeR +0,185 / PF 1,35 / 70 % Treffer"
REPRODUZIERT NICHT: mit echtem Exit + Echtkosten liegt das Setup bei
~Breakeven. Die alten Werte stammen aus dem vereinfachten Exit ohne Kosten.
Das Setup bleibt sinnvoll als nachrangiges Zweitsignal (so ist es live auch
eingebaut), ist aber kein +0,185-Ertragsbringer.

ER-CHOP-GATE - Ablehnung BESTAETIGT: alle vier ER-Baender liegen gleichauf
(H1 -0,137..-0,172, H2 -0,049..-0,067). Die Efficiency Ratio trennt auch mit
dem echten Exit nicht. Gate bleibt zu Recht verworfen.

Damit sind alle sechs Legacy-Skripte abgedeckt: EIA bestaetigt, Dead-Hours
nicht selektiv, Bounce nur relativ, ER-Gate zu Recht verworfen.

Einschraenkung unveraendert: der Recheck handelt die UNGEGATETE EMA-Richtung
(ohne min_conf, Breakout-Bestaetigung, HTF-Filter, Raum-Gate) - fuer die
Vergleiche neutral, die absoluten Werte sind nicht das Live-Signal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 13:25:46 +02:00
Axel HocksandClaude Opus 5 bb17ecff0a Beide offenen Vorschlaege umgesetzt: Trail 1,0 + Legacy-Recheck
VORSCHLAG 1 - Trail-Multiplikator 1,5 -> 1,0 (core/exit_model.py LIVE.mult),
live verifiziert ("AKTIVIERT ... mult=1.0x").
Voller Sweep mit FIXEM SL 2,0 (backtest_trailmult.py, 8 Werte 0,5-3,0):
enger ist MONOTON besser. Wave-Signal H1/H2 SigmaR:
    0,5 +1258/+2418 · 0,8 +852/+1668 · 1,0 +80/+1360
    1,5 -220/+1305 · 2,0 -394/+1198 · 2,5 -1072/+1327
Optimum am RAND = Warnsignal, deshalb Gegentest auf SQUEEZE-Entries mit
Echtkosten (--squeeze): das Setup lebt von Laeufern, muesste also
dagegenhalten - tut es NICHT (1,0: H1 -0,202/H2 +0,010 · 1,5:
-0,219/-0,032). Deshalb 1,0 (besser als 1,5 in beiden Haelften auf BEIDEN
Signalmengen), aber NICHT 0,5: Randwert, und die Sim modelliert keine
Exit-Slippage - ein engerer Trail loest viel haeufiger aus und ist davon
staerker betroffen (real bis 0,75xATR ueber den Stop).

VORSCHLAG 2 - backtest_legacy_recheck.py (NEU): die beiden Legacy-Befunde
nachgerechnet, die live ECHTE Gates steuern.
  EIA-Blackout BESTAETIGT: auch mit echtem Exit + Echtkosten in BEIDEN
  Haelften schlechter als der Rest (-0,097 / -0,119). Gate ist gedeckt.
  DEAD-HOURS reproduzieren NICHT als selektiver Befund: 19 von 22 Stunden
  sind in beiden Haelften negativ, keine robust positive Stunde. Die alte
  Auswahl (0-7, 12, 16) ist damit nicht mehr gestuetzt. Praktisch folgenlos
  (dead_hours ist leer), aber eine Reaktivierung auf der alten Begruendung
  waere nicht gedeckt.

Einschraenkung selbst benannt: der Recheck handelt die UNGEGATETE
EMA-Richtung (ohne min_conf, Breakout-Bestaetigung, HTF-Filter, Raum-Gate).
Fuer den Vergleich neutral, die absoluten Werte sind nicht das Live-Signal.

Konsequenz fuer den TF-Churn-Fix: "WARTEN Richtung 43 %" ist eine
Haeufigkeits-, keine Ertragsgroesse - mehr Signale sind nur dann besser,
wenn die freigegebenen Setups auch tragen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 13:09:32 +02:00
Axel HocksandClaude Opus 5 4c1a68a7e1 Stufe 3: geteilter Exit-Kern (core/exit_model.py) + Korrektur der Stufe-1-Begruendung
core/exit_model.py (NEU): LIVE:ExitParams als EINZIGE Quelle der Exit-
Parameter; core/trailing.py leitet _TRAIL_START_ATR, _BREAKEVEN_ATR,
_PHASE4_* und _MULT_BY_TF jetzt davon ab statt eigene Zahlen zu halten.
Aendert jemand LIVE.mult, aendern sich Live-Verhalten UND Messung gemeinsam
-> Deployment-Drift-Fall 3 ist konstruktiv unmoeglich geworden. Dazu die
kanonische simulate() fuer Backtests mit Flags timestop/use_tp, um
Teilmodelle EXPLIZIT zu machen statt zu verstecken.

BEFUNDE BEIM REFACTOR - schlimmer als angenommen:
(1) Es gibt mindestens DREI materiell verschiedene Exit-Modelle:
    A) Phasen ~ live (_trailing/_exit/_atrfloor/_candle_fade)
    B) EINFACH - _TPTRAIL=0.5, kein Breakeven, kein Lock, kein Time-Stop,
       _MAXH=240 (_hourly, _hourly_split, _bounce, _events, _deadhour,
       _chopgate)
    C) Phasen mit be_on=1.0 statt 1,3 (_breakout, _confluence_angle)
    => Dead-Hours, EIA-Blackout, Bounce, Chop-Gate, Stunden-Analyse und
    breakout_k ruhen auf einem Exit, der dem Live-System nicht entspricht.
    Bewusst NICHT stillschweigend umgestellt (wuerde historische Schluesse
    rueckwirkend aendern); als LEGACY_SIMPLE / LEGACY_BE10 markiert.
(2) Selbst die "Phasen"-Skripte weichen voneinander ab: _trailing hat TP
    aber keinen Time-Stop, _candle_fade Time-Stop aber kein TP, _atrfloor
    liefert Punkte statt R.
(3) backtest_trailing.py koppelt den Initial-SL an mult (sl = entry -
    d*mult*atr) statt fix 2,0.

KORREKTUR DER STUFE-1-BEGRUENDUNG: die "67 % groesserer Einzelverlust" war
ein Artefakt von (3) - dort war der Worst-Case per Konstruktion gleich dem
Multiplikator. Sauber nachgemessen mit fixem SL (backtest_trailmult.py, NEU,
80k Bars, 2 Halbjahre):
    Trail 1,0  H1  -73 · H2 +1346 · Worst -2,00
    Trail 1,5  H1 -325 · H2 +1294 · Worst -2,00   (live)
    Trail 2,0  H1 -446 · H2 +1195 · Worst -2,00
    Trail 2,5  H1 -1174 · H2 +1223 · Worst -2,00
    Trail 3,0  H1 -1088 · H2 +1397 · Worst -2,00
Der Worst-Case ist bei JEDEM Multiplikator identisch -2,00. Die Entscheidung
bleibt richtig (1,5 schlaegt 2,0 und 2,5 in beiden Haelften), nur die
Tail-Begruendung war falsch.

NEU UND OFFEN: Trail 1,0 schlaegt 1,5 in BEIDEN Haelften - eigener
Vorschlag, bewusst nicht ungefragt umgesetzt.

Aequivalenz verifiziert (500 synthetische Kursreihen je Fall): _candle_fade
und _atrfloor sind bitgenau identisch zur neuen simulate().
Live verifiziert: "AKTIVIERT ATR=0.5796 (M30) mult=1.5x".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 13:02:02 +02:00
Axel HocksandClaude Opus 5 97617cd81d Deployment-Drift: Stufe 1 (Trail-mult) + Stufe 2 (Entscheidungs-Telemetrie)
Behebt die strukturelle Schwachstelle, die heute dreimal zugeschlagen hat:
Komponenten werden unter anderen Bedingungen BETRIEBEN als VALIDIERT.
Track B schuetzt gegen Overfitting, nicht gegen Deployment-Drift.

STUFE 1 (core/trailing.py): _MULT_BY_TF durchgehend 1,5 (vorher M15 2,0 /
M30 2,5 / H1 3,0) und _MULT_BREAKOUT_ADD 0,5 -> 0,0. Die Staffelung war nie
gemessen; backtest_trailing.py validiert nur 1,5 und die breiteren Werte
sind dort messbar schlechter (80k Bars, 2 Halbjahre):
    mult 1,5  H1 SigmaR  -249 · H2 +1252 · Worst -1,50
    mult 2,0  H1 SigmaR  -412 · H2 +1187 · Worst -2,00
    mult 2,5  H1 SigmaR -1367 · H2 +1450 · Worst -2,50
Auf M30 fuhr der Bot also 5,5x schlechteres H1 und einen 67 % groesseren
Einzelverlust; bei Breakouts waren es 3,0 - nie getestet. Relevant, weil die
TF-Heuristik oft auf M15/M30 landet (31.07.: 19 von 33 Phasen).

STUFE 2a (wave_rec/history/engine): jede Empfehlung loggt einen
maschinenlesbaren block_reason - deadband, dead_hour, eia, htf_counter,
stretch, min_conf, breakout_pending, entry_room, no_data, stale. DB migriert
(Backup angelegt). Ohne den war nicht feststellbar, WELCHES der Gates die
93 % WARTEN erzeugt (Backtest-Erwartung ~43 %).

STUFE 2b (analyze_divergence.py, NEU): haelt vier Dinge gegen die
Backtest-Erwartung - A Signal-Verteilung, B Gate-Anteile inkl.
"im Backtest modelliert?", C TF-Wechsel-Rate, D0 Modell-Kalibrierung,
D Merkmals-Drift gegen _PB_MU/_SD.

LEHRE AUS DEM BAU SELBST: die Merkmals-Drift (D) haette den realen Fehler
NICHT gefangen - mom3 lag nur 0,50 Sigma unter mu, bei Gewicht 1,43 wurden
daraus aber -0,71 im Logit (23 % statt 41 % vorhergesagt). Deshalb ist D0
der schaerfere Test und die D-Schwelle auf 0,5 Sigma gesetzt.

Erster Lauf nach dem Fix bestaetigt das Nachtraining live:
D0 = 27,0 % vorhergesagt vs 28,0 % real (vorher 23 vs 41).

Stufe 3 (geteilter Exit-Kern) bleibt offen, spaeter und einzeln.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 12:54:34 +02:00
Axel HocksandClaude Opus 5 0208101707 TF-Churn-Fix: Breakout-Bestaetigung ueberlebt TF-Wechsel + Verweildauer
Auslöser: User-Frage warum der Bot die Rally am 31.07. (82,5 -> 84,4 in 2 h)
nicht gehandelt hat. Befund: in dem Fenster 99x WARTEN und 1x SHORT - und
dieser SHORT wurde am Tief autonom eroeffnet (AUTOSIG, -26,31 EUR, per
adverse15 geschlossen). Den LONG machte der User um 11:56 von Hand.

Der WARTEN-Anteil ist strukturell zu hoch:
   Backtest-Erwartung (backtest_dist.py)   ~43 %
   Live letzte 24 h                         93,2 %
   Live letzte 7 Tage                       88,0 %
   Live gesamt (93.599 Zeilen)              78,6 %

MECHANISMUS (im Log belegt): _choose_tf setzt den Score einer TF hart auf
0,0, sobald sie ueberdehnt ist - genau das passiert M5 IM Trend. Real am
31.07.: M5 sprang zwischen 0,00 und 1,93, die TF wechselte 33x am Tag
(Median-Abstand 5 min). Die 1,2x-Hysterese ist dagegen wirkungslos. Und
set_timeframe() verwarf bei JEDEM Wechsel die laufende Breakout-
Bestaetigung und verankerte sie beim aktuellen Kurs neu. Bei k=0,3 und
ATR_M30~0,53 braucht sie ~0,16 $, der Kurs lief ~0,08 $ je 5 min -> die
Bestaetigung konnte rechnerisch nie fertig werden.

Gleicher Fehlertyp wie beim P(break)-Modell am selben Tag:
backtest_breakout.py hat k=0,3 auf einer FESTEN Zeitebene validiert; live
wandert sie - die Bedingung, unter der die Messung gilt, existiert im
Betrieb nicht.

FIX 1 (wave_rec.set_timeframe): _pend wird nicht mehr zurueckgesetzt. Der
Anker gehoert zum Signal, nicht zur Zeitebene; bei Richtungswechsel
verankert _confirm_breakout ohnehin neu.
FIX 2 (engine._tf_loop): Mindest-Verweildauer [trading] tf_min_dwell_s=900.

Verifiziert mit synthetischen Szenarien: Fix 1 - Bestaetigung ueberlebt
M5->M30 und feuert LONG, Richtungswechsel verankert korrekt neu; Fix 2 -
an der ECHTEN Score-Folge vom 31.07. nachgespielt: 4 Wechsel -> 2.

NICHT backtestbar (Backtests laufen auf fester TF, das Churning existiert
dort nicht). Begruendung ist "stellt die Bedingung her, unter der die
Messung gilt", nicht "gemessen besser". Erfolgskontrolle = WARTEN-Anteil
muss sich Richtung ~43 % bewegen.

Bewusst nicht behoben: der 0,0-Einbruch des Scores bei Ueberdehnung selbst
- das waere eine Aenderung der TF-Bewertung und damit messpflichtig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 12:37:54 +02:00
Axel HocksandClaude Opus 5 0944b1c13a P(break) neu trainiert auf live-spiegelnder Stichprobe (Weg b) - eingebaut
Behebt die am selben Tag gefundene Merkmals-Diskrepanz: das alte Modell war
auf "Anlauf zu einem beim Entry FIXIERTEN Level" trainiert, live waehlt
_draw_levels das Level jede Sekunde neu -> mom3 live 0,15 statt 1,45 ->
Ausgabe immer ~23 % -> Gate seit Inbetriebnahme faktisch nie aktiv.

backtest_pbreak_retrain.py: Stichprobe spiegelt den Live-Pfad (Level
dynamisch mit Hysterese, gesampelt an JEDEM Bar im 0,15xATR-Band, keine
Anlauf-Bedingung). Kontrolle: Merkmalsmittel der Stichprobe (mom6 0,203 /
mom3 0,202) treffen die live rekonstruierten Werte (0,181 / 0,149).

  AUC auf dieser Stichprobe (H2, out-of-sample):
      ALT-Modell  0,368   (schlechter als Zufall, 19,2 % vs real 39,4 %)
      NEU-Modell  0,654   kalibriert

backtest_pbreak_rvalue.py (R-Ertrag, Echtkosten, Baseline = nur Trailing):
NEU schlaegt ALT in BEIDEN Haelften bei JEDER Schwelle. Gegen die Baseline
gewinnt es bei 0,35/0,45/0,55 in beiden (bei 0,60 kippt H1).
Bestwert 0,35: H1 -149 vs -506 (+357), H2 +1308 vs -110 (+1418).
Nebenbefund: das ALTE Modell war in H1 schlechter als gar kein Auto-Close.

EINGEBAUT: neue _PB_MU/_SD/_W (final auf allen 80k gefittet, n=76.542,
Basisrate 37,8 %, nach H1->H2-Validierung; alte Werte als Kommentar) +
sr_close_pbreak 0,55 -> 0,35, Config-Waechter-Anker mitgezogen.
Verifiziert: Chart-Linien zeigen 43 %/36 % statt 8-15 %.

ACHTUNG - invertiert eine alte Projekt-Regel: mom3-Gewicht dreht das
Vorzeichen (+1,4330 -> -0,5420). Alt: "kriecht ans Level -> 26 % Bruch, mit
Schwung -> laufen lassen". Neu: Anlauf-Schub -> 26,5 % (Level absorbiert
ihn und haelt), Schwung weg vom Level -> 51 %. Beides gilt in seiner
Population (fixiertes vs. dynamisches Level); fuer den Live-Pfad gilt die
neue Lesart.

Offen: auch NEU schliesst bei 0,35 noch ~94-97 % der Positionen (waehlt vor
allem den besseren Moment). Touch-Zahl bringt im neuen Modell nichts mehr
(0,652 vs 0,654) - die dynamische Level-Wahl erfasst den Effekt bereits.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:57:16 +02:00