Commit Graph
125 Commits
Author SHA1 Message Date
Axel HocksandClaude Opus 5 90d77a2305 Pending-Pfad fuer SIG: ruhende Stop-Order am Bestaetigungs-Level
SIG laeuft damit auf der gemessen positiven Variante (OeR +0,35/+0,32, PF 2,2)
statt auf der Market-Order (-0,09/-0,11).

Der heikelste Punkt war nicht die Order, sondern die Kollision beider Pfade:
trader.pending_orders() liefert ALLE magic-gleichen Orders, zwei getrennte
Manager haetten sich gegenseitig storniert - sporadisch und im Log kaum
erkennbar. Deshalb EIN gemeinsamer Ziel-Zustand (engine._pending_ziel), der
Manager gleicht nur noch ab. Vorrang Squeeze > Signal (unabhaengig validiert,
selten; das Signal feuert dauernd, es gibt einen Positions-Slot).

Zwei additive Ergaenzungen in wave_rec._confirm_breakout: das
Bestaetigungs-Level wird auch NACH der Bestaetigung veroeffentlicht (die
Nachjagd-Bremse braucht es genau dann; pending bleibt False, Frontend
unberuehrt), und conf = die Konfidenz VOR dem Stummschalten - sonst muesste
die ruhende Order blind platziert werden.

Nachjagd-Bremse jetzt auch fuer SIG (0,20 xATR, Haertetest-gedeckt).
12 Szenarien getestet, live am Snapshot verifiziert. Snapshot-Felder
squeeze_pending_levels -> pending_levels + pending_quelle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 11:43:04 +02:00
Axel HocksandClaude Opus 5 12fb11fa44 Auto-Signal (SIG) neu gemessen: besteht erstmals - aber nur am Level, nicht am Markt
backtest_auto_signal_v3.py, voller Live-Gate-Stack (echte _build /
_confirm_breakout / _room_gate), sequentiell EIN Slot, Live-Dedup,
kanonischer Exit, Echtkosten, 80k M5, 2 Halbjahre.

A) Einstieg am Bar-Close (= heutige Market-Order): in ALLEN acht Feldern
   negativ (Konf 55/65/75/85 x 2 Halbjahre). Bestaetigt die drei Vormessungen.
B) Einstieg am Bestaetigungs-Level (_pend["level"], ruhende Stop-Order):
   besteht in ALLEN acht - WR 39,6 -> 53,2 %, PF 0,83 -> 2,20, und alle vier
   Nachbar-Schwellen halten mit.

Haertetest Fill-Slippage (Konf>=65): +0,05 -> +0,315/+0,249 · +0,20 ->
+0,148/+0,090 (noch beidseitig positiv) · +0,31 -> +0,026/-0,031. Die letzte
Zeile ist die interne Kontrolle: bei Slippage gleich dem gemessenen
Median-Abstand (0,311 xATR) konvergiert B gegen A.

Nichts umgeschaltet. Grenzen dokumentiert: fuer SIG ist nicht verifizierbar,
wo live zwischen A und B liegt (nur 4 echte Trades); _pend verankert sich
staendig neu, eine ruhende Order muesste nachgezogen werden und faellt bei
Nicht-Platzierbarkeit auf A zurueck; _pend steht nicht im Snapshot.

Methodik-Fehler beim Bau gefunden und behoben: der erste Entwurf liess
pend["level"] nach der Bestaetigung stehen und waere bei verzoegertem Einstieg
zu einem laengst verlassenen Preis eingestiegen - sichtbar an einem
unplausiblen Bruch zwischen Konf 65 und 75. Behoben ueber ein frisch-Flag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 10:55:32 +02:00
Axel HocksandClaude Opus 5 43b7756df3 Manuelle Trades, Letzte Trades und Kurslueken in den Statistik-Tab verschoben
User-Vorgabe: die drei sind Rueckschau, das Dashboard soll das
Handlungsrelevante zeigen. Reiner Umzug im Markup - keine Logik beruehrt.
Die Karten werden weiterhin von render() aus dem Snapshot gefuettert und
haengen NICHT an loadStats(); ein ausgeblendeter View ist nur display:none,
die Elemente bleiben im DOM.

