Commit Graph
79 Commits
Author SHA1 Message Date
Axel HocksandClaude Opus 5 e48ad80c0a UI aufgeraeumt + Telegram auf Closes reduziert (v=177)
Vier User-Vorgaben:
1. Einsatz-Felder entfernt. Backend bleibt vollstaendig -- Folge: der
   Prozentsatz ist ohne UI nur ueber ini + Neustart aenderbar.
2. BRK-Schalter entfernt, dafuer STOPP (Circuit-Breaker). Bewusster Tausch mit
   Konsequenz: der An/Aus-Schalter des AUTONOMEN Pfads ist aus der App weg (nur
   noch POST bzw. ini), sein Zustand bleibt in der Breakout-Karte sichtbar.
   Dafuer ist die Notbremse bedienbar, die am 17.08. real ausgeloest hat.
   set_circuit_breaker + POST /api/circuit + runtime_state (cb_limit_pct,
   cb_remember -- ohne das Gedaechtnis waere die Prozentzahl nach einmal
   Ausschalten fuer immer weg).
3. Telegram nur noch bei geschlossenen Trades: EINE Filterstelle vor
   _send_telegram_roh statt 17 Einzeleingriffe, _TG_ERLAUBT = ('Trade
   geschlossen',). Umkehren = Liste erweitern. Tages-/Wochenreport wird nur auf
   dem Telegram-Weg still, die E-Mail laeuft weiter.
   EINE Ausnahme mit Bypass: '<ok_word> FEHLGESCHLAGEN' beim Notfall-Close --
   dort ist die Position NICHT zu und es braucht eine Handeingabe.

Verifiziert: /api/circuit vorher 405, nachher 200; Toggle aus->an->8 %/57,94 EUR
persistiert; 85 Tests, node --check, check_nfalle gruen; 0 verwaiste
JS-Referenzen; genau eine Instanz je Port.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:03:30 +02:00
Axel HocksandClaude Opus 5 30cb77b795 Breakout-Karte vorbereitet (inaktiv bis Neustart) + Bewertung der Margin-Idee
User-Idee: 40 % Margin manuell, 50 % fuer Breakout reservieren, neue Karte.

Bewertung: (1) 40 % ist der groesste gemessene Hebel (MaxDD 82,8 %) und ein
Schalter ohne Neustart. (2) Reserve ist technisch moeglich (Konto ist
RETAIL_HEDGING), aber _check_auto_squeeze feuert 'nur FLAT' und engine.py hat 17
Einzel-Positions-Annahmen -- Kern-Umbau, kein Parameter. Zudem steht die
Zuteilung gegen die Messung: autonom -4,71 EUR/Lot gegen Mensch +1,56 EUR/Lot.
Live-Befund macht (1) dringlich: freie Margin -6,21 EUR, Margin-Level 99,3 %.
Es gibt derzeit nichts zu reservieren.

Gebaut (inaktiv): history.fetch_squeeze_since, engine._squeeze_b5_cached
(120 s gecacht), Snapshot-Feld squeeze_b5, Karte #card-brk. Eigenes Fenster ab
01.08. -- squeeze_monitor.live rechnet ueber alle 42 Trades, B5 zaehlt 11. Die
Karte zeigt beide Zahlen, weil der Monitor 'ontrack' aus der MECHANIK meldet,
waehrend live Verhaeltnis 0,14 / PF 0,39 steht.

Live aendert sich nichts: Karte ist hidden, renderBrk blendet sie aus solange
squeeze_b5 fehlt. Aktiv nach dem naechsten Neustart (wartet auf den Trade).

BEINAHE-SCHADEN: ein UnicodeEncodeError liess web/app.js mit 0 Bytes zurueck.
node --check bestand trotzdem -- eine leere Datei ist gueltiges JS. Gefangen hat
es erst der Groessenvergleich. Neue Regel: erst .tmp schreiben, Groesse pruefen,
dann os.replace.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:32:48 +02:00
Axel HocksandClaude Opus 5 ca61cf1498 S/R als ZONE statt Linie (RZ/SZ, Indikator v1.37)
User-Wunsch nach einem TradingView-Bild: Resistance Zone und eine untere Zone
als farbige Baender. Neu RZ;lo;hi und SZ;lo;hi, im Indikator als OBJ_RECTANGLE
mit Beschriftung, nach rechts verlaengert.

DIE BREITE IST ECHT: sie ist die Spanne der M30-Pivots, die den Cluster gebildet
haben (sr_levels.zonen(), additiv -- cluster() bleibt unveraendert, weil es den
S/R-Auto-Close speist). Live verifiziert: R;82.786 liegt in RZ;82.776;82.797,
S;82.15 in SZ;82.14;82.16. Einzel-Pivot bekommt 0,10xATR Mindestbreite.

ZWEI ABWEICHUNGEN VOM VORBILD, beide begruendet:
(1) KEIN Fibonacci. Das Bild leitet seine Zone aus 0,618/0,658 ab. Fib ist hier
    gemessen und verworfen (04.08.): 54,3/54,5 % Haltequote gegen 55,7/53,8 %
    einer Zufallslinie gleicher Distanz, und schlechter als M30-Pivots.
(2) Die untere Zone heisst SUPPORT, nicht "Cumulative Long Liquidation". Echte
    Liquidationsdaten hat das Projekt nicht; die HL-Waende sind am 17.08. als
    reaktiv gemessen. Bricht die Support-Zone, liegen dort die Long-Stops --
    dieselbe Stelle, ehrlich benannt.

Abschaltbar InpShowZonen. Kompiliert ins richtige Terminal (0/0), deployt,
verifiziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:27:26 +02:00
Axel HocksandClaude Opus 5 204e80bb68 Meldungen oben links im MT5-Chart (MS;<text>, Indikator v1.36)
User-Wunsch. Neue CSV-Zeile MS;<text>, im Indikator als gestapelte OBJ_LABEL an
CORNER_LEFT_UPPER (oben rechts sind Kurs, G/V und HL belegt). Inhalt = dieselben
Zeilen wie die Dashboard-Karte "Meldungen": Squeeze, Ueberdehnung, S/R-Ziel mit
P(break), Stop-Seite, News-Blackout.

NUR ZUSAMMENGESETZT, NICHT NEU GERECHNET -- alles aus bereits berechneten
Snapshot-Teilen bzw. _last_sr_close_hint/_last_stop_approach; calendar.blackout()
ist ein reiner Speicher-Zugriff. Der Konsens-Pfeil hat im 5-s-Export-Takt einmal
ein komplettes zweites _verdict() gezogen.

Zwei Felder vorher geprueft statt angenommen: _last_calendar und
_export_meldungen gab es NICHT -- ohne die Pruefung haette das umgebende
except Exception es still verschluckt und die Meldungen waeren dauerhaft leer
geblieben (dieselbe Klasse wie der wave_snap-Fallstrick vom 04.08.).

ASCII-SICHER, real noetig: der erste Lauf lieferte "MS; Kompression  Ausbruch
steht bevor" -- Emoji und Gedankenstrich waren zu Leerzeichen geworden. Der
Indikator liest die CSV nicht als UTF-8 (deshalb steht dort auch
"Unterstuetzung"). Jetzt Ersetzung + Filter auf 32-126.
Verifiziert: MS;Squeeze-Ausbruch LONG @ 82.413, 0 Nicht-ASCII-Zeichen.

Deckel 5 Zeilen a 70 Zeichen; eigener Praefix SRB_MSG_*, damit die Labels beim
Redraw verschwinden. Abschaltbar per [trading] export_meldungen=false oder
InpShowMeldungen. Kompiliert ins richtige Terminal (0 errors, 0 warnings),
deployt und am laufenden Server verifiziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 11:00:34 +02:00
Axel HocksandClaude Opus 5 44191947ac Telegram bei gruener M15-Karte (m15_alert) + Tests verschmutzen nicht mehr das Log
User: "wenn es eine Empfehlung gibt (gruen), schicke eine Telegram-Nachricht."
engine._check_m15_alert, direkt hinter _log_m15_state -- dieselbe Quelle wie
Anzeige und Selbstmessung, damit die drei nicht auseinanderlaufen koennen.

DIE ENTPRELLUNG IST DER GANZE BAU. Roh springt die Karte 85x/Tag auf gruen
(m15_states, 3 Tage nach der Hysterese vom 12.08.) -- das waere Spam. Alle
Stufen an den echten Daten kalibriert, nicht geraten:

  nur Flanke                          85,0/Tag
  + Level & Richtung als Schluessel   23,7/Tag
  + 30 min Mindestabstand             13,3/Tag
  + Fenster 8-20 Uhr (Default)         7,7/Tag
  (Vergleich: Close-Meldung ab 50 EUR  2,4-6,1/Tag)

Nach 4 h darf dasselbe Level erneut melden, sonst verschweigt der Alert ein
Setup, das den ganzen Tag wiederkommt.

Der Text sagt ausdruecklich, dass es KEINE Prognose ist: die Karte automatisch
zu handeln faellt gemessen durch (backtest_m15_auto.py: OeR -0,162/-0,094). Die
Meldung ist ein Hinweis zum Hinsehen fuer den Menschen (+3,20 EUR/Lot ueber 146
Trades). Die P(break)-Formulierung ist wortgleich zu Karte und Chart (v1.35).

13 Tests, Schwerpunkt auf dem was NICHT gesendet werden darf. Mutationsprobe in
vier Zweige, alle gefangen.
DIE PROBE HAT EIN TESTLOCH AUFGEDECKT: das Entfernen der Flankenerkennung liess
zunaechst ALLE Tests gruen, weil Cooldown und 4-h-Schluessel dasselbe abfangen.
Zwei Schutzschichten, die sich maskieren -- dasselbe Muster wie beim Fill-Dedup.
Geschlossen durch test_flankenerkennung_ISOLIERT.

NEBENBEFUND, behoben: Tests schrieben ins Produktions-Log (ueber 150
M15-Alert-Zeilen + Close-Push #4711 aus test_close_buchung). Ich hielt die
Entprellung deshalb zuerst fuer live defekt. conftest.py entfernt den
FileHandler des oil-Loggers jetzt fuer die Sitzung -- vierte Grundregel der
Suite. Verifiziert: Log-Groesse vor und nach einem Komplettlauf identisch.

Live verifiziert: seit dem Serverstart genau 1 Alert trotz mehrfachem
gruen/gelb-Wechsel. 85 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 08:37:53 +02:00
Axel HocksandClaude Opus 5 19ee379f20 rec_outcomes: zweiter Bug gefunden und behoben (timeframe_name)
Der Log verriet die wahre Ursache: 'WaveRecommender' object has no
attribute 'timeframe_name'. rec["tf"] ist leer, also lief der Aufruf
immer in diesen Fallback - AttributeError, im except auf DEBUG
verschluckt.

Der pb_feats-Fix vom 11.08. war damit RICHTIG: er kam an der ersten
Sperre vorbei und legte diese zweite frei. Vorher wurde log_rec_outcome
nie aufgerufen (atr immer 0), deshalb konnte der zweite Bug gar nicht
auftreten.

Richtig ist self._wave_tf_label (die Engine haelt das Label).

Lehre: nach einem Fix nicht nur pruefen, ob die Tabelle jetzt schreibt,
sondern das LOG lesen. Die Zeilen standen seit Stunden da - ich hatte
nur auf INFO gefiltert und daraus geschlossen, es gaebe keine.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 20:17:12 +02:00
Axel HocksandClaude Opus 5 bf7e382818 Auto-Signal-Entry (SIG) komplett entfernt inkl. Button (v=166)
User-Entscheidung. Der Pfad war seit 01.08. aus und auf BEIDEN
Ausfuehrungs-Achsen gemessen negativ: Markt-Einstieg in allen 8
Feldern, ruhende Order mit Touch-Fill -0,392/-0,338 in allen 6 und
damit sogar schlechter als Markt. Die +0,35/+0,32 aus
backtest_auto_signal_v3.py galten in Variante B (Fill beim
Close-Bruch) und waren Look-ahead - Aufschlag 0,77-0,85 R. Ursache
strukturell: das Bestaetigungs-Level _pend WANDERT.

Nebenbei entfaellt der offene Churn-Defekt (4x setzen/stornieren in
76 s bei identischem Level, gefunden 06.08., nie behoben).

Entfernt: _check_auto_signal, set_auto_signal, der Signal-Zweig in
_pending_ziel, /api/autosignal, Button + Handler, vier Snapshot-Felder,
die auto_signal*/signal_pending_entry-Leser.
Geblieben: AUTOSIG_*-Trades in der DB, die Backtests, wave_rec.breakout
(speist block_reason) und _confirm_breakout selbst.
Sicherung: .removed_backup/auto_signal_2026-08-12.py + Git.

Das Risiko war nicht SIG, sondern der GETEILTE Pending-Manager (zwei
getrennte Manager wuerden sich gegenseitig stornieren). Deshalb wurde
das Squeeze-Verhalten VOR dem Eingriff in tests/test_pending_ziel.py
festgenagelt - 7 Tests, vorher gruen, laufen unveraendert weiter.

Zwei Folgefehler fing die Pruefkette sofort: ruff F821 ein verwaistes
_t, py_compile ein dangling if. Zwei Tests wurden mitgezogen statt
geloescht - test_signal_fill_long ist jetzt umgedreht (unbekannte
Quelle darf NICHT als Squeeze durchgehen).

Live verifiziert: alle vier Snapshot-Felder weg, Endpunkt tot,
auto_squeeze/squeeze_pending unveraendert, 67 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 18:47:28 +02:00
Axel HocksandClaude Opus 5 5fb1d7e268 M15-Karte: Flacker-Ursache gemessen, Hysterese + EINE Quelle (v=165)
Die Karte wechselte den Zustand alle 12 Sekunden (~1.030/Tag) - der
Grund, warum ihre Selbstmessung so stark geclustert war.

Mein erster Verdacht (das Level im Wechsel-Schluessel) war falsch.
Ausgezaehlt ueber 3.525 Zeilen: status 32,9 %, lesart 32,7 %,
level allein nur 7,6 %. Das Level zu entfernen braechte 3.525 -> 3.248,
also nichts. Der Zustand selbst zappelt: gap <= 0,5 und das 45/55-Band
von P(break) sind stetige Groessen um ihre Schwelle.

Das Projekt hatte die Loesung schon (analyze_pbreak_flicker.py, 14.07.:
Hysterese +-5 Pp) - die Karte umging sie, weil sie P(break) selbst neu
rechnet. Jetzt dieselbe Hysterese auf beide Schwellen: Status gruen ab
0,50 / zurueck erst ueber 0,60; Lesart gerichtet ab 40/60 / zurueck
erst innerhalb 45/55. Simuliert: 64 % weniger Wechsel.

Zweiter, groesserer Befund: Status und Lesart wurden an DREI Stellen
unabhaengig gebildet und wichen bereits ab - der Logger kannte den
"kein Veto"-Fall des Frontends nicht, protokollierte also einen
anderen Zustand als angezeigt wurde. Jetzt eine Quelle: _m15_setup
liefert status/lesart/nah im Snapshot, Logger und Frontend lesen sie.

Die alten 3.525 Zeilen sind mit den neuen nicht vergleichbar; die
Selbstmessung beginnt faktisch neu (Stichtag 12.08.). Kein Verlust -
sie liess vorher ohnehin kein Urteil zu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:37:12 +02:00
Axel HocksandClaude Opus 5 b2a1e35f5e rec_outcomes: Fix hat nicht gewirkt - jetzt instrumentiert
Korrektur meiner Behauptung vom 11.08. Nach dem Neustart um 22:45 gab
es bis 09:00 mindestens 10 gerichtete Episoden, und rec_outcomes stand
weiter bei 0 Zeilen. Die Praemisse (falsches dict: s.get("pb_feats")
auf dem MT5Data- statt dem Wave-Snapshot) ist live belegt - die
WIRKUNG des Fixes war es nicht. Ich habe "behoben" geschrieben, ohne
sie zu pruefen.

Warum es von aussen nicht feststellbar war: der except-Zweig loggte
auf DEBUG, der Logger steht auf INFO. Genau die Blindheit, die den
Ausfall fuenf Tage getragen hat.

Jetzt melden sich BEIDE Zweige sichtbar:
- Erfolg: "rec_outcome #<id>: LONG @ <px> atr=<atr>" (INFO)
- Fehlschlag: "rec_outcome NICHT geschrieben: atr=.. px=.. pb_feats=.."
- Exception: WARNING statt DEBUG, mit repr

Es feuert nur bei einem echten Richtungswechsel, also selten - kein
Laerm. Ursache offen bis zur naechsten Episode.

Der Telemetrie-Puls ist der Grund, dass die ausbleibende Wirkung
ueberhaupt auffiel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:21:50 +02:00
Axel HocksandClaude Opus 5 b18b594639 Systemzustand in den Tagesreport - der fehlende letzte Meter
Selbstaendige Empfehlung nach der Gesamtpruefung, vom User beauftragt.

Befund: die Erkennung funktioniert, die Zustellung nicht. Sieben
Waechter, jeder nach einem eigenen Vorfall gebaut, jeder funktioniert -
und trotzdem blieben diese Woche sechs Zustaende tagelang unbemerkt,
vier davon waren bereits erkannt.

Belegt an den Marker-Dateien: cfg_auto_sr_close traegt 06.08. 18:10,
cfg_auto_squeeze sogar 02.08. Der Config-Waechter meldet je Schluessel
genau einmal und schweigt danach fuer immer. auto_sr_close war damit
fuenf Tage aus - gemessen +350,81 EUR ueber 43 Trades. Ursache ist ein
Kategorienfehler: die Marker-Logik behandelt einen Dauerzustand wie ein
Einmal-Ereignis.

Gebaut: engine._system_status() als Block im Tagesreport (07:30,
Telegram + E-Mail) - der einzige Kanal, der nachweislich jeden Tag
ankommt. Saubere Trennung: Popup = "etwas Neues", Report = "so steht
es gerade". Reine Anzeige.

- telemetrie_puls() liegt in core/history.py, beide Nutzer rufen
  dieselbe Funktion (Skripte importieren core, nie umgekehrt)
- measurement_reminder wird lazy und gekapselt importiert; ein
  Fehlschlag wird sichtbar gemeldet statt still verschluckt
- tests/test_system_status.py: 7 Tests, Schwerpunkt Ausfallpfade -
  der Report darf an dieser Zeile nie scheitern

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:43:24 +02:00
Axel HocksandClaude Opus 5 dca3c11bbd Gesamtpruefung 2026-08-11: drei Defekte behoben
Zweiter vollstaendiger Durchlauf nach docs/review-prompt.md.

BEFUND 1: rec_outcomes war seit dem Einbau (06.08.) still tot - 0
Zeilen in 5 Tagen. _run_analysis las s.get("pb_feats"), aber s ist der
MT5Data-Snapshot; pb_feats lebt im Wave-Snapshot. _atr also immer 0,0
und die Schreibbedingung nie erfuellt. Kein NameError (ruff sieht
nichts), und das umgebende except loggt auf DEBUG. Aufgefallen nur,
weil die Tabelle mit 0 Zeilen neben ihren Schwestern stand.
Generalisiert als measurement_reminder.telemetrie_puls(): jede
Telemetrie-Tabelle muss einen Puls haben. Erster Lauf meldet genau
diesen Fund, alle uebrigen gruen.

BEFUND 2: der Divergenz-Waechter war selbst driftend. Abschnitt A
verglich gegen 43 % WARTEN - seit 05.08. ausdruecklich ungueltig (das
misst _build allein); richtig sind 80,5 %. Und entry_room galt als
"live-only", obwohl es seit 04./05.08. modelliert wird.
A: +50,8 Pp Warnung -> +13,3 Pp OK. B: 63,9 % -> 5,0 %.

BEFUND 3: P(break) ist wieder kalibriert (Delta -1,7 Pp nach +14,3 Pp
am 07.08.) - stuetzt den Schluss, dass die gewanderte Basisrate ein
Zeitraum-Effekt war.

Sauber: alle Standardpruefungen, 0 fehlende Frontend-IDs, mt5_lock,
Broker-Zeit, Race-Klasse. Performance: Snapshot-Median 15,9 ms, alle
heissen Abfragen ueber Index - keine Optimierung noetig.

Kein toter Code geloescht: die vermeintlich verwaisten Snapshot-Felder
sind Diagnose-Oberflaeche (vier davon heute zur Deploy-Verifikation
benutzt).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:31:42 +02:00
Axel HocksandClaude Opus 5 4eb92bf192 Telegram: Close-Benachrichtigung ab Schwelle + Auto-Squeeze wieder an
Diagnose zu "ich bekomme keine Telegram-Nachrichten mehr": der Kanal
war intakt (getMe/getChat ok, Testnachricht zugestellt, keine einzige
Fehlermeldung im Log, Tagesreport kam taeglich). Ursache war, dass
ALLE NEUN sendenden Ausloeser aus waren - Auto-Squeeze (ueber
runtime_state.json, unbemerkt), Auto-Signal, S/R-Close, Flip-Close,
15-Minuten-Regel, Circuit-Breaker und die drei Notfall-Stop-Modi.
Jede Abschaltung war fuer sich begruendet; zusammen ergaben sie eine
Stille, die niemand beschlossen hatte.

Gebaut: engine._check_close_notify - Telegram bei JEDEM geschlossenen
Trade ab close_notify_min_eur (50, 0 = aus). Haengt an keiner
Automatik, feuert also auch bei manuellem Close und Broker-SL. Der
-87-EUR-SL vom 10.08. kam bisher wortlos.

Schwelle aus den Daten: bei ~17 Trades/Tag rund 2,4-6,1 Meldungen/Tag,
erfasst 54-80 % des bewegten Geldes. Absolute Euro-Schwelle altert mit
der Positionsgroesse - bewusst so, ein Mensch denkt in Euro.

Der Unterschied zum frueher entfernten Push ist die Schwelle, und sie
liegt in der Engine statt in der DB-Schicht. Vorgemerkt statt sofort
gesendet, weil der Flat-Zustand dem DB-Schreiber einen Tick voraus
sein kann (exit_time IS NULL heisst "noch nicht fertig").

- tests/test_close_notify.py: 7 Tests, Netz abgefangen
- Mutationsprobe in beide kritischen Zweige, beide gefangen
- Snapshot-Feld close_notify_min (belegt die Schwelle im Prozess)
- Auto-Squeeze wieder AN ueber /api/autosqueeze (ini + runtime_state)
- v=161

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:22:41 +02:00
Axel HocksandClaude Opus 5 47c596ed70 M15-Karte: Gate 3b zeigt Motor-Block + RAUM je Richtung
Anlass Trade #49671601 (-87,03 EUR). Die Praemisse "SL trotz LONG-
Empfehlung" stimmte nicht: 138 Zeilen zwischen Ein- und Ausstieg,
100 % WARTEN (entry_room 76 %, breakout_pending 19 %, min_conf 5 %).
Gesehen wurde "verboten: SHORT" - ein Veto. Dritter Fall derselben
Veto->Richtung-Umwandlung in dieser Karte (Code 08.08., Geometrie
10.08. frueh, jetzt die Lesart).

Der eigentliche Befund: entry_room und Gate 3 lesen DIESELBE Tatsache
("ein Level ist nah") mit umgekehrtem Vorzeichen. Beide gemessen,
beide richtig - ueber verschiedene Trades (Markt-Einstieg mit dem
Level als Hindernis vs. ruhende Order AM Level). Die Karte zeigte nur
die gruene Haelfte; die Block-Grund-Zeile war mit der Gesamtempfehlung
verschwunden.

Gebaut: Zeile 3b (#m15-motor) mit block_reason im Klartext + Raum je
Richtung. Reine Anzeige. Das Status-Banner bleibt bewusst unveraendert
- es auf gelb zu ziehen waere eine Strategie-Aenderung, und die einzige
Live-Zahl dafuer (-9,91 vs +3,24 EUR/Lot, n=76) hat ein KI, das die
Null enthaelt.

- wave_rec.room_info(): EINE Implementierung fuer Gate und Anzeige,
  _room_gate rechnet jetzt darueber (kein Nachbau)
- tests/test_room_info.py: Bitgleichheit ueber 2.000 Zufallslagen x 3
  Signale, Gate feuerte >300x; Grenzfall-Test fuer die Rundung
- v=160

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 09:09:27 +02:00
Axel HocksandClaude Opus 5 5474c2be61 Gate 4 der M15-Karte: Ziel nur noch in der ERLAUBTEN Richtung
User-Fund: Karte zeigte "verboten SHORT" (= LONG erlaubt) UND ein Ziel
0,15 $ UNTER dem Kurs. Die Arithmetik war korrekt - aber fuer die
verbotene Richtung.

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

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

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

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 06:36:02 +02:00
Axel HocksandClaude Opus 5 b8705e297f Kegel mit Adaptive Conformal Inference nachkalibriert (v=158)
Der Kegel war seit dem 31.07. dokumentiert 3-5 Pp ZU ENG - 80 % nominal gegen
real 76,7 / 76,6 / 75,3 % - und blieb es, weil Nachfitten das Problem nur
verschiebt. ACI justiert stattdessen ONLINE nach jedem aufgeloesten Fenster und
konvergiert nachweislich gegen die Zielabdeckung, auch unter Drift.

EHRLICH ZUR BAUART: die Lehrbuch-Form justiert alpha und schlaegt das Quantil
nach. Hier liegt nur eine feste Quantil-Tabelle vor, kein Verteilungsobjekt -
umgesetzt ist die multiplikative Variante:
    s <- s * exp(gamma * (1{verfehlt} - alpha_ziel)),  gamma 0,02, Deckel 0,7-2,0
Dieselbe Regelungsidee, aber die Konvergenz-GARANTIE der Originalform ist damit
nicht woertlich uebertragen.

Verifiziert: bei exakt 20 % Verfehlern bleibt die Skala bei 1,0000 - der
Fixpunkt stimmt. Simulation aus der dokumentierten Lage (76,6 %): nach ~50
Checks um 80 %. Die Skala pendelt um das Ziel statt exakt zu treffen - das ist
das bekannte ACI-Verhalten (garantiert ist die Langfrist-Abdeckung).

NICHT-UEBERLAPPEND geloggt (neue Tabelle cone_checks): ein 120-min-Fenster alle
5 min waere 24-fach ueberlappend - genau die Cluster-Verzerrung, an der
analyze_hl_funding.py aufgelaufen ist und die die Faelligkeitsbedingung
pbreak_accuracy_v2 um das Zehnfache danebenliegen liess. Je Horizont startet ein
neuer Check erst, wenn der vorige ablief -> 48/24/12 Checks je Tag.

Neustart-fest ueber runtime_state.json. build() ohne skalen liefert bitgenau die
alten Werte (additiv geprueft).

ZWEI EIGENE PLATZIERUNGSFEHLER, beide gefangen: der Lade-Block landete zuerst
HINTER den except-Klauseln von _load_runtime_state, wo st nicht mehr existiert;
und beim M15-Setup landete ein Block mitten in einem mehrzeiligen Aufruf. Der
erste waere stillschweigend nie gelaufen - gefunden nur, weil ich die Funktion
danach gelesen habe statt dem gruenen py_compile zu trauen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:45:26 +02:00
Axel HocksandClaude Opus 5 86c432f791 M15-Karte misst sich selbst + Ausfuehrungsqualitaet sichtbar (v=157)
Nach Web-Recherche umgesetzt, Punkte 2 und 3 der Wahl.

SELBSTMESSUNG (neue Tabelle m15_states): die Karte hatte KEINE Rueckkopplung -
geprueft, es gab kein Logging. Das war die auffaelligste Luecke: jeder Ausfall,
der in diesem Projekt je aufgedeckt wurde, kam aus einer Rueckkopplung
(pbreak_predictions entlarvte den Modellausfall LIVE, was kein Backtest konnte;
der B4-Monitor die Squeeze-Drift). Die Karte haette monatelang falsch stehen
koennen.
Neu: eine Zeile je ZUSTANDSWECHSEL, nach 30/60 min gegen candles_m1
ausgewertet, Ergebnis als Zeile 6 in der Karte. Gewertet wird die LESART, nicht
der Status, und nur die gerichtete (45-55 % zaehlt nicht mit). Gegen 50 % lesen.
Nur bei Wechsel, nie je Tick - sonst dieselbe Cluster-Verzerrung, die am 07.08.
elf widerlegte Hypothesen ausgeloest hat. Live verifiziert: 1 Zeile trotz
laufendem Sekundentakt.

AUSFUEHRUNGSQUALITAET (Zeile 7): analyze_squeeze_entry_gap.py existiert seit dem
05.08. und misst die TCA-Kennzahl (Arrival-Price-Slippage) - niemand hat je
hineingesehen. Dabei war das der einzige Erfolgsmassstab des Stop-Order-Umbaus
und zugleich der groesste je gemessene Hebel (+0,32 R). Jetzt steht der
Zaehlstand in der Karte: 3 von 12 Bot-Trades seit dem Umbau.

NICHT gebaut: der Kegel mit Adaptive Conformal Inference. Er ist mit
76,7/76,6/75,3 % gegen 80 % Nennwert dokumentiert zu eng, und ACI waere die
Standardmethode (adjustiert online, garantiert Konvergenz auch unter Drift).
Bleibt offen.

BEIM BAU EIN NAMEERROR IM 1-SEKUNDEN-PFAD, VOM LINTER GEFANGEN: der erste
Entwurf berechnete _m15 in _run_analysis und benutzte es in snapshot(); dort
gibt es weder market noch wave_snap. py_compile sieht das NICHT, ruff F821
meldete 4 Befunde. Genau die Fehlerklasse, fuer die der Linter am 07.08.
eingebaut wurde - und der erste echte Fang. Zweiter Fehler beim Verschieben:
der Block landete mitten in einem mehrzeiligen Aufruf. Beide behoben.

DB-Backup: oil_widget_history.db.bak-2026-08-08-m15states

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:38:56 +02:00
Axel HocksandClaude Opus 5 30830d76b1 M15-Karte: Bias war ein Richtungsgeber - korrigiert zum Veto (v=155)
Tagestest an 07.08. (test_m15_karte_tag.py) deckt einen strukturellen Fehler in
meiner eigenen Karte auf.

Rohzahlen: 92 M15-Bars, davon 46 (50 %) auf GRUEN. Entkoppelt auf
zusammenhaengende Bloecke bleiben 13 Setup-Episoden - und ALLE 13 waren LONG,
an einem Tag, der von 78,399 auf 77,383 FIEL (-1,016 $). Trefferquote 0 %,
OeR -0,753, SumR -9,79.

Ursache ist nicht Pech, sondern ein Denkfehler: gemessen ist "gegen den
M30-Trend zu handeln halbiert den Edge" - eine VERBOTS-Aussage. Ich hatte
daraus "M30+H1 einig -> Bias LONG" gemacht, also einen Richtungsgeber. Exakt
der Fehler, wegen dem die Gesamtempfehlung entfernt wurde (Richtung dort 48-51 %
Treffer). Die nachlaufende EMA zeigt im Trendtag stur in die alte Richtung -
dokumentiert seit analyze_signal_live.py.

Korrigiert: das Feld liefert nur noch, welche Richtung VERBOTEN ist
(bias.verboten); bias.richtung ist dauerhaft None. Das Banner nennt keine
Richtung mehr:
  "BEDINGUNGEN OK @ 77,098 - Order ANS LEVEL, nicht zum Markt - SHORT vermeiden"

Zwei weitere Befunde aus demselben Test, offen dokumentiert:
- Das Kosten-Gate blockte 0 von 92 Bars. Auf M15 liegt Spread/ATR bei ~0,10,
  die Schwelle bei 0,32 - das Gate ist dort faktisch dekorativ.
- Die strengere Bias-Variante (M30 UND H1) unterscheidet sich kaum von der
  laxen (46 gegen 47 gruene Bars) - die Zusatzstrenge kostet nichts, bringt
  aber auch nichts.

Auch ein Fehler in meinem TEST, dokumentiert: der erste Lauf zaehlte 46
fortlaufende Bars als 46 Trades und meldete 7 % Trefferquote - eine Bewegung
46-mal gezaehlt. Erst die Entkopplung auf Episoden macht die Zahl lesbar.

WARNUNG zur Beweiskraft: EIN Tag ist kein Edge-Nachweis. Belastbar ist hier
nicht die Trefferquote, sondern der MECHANISMUS - und der ist aus zwei
Halbjahren dokumentiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:14:47 +02:00
Axel HocksandClaude Opus 5 e5adfc9757 Slippage vs Vola-Regime gemessen + Ziel-Erreichbarkeit gebaut (v=154)
MESSUNG (analyze_slippage_vola.py, 337 SL-Closes): die Exit-Slippage steigt
MONOTON ueber alle vier Delta-ATR-Quartile:
  0,39-0,91   Schaetzer 0,0200 $
  0,91-1,08             0,0390 $
  1,08-1,26             0,0645 $
  1,26-2,39             0,0839 $   Faktor 4,19x
Mechanismus stimmig: die Slip-RATE bleibt flach (20-23 %), die GROESSE waechst
(0,094 -> 0,396 $). Es rutscht nicht oefter, sondern weiter.

ABER: der Bootstrap auf die DIFFERENZ oben-unten ergibt [-0,012 ... +0,183] -
enthaelt die Null. Bei n=85 je Quartil NICHT statistisch belegt.
Meine vorab fixierte Regel (Faktor >=2 UND monoton) war damit
unterspezifiziert - sie haette ein Konfidenzintervall verlangen muessen.
Konsequenz: gebaut als reiner HINWEIS im Kosten-Gate, kein Gate, und die
Beschriftung sagt "historisch ~4x hoeher", nicht "belegt".

ZIEL-ERREICHBARKEIT (Vorschlag 3, Decay-Clock): reine Geometrie auf dem
kalibrierten Kegel - passt das Gegenlevel noch in das 80-%-Band des jeweiligen
Horizonts? Live: Ziel 77,784 (0,401 $) liegt im 120'-Kegel, nicht im 30'/60'.
Die im Vorschlag mitgedachte Annahme "je laenger, desto eher bricht es" ist
BEWUSST NICHT eingebaut - sie ist nicht belegt (Touch-Zahl: umgekehrtes U auf
4 Live-Tagen, im Backtest +0,010 AUC, nach dem Nachtrainieren gar nichts mehr).

Umsetzung ohne zweiten MT5-Fetch: _vola_regime puffert den ATR_M15 aus dem
ohnehin laufenden Turn-Fetch (deque, ~5 h). Kaltstart liefert datr=null statt
zu raten - live verifiziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 22:59:37 +02:00
Axel HocksandClaude Opus 5 44955bf70a M15-Karte "Setup-Bereitschaft" gebaut - Ersatz der Gesamtempfehlung (v=153)
Nach drei negativen M15-Messungen (Squeeze-Einstieg, VWAP-Baender, Exit-ATR)
steht fest: auf M15 traegt keine Richtungsquelle. Gebaut ist deshalb bewusst
KEINE Empfehlung, sondern eine sequenzielle Gate-Kette:

  [1 HTF-BIAS M30/H1] -> [2 KOSTEN Spread/ATR_M15] -> [3 LEVEL & KEGEL]
  -> Order AM LEVEL

Der Unterschied zur alten Karte ist grundsaetzlich: dort wurden Stimmen zu einem
Bias VERRECHNET (gemessen 48-51 % Treffer), hier muss jedes Gate EINZELN
passieren. Ein gefallenes Gate laesst sich nicht durch ein anderes ausgleichen.

Nur belegte Bausteine: HTF-Trend (einziger robuster Filter, Edge x2), Kosten
(M15 gemessen 0,104 gegen M5 0,193), naechstes stehendes Level + P(break),
Kegel (out-of-sample kalibriert, 80-%-Band trifft 77 %), Veto (-6,60 EUR/Lot).

Status-Banner: SETUP BEREIT / WARTEN AUF LEVEL / KEIN TRADE. Es bestaetigt
ausdruecklich auch das NICHT-Handeln - die gemessene Kern-Leckage sind
diskretionaere Abweichungen.

Die Order-Buttons werden BEWUSST NICHT gesperrt (gegen den Vorschlag
"ausgrauen"): hartes Blockieren wurde im Projekt verworfen, und
User-Uebersteuerungen liefen gemessen 68 % WR.

Umsetzung: engine._m15_setup() setzt nur zusammen, was der Snapshot ohnehin
erzeugt. Neu gerechnet wird allein das M15-Kosten-Verhaeltnis und P(break) fuer
das naechste Level. Dafuer veroeffentlicht wave_rec jetzt tf_atr (ADDITIV) - der
ATR je Zeitebene wurde im Turn-Fetch laengst berechnet, war aber nirgends
abrufbar.

P(break)-Merkmale bleiben auf M5 (Modell ist darauf trainiert, Fix 2026-07-13).

Mit 5 Szenarien getestet (alles passt, Bias uneinig, Kosten teuer, Level zu
weit, Kaltstart ohne ATR_M15 -> kein Absturz), live verifiziert ueber
deploy.py --feld m15_setup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 15:18:29 +02:00
Axel HocksandClaude Opus 5 30c8616280 Gesamtempfehlung entfernt (User-Entscheidung 2026-08-08)
"Funktioniert so leider nicht, entferne es komplett - wir bauen etwas Neues."

Entfernt: Headline, Konfidenz-Ring, Bias-Nadel, Modul-Chips, Konsens-Zeile,
Block-Gruende. Dazu renderVerdict(), die zugehoerigen 24 CSS-Regeln,
docs/gesamtempfehlung.md und die Snapshot-Felder `verdict` + `block_mix`.

Die Aggregation war reine ANZEIGE - vor dem Loeschen belegt: die Order-Logik
haengt an `wave_signal` bzw. `checklist`, nicht am Verdict (Blinken app.js:821,
Order-Dialog 1312/1366/1391). Orders, Alarme und das gemessene Veto
(-6,60 EUR/Lot) sind unberuehrt.

BEHALTEN (sassen nur in derselben Karte, je eigene Beleglage, User-Entscheidung):
  Zeitebenen-Ampel  #wave-turns  - war aus der Welle-Karte dorthin verschoben
  Erwartete Spanne  #kx-cone     - out-of-sample kalibriert, trifft real ~77 %
  Selbstkalibrierung #kx-selfcal - misst das Wellen-Signal, das bleibt
  HL-Kontext        #hl-note     - lief in renderVerdict mit, schreibt aber in
                                   die Meldungen-Karte
Sie stehen jetzt in der neuen, schlanken Karte "Marktkontext" (#card-kontext).
IDs von vd- auf kx- umbenannt, damit keine tote Nomenklatur zurueckbleibt.

verdict_votes wird WEITER geloggt (User-Entscheidung): `_verdict()` bleibt
bestehen und laeuft 1x/min fuer die Telemetrie sowie fuer den optionalen
MQL5-Konsens-Pfeil. Aus dem 1-s-Snapshot ist es raus - dort waere es Arbeit fuer
eine Anzeige, die es nicht mehr gibt.

Verifiziert: node --check gruen, 34 Tests gruen, 0 verwaiste $("id")-Zugriffe
(die zwei Treffer 'neu'/'x' stehen in Kommentaren), CSS-Klammern ausgeglichen
(287/287), @media und @keyframes intakt. Zeile 1572 (_SQM_VERDICT[d.verdict])
ist der SQUEEZE-MONITOR-Verdict und bleibt.

Asset-Version v=152.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 14:12:27 +02:00
Axel HocksandClaude Opus 5 aefac274d3 Level-Auswahl: Nachbau behoben (core/sr_levels.py) - Luecke bleibt offen
Auftrag zum benannten naechsten Schritt: die Backtests bauten die
Live-Level-Auswahl nach, statt sie zu benutzen. Drei echte Abweichungen:

  1. Der Nachbau clusterte den GEMISCHTEN Rohpool (sorted(ch+cl)); live werden
     ph und pl GETRENNT geclustert. Das ist exakt der Fehler, den der Live-Code
     als behoben dokumentiert ("nicht vorher zusammenlegen!" - Ketten-Mega-
     Cluster in dichten Zonen). Gemessen: 4,5 % aller Zeitpunkte hatten einen
     anderen Widerstand.
  2. Live rundet jede Linie auf 3 Stellen, der Nachbau nicht.
  3. Live fuehrt Widerstand und Unterstuetzung mit getrennter Hysterese.

Geloest ueber core/sr_levels.py (cluster/linien/naechste/halten).
engine._draw_levels ruft es auf, Verhalten bitgenau unveraendert
(tests/test_sr_levels.py, 6 Tests, je 300-400 Zufallsfaelle). Der Test enthaelt
die Gegenprobe, dass der Nachbau wirklich abwich - sonst waere nicht belegt,
dass es etwas zu beheben gab.

backtest_pbreak_retrain.build_levels bleibt unveraendert (Migrations-Regel: die
daraus gefitteten Live-Gewichte duerfen sich nicht rueckwirkend verschieben).
Daneben neu: build_levels_live fuer kuenftige Fits.

ABER die Korrektur schliesst die Basisraten-Luecke nicht: 38,0 -> 38,3 %,
live 52,7 %.

Damit fuenf Hypothesen geprueft und alle widerlegt:
  Niveau/Achsenabschnitt   Roll-Achse faellt live durch
  Vola-Regime              ueber 5 Quintile flach (37,0-39,2 %)
  Sammelart                -1,7 Pp, falsche Richtung
  ATR-Floor-Artefakt       +2,8 Pp; bei live-gleichem ATR erst 40,1 %
  Level-Auswahl            +0,4 Pp

Nebenbefund: 53,9 % aller Backtest-Bars sitzen auf dem ATR-Floor 0,12, live nur
5,4 % - der Backtest-Zeitraum ist deutlich ruhiger. Der ATR selbst stimmt aber
ueberein (Median live 0,2167 gegen letzte 7 Tage 0,2174).

Kein Notfall: auto_sr_close ist false, das Modell schliesst keine Trades.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:30:07 +02:00
Axel HocksandClaude Opus 5 fd3c7f57a5 Live-Code von Backtest-Skript entkoppelt: core/squeeze_scan.py
core/engine.py (squeeze_monitor) und weekly_review.py importierten
backtest_breakout_squeeze - die Abhaengigkeitsrichtung war verkehrt:
ein Fehler im Backtest konnte den laufenden Bot treffen.

Schwerer wog, WIE die Parameter hineinkamen:

    BQ._N = _SQ_N; BQ._K = _SQ_K

Das mutiert Modul-Globale eines Backtests, wirkt prozessweit und damit auf
jeden anderen Nutzer desselben Moduls im selben Prozess. Die Werte weichen
real ab (Backtest _N=12, live _SQ_N=10).

Geloest ueber core/squeeze_scan.py - Parameter stehen in der Signatur.
backtest_breakout_squeeze.py leitet nur noch weiter, damit es EINE
Implementierung gibt statt zweier (der sim_run/_ema_series-Fehler).

Der Exit ist bewusst NICHT mitrepariert: exit_legacy ist eine bitgenaue
Kopie inkl. seiner Abweichungen vom kanonischen Exit (Trail 1,5 statt 1,0,
kein Lock/Time-Stop/TP, max_hold 288 statt 200). Damit misst der B4-Monitor
gegen einen veralteten Exit - separater, offener Befund. Ihn hier still
mitzuaendern haette die Vergleichsgrundlage verschoben.

Bitgenauigkeit bewiesen (tests/test_squeeze_scan.py): die alte Fassung liegt
eingefroren im Test und laeuft gegen die neue ueber 500 synthetische Reihen
x 3 Multiplikatoren. Ein Vorher/Nachher-Lauf waere ungueltig gewesen - der
Backtest zieht Bars live aus MT5, das Fenster verschiebt sich staendig.

Test selbst per Mutationsprobe geprueft: 5 von 6 eingebauten Fehlern schlagen
an, der sechste (d>0 -> d>=0) ist beweisbar aequivalent, da d nur +-1 ist.

Live-Gegenprobe auf 9000 M5-Bars: n=112, Treffer 44%, OeR +0,178, PF 1,26.

Aktivierung beim naechsten Neustart - bei offener Position kein Neustart fuer
eine verhaltensneutrale Aenderung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 07:21:45 +02:00
Axel HocksandClaude Opus 5 caa937f87d Gesamtempfehlung: nur noch Module mit Stimmrecht · Tooltips ueberall (v=147)
· Modul-Chips: neues `used`-Flag in _verdict.add(). used=False = dauerhaft
  entmachtet (Elliott, Orderbuch — beide heute gemessen ohne Inhalt), das
  Frontend filtert sie aus. ⚠ Sie bleiben im Snapshot und in verdict_votes:
  log_verdict_votes speist daraus die Telemetrie und die 25.000-Verdict-Messung
  braucht die Reihe weiter. Ausgeblendet wird die Anzeige, nicht die Messung.
  Module mit weight=0 aus SITUATIVER Stille (Welle bei WARTEN, Squeeze ohne
  Ausbruch) bleiben sichtbar.
· #vd-note (Muenzwurf-Hinweistext) entfernt, samt CSS. Die Aussage steht
  weiter im Karten-Tooltip.
· Tooltips auf allen Dashboard-Anzeigen (59 title-Attribute): Karten,
  Header-Boxen, Trade-Leiste, Anzeige-Elemente. Wo eine Messung existiert,
  steht sie drin. Gesetzt ueber set_tooltips.py — idempotent, ergaenzt nur
  fehlende title=.

Verifiziert: keine Anzeige mehr ohne Tooltip, keine doppelten IDs, Tag-Balance
ok, v=147 ausgeliefert, Elliott/Orderbuch used=False, eine Instanz auf 8000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:46:31 +02:00
Axel HocksandClaude Opus 5 2cdd1ba0e8 Hyperliquid geprueft: Orderbuch-Stimme raus, Funding gemessen (traegt nicht),
Kontext in die Meldungen (v=145)

Direkt gegen die HL-API geprueft statt aus dem Code geschlossen.

ANGEBOT: 4 Oel-Maerkte (2 liquide: xyz:CL OI 3,07 Mio, xyz:BRENTOIL 2,25 Mio),
je Markt mark/oracle/funding/open_interest/day_volume + l2Book (20 Level je
Seite). Historie: fundingHistory 5.095 Stundenwerte ueber 7 Monate inkl.
premium. Open Interest hat KEINE Historie -> waere sammelpflichtig.

Netz-Frage geklaert: config sagt testnet (leeres Buch, 0 Bids/0 Asks), aber es
sind zwei Schalter — [hyperliquid] network steuert das Handeln (aus),
[sim] price_network die Daten (mainnet, live bestaetigt).

(1) Mehr Orderbuch-Daten: NEIN. Zweimal unabhaengig gemessen — bookflow_report
    0,2-1,0 bp gegen eine ~3-bp-Schwelle und KIPPT; Lead-Lag: Pepperstone
    fuehrt, HL trifft nach 6 s zu 51 %.
(2) Modul "Orderbuch" Gewicht 0,5 -> 0. Ueber 2.688 Episoden beidhaelftig
    negativ (-0,054/-0,066, 49 % Treffer). Chip bleibt.
(3) analyze_hl_funding.py: Funding/Premium gegen den CFD, 2 Haelften.
    ⚠ Der erste Lauf meldete mehrere "robuste" Buckets und war FALSCH —
    ueberlappende Forward-Fenster (aus n=506 werden ~21 unabhaengige Faelle)
    und global gebildete Quintile (Bucket mit der Zeit konfundiert). Dass
    Funding- und Premium-Tabelle fast identisch waren, war der dritte Hinweis:
    HL rechnet das Funding aus dem Premium. Entueberlappt haelt kein Bucket.
(4) hl_ctx in den Meldungen (#hl-note) als reine Anzeige.
    ⚠ Zwei Bau-Fallen behoben: der Aufruf erbte den 2-s-Timeout der Waende und
    lief still ins Leere (braucht real 7,2 s), und er haette den Trend-Loop
    blockiert -> Daemon-Thread wie beim Wirtschaftskalender.

Live verifiziert: hl_ctx befuellt, Orderbuch weight=0 bei erhaltenem Chip,
v=145 ausgeliefert, eine Instanz auf Port 8000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:38:01 +02:00
Axel HocksandClaude Opus 5 874ee16e00 Gesamtempfehlung: Selbst-Kalibrierung, voller Ausrichtungs-Split, Block-Gruende,
Elliott entmachtet (v=144)

Vier Verbesserungen, alle aus dem Gemessenen abgeleitet — kein neues Signal.
Ausgangspunkt: die Karte hat genau eine belegte Funktion, das Veto; als Prognose
ist sie ein Muenzwurf (48-51 % ueber 1.071 Episoden).

(1) SELBST-KALIBRIERUNG. Neue Tabelle rec_outcomes: eine Zeile je EPISODE
    (Richtungswechsel, nicht je Minute), Auswertung ~alle 5 min gegen candles_m1
    nach 30/60 min, Snapshot rec_track, Zeile #vd-selfcal. Gegen 50 % zu lesen.
    Warum der groesste Hebel: die Qualitaet war bis heute unsichtbar und musste
    auf Nachfrage rueckwirkend gemessen werden. Dasselbe Muster
    (pbreak_predictions) hat den Ausfall des P(break)-Modells LIVE aufgedeckt.
    Mit 4 Szenarien getestet (tests_rec_outcomes.py). Zwei Fehlschlaege dabei
    waren Testfehler, keine Code-Fehler — dokumentiert.

(2) alignment_stats auf die VOLLE Historie (1.216 statt 40 Trades) und
    zusaetzlich je Lot. Absolute Euro-Vergleiche sind bei wechselnder
    Positionsgroesse ungueltig (Lehre 04.08.). Damit steht die einzige
    beidhaelftig robuste Aussage der Karte auf ihrer vollen Stichprobe.

(3) Block-Gruende sichtbar (block_mix -> #vd-blocks): "heute X % ohne Block ·
    entry_room … · min_conf …". Bisher nur per DB-Abfrage zu beantworten.

(4) ELLIOTT: Verdict-Gewicht 1,0 -> 0. Gemessen ueber 15.544 Zeilen hatte es mit
    1.384 Episoden die groesste Stichprobe der Tabelle und ist darin flach
    (-0,075/+0,032, 50 % Treffer) — bei 25,9 % Einfluss auf die Nadel, weil es
    in nur 1 % der Zeilen schweigt. Chip bleibt, Stimme entfaellt.
    ⚠ Folge: die Nadel schlaegt staerker aus (real +0,33 -> +1,00).

⚠ Namenskollision beim Bau gefunden und behoben: die neue Klasse hiess zuerst
.vd-track — so heisst bereits die Schiene der Bias-Nadel; sie waere
ueberschrieben worden. Jetzt .vd-selfcal.

Live verifiziert: alignment je Lot, block_mix (93 von 1381 ohne Block),
rec_outcomes angelegt, Elliott weight=0 bei erhaltenem Chip, v=144 ausgeliefert,
eine Instanz auf Port 8000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:21:52 +02:00
Axel HocksandClaude Opus 5 3c1442109d Pending-Fill: Bot-Trades wurden nicht als solche gebucht
Auftrag "überprüfe die heutigen autotrades": die DB meldete für den 06.08.
null Bot-Trades, das Log vier gefüllte SQZ-STOP-Orders. Beides stimmte.

Ein Pending-Fill läuft nicht über engine._open — die Position wird von
trader._refresh_locked per magic-match adoptiert, und dieser Pfad loggt nur
Ticket/Symbol/Richtung/Lots/Preis. Es fehlten setup, sl_at_entry und alle
16 ctx_*-Spalten. Damit war genau die Messpipeline, die den Pending-Umbau
vom 05.08. kontrollieren soll, blind für ihn (B4-Monitor, squeeze_b5,
squeeze_entry_gap zählten null) — Deployment-Drift Fall 8, erste Variante,
bei der nicht die Strategie driftet, sondern ihre Beobachtbarkeit.

- history.tag_bot_trade(): UPDATE nur wenn setup IS NULL, stiller Fail-open
- engine._pending_tickets: Ticket -> Quelle, beim Platzieren/Stornieren gepflegt
- engine._check_pending_fill() im _pos_loop vor dem Pending-Manager;
  Zuordnung über Positions-Nr == Order-Nr (an allen 4 Fills verifiziert),
  setzt zusätzlich _bot_open_ticket/_source und die Entry-Zähler

6 Szenarien getestet, darunter die zwei gefährlichen: fremde Position wird
nicht getaggt, derselbe Fill zählt bei Folge-Ticks nur einmal.
Die 4 Trades des 06.08. nachgetragen (Backup .bak-2026-08-06).

ctx_*/sl_at_entry bewusst NICHT nachgetragen: rekonstruiert wären sie später
von gemessenen Werten nicht unterscheidbar.

Dabei gefunden, dokumentiert, NICHT behoben: der Signal-Pfad setzt/storniert
dieselbe Order 4x in 76 s bei identischem Level, weil block_reason zwischen
entry_room und breakout_pending pendelt (Drift Fall 9).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 10:55:41 +02:00
Axel HocksandClaude Opus 5 a1a5d560b9 Charts-Tab komplett entfernt (User-Vorgabe)
Entfernt: Tab-Button, #view-charts, der gesamte app.js-Chart-Block
(Kartenaufbau, renderChart, loadCharts, 20-s-Refresh, Resize-Handler), die
Chart-CSS-Regeln, die vendorte Bibliothek
web/lightweight-charts.standalone.production.js (164 KB) samt script-Tag - und
die Backend-Kette dahinter: /api/bars und engine.get_bars (60 Zeilen). Beide
existierten ausschliesslich fuer dieses Tab; geprueft, dass es keinen anderen
Aufrufer gibt.

Nicht betroffen (sahen nur aehnlich aus): die Chartmuster-Karte (Verdict-Gewicht
0,25, im Tab "SIG Live"), der MQL5-Indikator samt sr_levels.csv-Export (eigener
Pfad ueber _write_levels_file) und die Analyse-Module structure/patterns/cone -
die speisen den Snapshot, nicht das Chart. Der MT5-Chart bleibt voll bedient.

Ein veralteter Kommentar in trader.py, der auf engine.get_bars verwies, wurde
auf core/gaps.py umgehaengt.

Verifiziert am laufenden Server: /api/bars -> 404, Bibliothek -> 404,
data-view="charts" und id="view-charts" nicht mehr im ausgelieferten HTML,
6 Tabs zu 6 Views paarig, keine verwaisten JS-Referenzen, Klammern-Balance ok,
keine Fehler im Log. v=142.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 23:27:24 +02:00
Axel HocksandClaude Opus 5 7009541c42 Squeeze-Trades bekommen den SL aus M5-ATR (User-Entscheidung), TP unveraendert
trader._calc_sl_tp bekommt die ATR-Zeitebene als Parameter (Default SL_TF =
M15); _send/_send_locked/open_long/open_short und place_stop reichen sie durch.
Gesetzt wird sie an genau zwei Stellen: engine._open bei source="auto_squeeze"
und _manage_squeeze_pending bei quelle="squeeze". Manuelle Trades und
Auto-Signal bleiben bei M15.

Grundlage backtest_sl_basis.py: auf Squeeze-Entries ist der Ertrag zwischen
beiden Basen ein Wash (alle Varianten innerhalb eines Standardfehlers), der
Worst-Case sinkt aber von -8,83 auf -2,44 xATR_M5 = Faktor 3. Auf der
Wellen-Population ist der weite M15-SL in BEIDEN Haelften besser - deshalb
bewusst keine globale Umstellung.

Die Multiplikatoren (1,8-2,2 xATR) sind nicht angefasst, nur die Zeitebene.

TP bewusst NICHT betroffen (User: "nur fuer SL, der TP soll mit dem Runner
mitwachsen"). Geprueft statt angenommen: der von _calc_sl_tp zurueckgegebene TP
wird von KEINEM Aufrufer gesendet, beide setzen nur req["sl"]. Das Ziel
verwaltet trailing.py dynamisch (3,5 x ATR der Wellen-Zeitebene). Warnkommentar
im Code, warum der TP dort nicht mit in die Order darf.

4 Szenarien getestet. Dabei eigene Fehlannahme korrigiert: ohne Pivot greift der
1,2-%-Fallback, der beim M15 vom MINDEST-Deckel aufgeweitet wird - die
2,2x-Obergrenze wird dort gar nicht erreicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 17:39:41 +02:00
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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