Noetig war eine CSS-Regel: #view-stats > .card{margin:11px 10px}. Das
Dashboard ist ein <main>-GRID mit eigenem Padding, #view-stats eine schlichte
<section> - ohne die Regel klebten die Karten randlos aneinander und
.card.wide{grid-column:1/-1} liefe ins Leere.

Verifiziert am ausgelieferten HTML (alle drei nach id="view-stats",
card-stats-live bleibt im Dashboard), keine doppelten IDs, Tag-Balance
geprueft. v=138.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 09:10:25 +02:00
Axel HocksandClaude Opus 5 5f70980e59 Erfolgskontrolle fuer den Stop-Order-Umbau: Skript + Reminder
analyze_squeeze_entry_gap.py fuehrt die zwei noetigen Quellen zusammen - das
Ausbruchs-Level steht NUR im Log, der tatsaechliche Fill NUR in trades - und
splittet am Umbau-Stichtag. Die Erfolgsmeldung ist paradox: eine per Pending
gefuellte Order erzeugt KEINE AUTO-SQUEEZE-ENTRY-Logzeile (die entsteht nur im
Market-Fallback), Squeeze-Trades ohne Log-Treffer sind also der Erfolg. Das
Skript weist sie deshalb getrennt aus.

Als Messung squeeze_entry_gap im measurement_reminder.py hinterlegt (>=12
Squeeze-Trades ab dem Umbau). Stichtag exakt 05.08. 08:55 statt Mitternacht -
der 08:33-Trade lief noch ueber die Market-Order und haette die Zaehlung
verfaelscht (0/12 statt faelschlich 1/12).

Zahlen-Korrektur: die zuerst dokumentierten +0,306 / +0,741 xATR stammten aus
einer Scratchpad-Auswertung mit FESTEM Stundenversatz. DST-korrekt ueber
zoneinfo sind es +0,275 / +0,686 (n=34 unveraendert). In CLAUDE.md, engine.py,
trader.py und der ini nachgezogen; die Schlussfolgerung aendert sich nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 09:06:50 +02:00
Axel HocksandClaude Opus 5 5e0e8b00ca Squeeze-Einstieg ueber ruhende Stop-Orders + Meta-Labeling gemessen (verworfen)
1) STOP-ORDER STATT MARKET (gebaut, live). engine._manage_squeeze_pending haelt
beide Box-Grenzen mit BUY_STOP/SELL_STOP bestueckt, solange der Squeeze armed
ist; trader.place_stop/cancel_pending/pending_orders neu. Groesse und SL kommen
aus denselben Funktionen wie die Market-Order, nur bezogen auf den Trigger.
OCO-Ersatz: faellt eine Seite, wird die andere im selben Tick storniert.

Der kritische Punkt bei einer ruhenden Order sind die Gates - sie waren bisher
Laufzeit-Checks im Market-Pfad. Neu: engine._squeeze_guard() als EINE Quelle
fuer beide Wege, jeden Tick neu bewertet; schlaegt ein Gate zu, werden die
Orders storniert. Market bleibt Fallback mit Nachjagd-Bremse
squeeze_max_chase_atr=0.20 (gemessen der noch positive Bereich).

Behandelt: Broker-Mindestabstand, falsche Marktseite, Toleranz 0,02 xATR gegen
Order-Churn, Log nur bei Fehleraenderung, Startup-Schonfrist. 10 Szenarien
getestet, live am Snapshot verifiziert.

2) META-LABELING (backtest_metalabel.py) - VERWORFEN. Zweitmodell auf 12
kausalen Merkmalen, Fit/Test in BEIDEN Richtungen: AUC 0,508 und 0,479 =
Muenzwurf, Kalibrierung im Top-Bucket 74 % vorhergesagt gegen 39 % real, und
8 von 12 Gewichten kippen das Vorzeichen. Die scheinbar besseren Schwellen
sind reine Handelsvermeidung und reproduzieren gegenlaeufig nicht.
23. verworfener Signal-Eingriff - deckt sich mit dem Caveat der Quelle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 09:03:14 +02:00
Axel HocksandClaude Opus 5 3b00820c15 Loesung fuer Fall 7 gemessen: ruhende Stop-Order am Level statt Market
Anstoss aus der Web-Recherche ("don't chase breakouts with market orders;
place orders just beyond the breakout level"). Variante E in
backtest_squeeze_entry.py: PENDING BUY_STOP/SELL_STOP, die schon liegt
waehrend der Squeeze armed ist, und vom Ausbruch selbst ausgeloest wird -
anders als die Limit-Order wartet sie NICHT auf einen Ruecklauf.

Ergebnis (80k M5, 2 Halbjahre, sequentiell, kanonischer Exit, Echtkosten):
  Level +0,05 xATR  -> OeR +0,397 / +0,553  PF 2,28 / 3,06
  Level +0,10 xATR  -> OeR +0,355 / +0,509
  Level +0,20 xATR  -> OeR +0,244 / +0,426  PF 1,62 / 2,25
gegen Market/Live -0,158 / -0,006. Selbst mit dem ~9-fachen Median-Spread
als unterstellter Fill-Slippage bleibt es beidhaelftig klar positiv.

Kernpunkt: nicht der Median-Abstand toetet den Edge, sondern der SCHWANZ
(live Median +0,306 xATR, Mittel +0,741, Max +4,339). Eine Stop-Order
deckelt den Einstiegspreis konstruktiv, die Market-Order auf dem 5-s-Poll
nicht. Die Extremfaelle stammen aus blockiert-dann-freigegebenen Ausbruechen.

NICHT gebaut - die Guards (Nacht/News/Cooldown/flat) wirken heute als
Laufzeit-Checks und muessten mit einer ruhenden Order ueber Platzieren/
Stornieren durchgesetzt werden; dazu MT5-Mindestabstand und Storno beim
Klaeren des Squeeze.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:49:49 +02:00
Axel HocksandClaude Opus 5 8d93de9867 Deployment-Drift Fall 7: Squeeze wird zu einem Preis gehandelt, den die
Validierung nie unterstellt hat

backtest_breakout_squeeze.py steigt AM LEVEL ein. Live schickt
_check_auto_squeeze eine MARKET-Order - aus 34 echten Entries (Logs
16.07.-05.08., Level aus der Log-Zeile x Einstiegspreis aus der DB) liegt der
Einstieg im Median +0,306 xATR ueber dem Level, nur 18 % innerhalb 0,10.

Gemessen (backtest_squeeze_entry.py, 80k M5, 2 Halbjahre, sequentiell EIN
Slot, kanonischer Exit, Echtkosten): allein der Einstiegspreis dreht das
Setup - OeR +0,456 -> -0,158 (H1) und +0,611 -> -0,006 (H2), WR 56 -> 37 %.

Ordnet den B4-Befund vom 01.08. neu ein: dort wurde die Luecke zwischen
Mechanik (+0,102) und Live (-0,242) dem EXIT zugeschrieben. Die Mechanik-Zahl
unterstellt aber denselben Level-Einstieg - es war ueberwiegend der ENTRY.

Beide naheliegenden Reparaturen fallen durch (Regel vorab fixiert):
Abstands-Bremse 0,10-0,40 xATR alle 5 durch (die NAHEN Ausbrueche sind pro
Trade die schlechteren - Fehlausbruch-Effekt), LIMIT/Retest am Level in allen
5 Varianten schlechter als Market.

Nichts abgeschaltet - der Befund staerkt die bereits fixierte
B5-Abbruchregel, die Entscheidung bleibt beim User.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:43:34 +02:00
Axel HocksandClaude Opus 5 cc4f1a0863 Provider-Failover bei hartem Fehlschlag + Einsatz-Prozentfeld im Dashboard
1) LLM-Failover (core/agent.py): ein hart gescheiterter Provider wird zeitweise
uebersprungen, analyze() nimmt den naechsten aus der Kette. Hart = 401/402/403/
404 (Key/Guthaben/Modell) -> 30 min, nicht erreichbar -> 5 min. Timeout/429/5xx
loesen BEWUSST keinen Wechsel aus (voruebergehend; sonst kostet jede Lastspitze
die volle Timeout-Summe aller Anbieter). Neu im Snapshot: agent.provider_dead
mit Restminuten - der DeepSeek-Ausfall stand vorher nur im Log und blieb
deshalb 18 h unbemerkt. 9 Szenarien getestet.

2) Einsatz-Prozentfeld (web, v=137): margin_buffer_pct hatte bisher keine UI.
Neues Feld "Einsatz %" neben "Einsatz EUR", POST /api/marginpct ->
engine.set_margin_pct -> config.set_margin_buffer, Snapshot margin_pct,
neustart-fest. Der feste EUR-Betrag hat Vorrang; das Prozentfeld wird dann
ausgegraut, damit nicht unklar bleibt was gilt. Auf 1-99 % geklemmt.
Ende-zu-Ende getestet (50, 150->99, 0 und -5 abgelehnt, 95, persistiert).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:38:17 +02:00
Axel HocksandClaude Opus 5 7e9b0196a5 Copilot-Provider auf z.ai umgestellt (DeepSeek-Guthaben leer)
DeepSeek liefert seit 04.08. 14:52 durchgehend HTTP 402 "Insufficient
Balance" - 29 Fehlversuche. Alle konfigurierten Provider real getestet:
zai/glm-4.5-flash OK in 2,3 s (kostenlos), kimi-k2.6 OK in 7,6 s
(kostenpflichtig), deepseek 402, ollama nicht konfiguriert.

Gewechselt auf zai: kostenlos, schneller als DeepSeek, im Projekt schon
fuer daily_levels im Einsatz, und der _has_cjk-Retry deckt es ab. Live
verifiziert nach Neustart ("[zai] NEUTRAL (30%)").

Nebenbefund, dokumentiert aber NICHT behoben: die Fallback-Kette
deepseek->kimi->zai->local hat nicht gegriffen, weil _active_provider in
avail nur das Key-FORMAT prueft, nicht ob der Key noch funktioniert. Ein
Provider ohne Guthaben gilt als verfuegbar und blockiert die ganze Kette -
der Copilot lief ~18 h still ins Leere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:28:53 +02:00
Axel HocksandClaude Opus 5 1c9bb34095 Auto-Squeeze-Nachtsperre von 0-7 auf 3-6 Uhr verkuerzt (User-Vorgabe)
Gemessen (backtest_cost_gate.py, Teil 2): es gibt KEINE toten Stunden - alle
24 Stunden sind in beiden Halbjahren positiv, keine ist beidhaelftig negativ.
Std 0 ist sogar die staerkste des Tages (OeR +1,48/+1,51) und lag im alten
Gate. Jedes Fenster kostet also Ertrag; die Sperre kauft ausschliesslich
Beaufsichtigungs-Ruhe.

Gewaehlt wurde deshalb nach PREIS, nicht nach Edge: 3-6 ist das guenstigste
Fenster mit noch >=4 h Schutz (SigmaR -12,5/-62,9 gegen -42,4/-242,6 bei 0-7
= ~27 %). Freigegeben: 0, 1, 2, 7 Uhr. Die 4-h-Untergrenze ist gesetzt, nicht
gemessen.

Umsetzung: neues [trading] auto_squeeze_night_hours (Default 3,4,5,6, leer =
aus), genutzt von _check_auto_squeeze und _check_auto_signal. _SQUEEZE_NIGHT
bleibt als STATISTISCHE Nacht-Definition fuer Entry-Checkliste und B4-Monitor
- dort gilt die Kostenfalle weiter und der Altdaten-Vergleich bleibt stabil.

7 Parse-Faelle getestet (Default, fehlender Schluessel, leer, Muell,
Rueckwaerts-Kompatibilitaet). Live verifiziert am NEUEN Snapshot-Feld
squeeze_night_hours = 3,4,5,6 und am Startup-Log; genau eine Instanz auf 8000.

Offen und als Reminder hinterlegt: der Backtest modelliert keine Slippage,
und die freigegebenen Stunden liegen in der duennsten Liquiditaet. Nach 15
Squeeze-Trades aus 0/1/2/7 Uhr gegen die Erwartung pruefen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 08:25:48 +02:00
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 3124fe5b4f Doku: wiederverwendbarer Review-Prompt fuer die Gesamtpruefung
docs/review-prompt.md — projektspezifisch statt generisch. Die gefaehrlichsten
Fehler hier sind nicht Syntax, sondern "Messung != Betrieb", deshalb ist
Deployment-Drift ein eigener Durchgang.

Enthaelt die harten Grenzen (Secrets, DB-Backup, eine Instanz, keine
Strategieaenderung ohne 2-Stichproben-Backtest, dokumentierte User-
Entscheidungen nicht anfassen) und als Pruefliste genau die Fehlermuster, die
in diesem Projekt real aufgetreten sind: stille catch-Bloecke, zu weite
Plausibilitaetsfenster, aus stalen Eingaben abgeleitete Werte, zwei Quellen fuer
denselben Zustand, null-unsichere DOM-Zugriffe, Ticket-Wechsel-Races.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 23:12:34 +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 81614a3128 Richtungs-Pfeile im MT5 statt des Kegels (v1.32) + Handbuch-Muster ergaenzt
PFEILE (User: "anstatt des Trichters einen Pfeil, der die wahrscheinlichste
Kursentwicklung anzeigt"). Randbedingung: die FREIE Richtungsfrage ist
gemessen ein Muenzwurf (analyze_reversal.py, AUC 0,499-0,509 oos, in-sample
nur 0,52). Ein frei schwebender Prognose-Pfeil waere unbelegt - und
gefaehrlicher als der Kegel, weil er ueberzeugender aussieht. Deshalb DREI
Pfeile mit jeweils eigener, benannter Beleglage:
  L blau      naechstes Level, aus dem kalibrierten P(break)
              (AUC 0,65 oos, live 27 % vorhergesagt vs 28 % real)
  S neongruen Squeeze-Ausbruch - das EINZIGE validierte Richtungssignal
  K grau      Konsens der Module - NICHT kalibriert, heisst deshalb
              "Konsens" und nicht "Prognose"

L hat ein TOTBAND 45-55 %: dort waagerechter Pfeil "unentschieden", statt
aus einem Muenzwurf eine Richtung zu zeichnen.

MQL5 v1.32: OBJ_ARROWED_LINE + Label an der Spitze. Label heisst ALBL_* und
NICHT T* - sonst zieht RepositionLabels() es an den rechten Rand und loest
es von der Pfeilspitze.

Kegel bleibt im Code und in der Dashboard-Kachel; der Bot exportiert ihn nur
nicht mehr ins Chart ([trading] export_cone=false).

CHARTMUSTER: alle Handbuch-Muster ergaenzt - Dreifach-Top/-Boden, Flagge,
Wimpel, Rechteck, Steigender/Fallender Keil. ALLE mit measured=False, sie
tragen die Verdict-Stimme NICHT: das Gewicht 1,0 stammt aus einem
Kontrolltest, der nur die alten Typen abdeckte. engine._verdict waehlt jetzt
nur Muster mit measured=True.

Bug beim Bau gefunden: der fallende Keil feuerte in 20.000 Bars KEIN
EINZIGES MAL - die Bedingung stand auf dh > dl, bei einem fallenden Keil
faellt aber die OBERE Linie schneller (sonst konvergiert nichts). Beim
Spiegelbild (steigender Keil) stimmte es.

backtest_patterns_v2.py (NEU) misst die neuen Typen - mit dem ECHTEN
Detektor (core.patterns._detect statt einer Nachbildung) und dem
kanonischen Exit, plus Kontrollgruppe "generischer Swing-Bruch".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 19:26:11 +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