Commit Graph
204 Commits
Author SHA1 Message Date
Axel HocksandClaude Opus 5 03329c44b5 Zwischenstand Autotrading: Entry repariert, Defekt in den Exit gewandert
Erhebung auf die Frage "wie erreiche ich das Ziel Autotrading?". Nichts am
Live-System geaendert -- aber die Diagnose verschiebt sich.

Der Pending-Umbau vom 05.08. hat gewirkt: von 8 Bot-Trades seit dem Umbau
fuellten 7 per ruhender Order; der Market-Fallback ist praktisch weg (n=1 bei
+0,148xATR, innerhalb der Nachjagd-Bremse). Vorher lag der Live-Median bei
+0,275xATR ueber dem Level. Deployment-Drift Fall 7 ist damit geschlossen.

Und trotzdem verliert der Squeeze -- die Ursache ist also eine andere geworden.
B5 (ab 01.08., n=11/20): Trefferquote 73 %, aber OeGewinn 13,62 gegen OeVerlust
94,15 = Verhaeltnis 0,14 (Latte 1,0), PF 0,39 (Latte 1,0), Summe -173,46 EUR.

Die Signatur steht im Trade-Protokoll: drei der sieben Pending-Trades wurden per
sr_close bei +0,26 / +2,88 / +0,28 EUR geschlossen, waehrend die Verlierer bis
zum vollen Stop liefen (-43 / -64 / -175). Der Squeeze lebt gemessen von
Laeufern (43 % Treffer, Ertrag im Tail) -- genau die werden gekappt.

Die alte Entlastung des S/R-Closes ist nicht mehr bindend:
backtest_squeeze_srclose.py (24.07.) mass einen Wash, aber mit dem ALTEN
P(break)-Modell und Schwelle 0,55/0,60. Heute laeuft das nachtrainierte Modell
mit 0,35, das 94-97 % aller Beruehrungen schliesst. Gemessen unter X, betrieben
unter Y -- dasselbe Muster wie die acht dokumentierten Faelle.
NAECHSTE MESSUNG: Squeeze mit gegen ohne S/R-Close unter dem heutigen Stand.

Kontext, je Lot normiert: AUTONOM n=11 -5,85 EUR/Lot · MENSCH n=146 +3,20/Lot.
Die setup-Spalte taugt NICHT als Bot/Mensch-Trennung (engine._open schreibt die
Wellenlage auch bei manuellen Trades mit) -- ein erster Auswertungsversuch hat
genau das verwechselt und dem Bot 152 Trades mit +730 EUR zugeschrieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 16:24:35 +02:00
Axel HocksandClaude Opus 5 354a57ef5f M15-Karte automatisch handeln = faellt durch (backtest_m15_auto.py)
User: "messe ob wir den Autotrader bei M15-Empfehlung automatisch traden lassen
koennen." Track-B-Frage, Regel VORAB fixiert (OeR>0 & PF>1 & KI ohne Null in
beiden Haelften, n>=100, schlaegt die Kontrolle, Nachbarn kippen nicht).

Neu gemessen wurde genau EIN Zusatz: die Karte hat bewusst keine Richtung, die
entsteht erst aus der `lesart` (aus P(break)). backtest_m15_gates.py handelt die
vom HTF ERLAUBTE Richtung, nicht die Lesart -- die war nie geprueft.

80k M5-Bars, 2 Halbjahre, echte core.sr_levels/_p_break-Gewichte, Status+Lesart
inkl. Hysterese, kanonischer Exit, Echtkosten, Fill bei BERUEHRUNG, ein Slot:

  A) Karte (Lesart)          H1 -0,162 / PF 0,72   H2 -0,094 / PF 0,84
  B) Lesart + Veto-konform   H1 -0,104 / PF 0,81   H2 -0,051 / PF 0,91
  C) KONTROLLE HTF-Richtung  H1 -0,085 / PF 0,85   H2 -0,030 / PF 0,95
  D) KONTROLLE Gegenrichtung H1 -0,070 / PF 0,87   H2 +0,007 / PF 1,01

Alle vier laufen auf DENSELBEN gruenen, gerichteten Momenten -- variiert wird nur
die Richtung. Die Lesart ist damit in BEIDEN Haelften schlechter als die
HTF-Richtung UND schlechter als ihr eigenes Gegenteil; sie kostet -0,077 bzw.
-0,064 OeR gegenueber C.

A ist nicht "unbelegt", sondern belegt NEGATIV: das 95-%-KI schliesst in beiden
Haelften die Null aus ([-0,222 … -0,099] und [-0,152 … -0,038]).
Nachbarn 0,40/0,50/0,60 alle beidhaelftig negativ und monoton schlechter.

Unabhaengige LIVE-Gegenprobe (m15_states, 3.678 Zustaende): der handelbare
Zustand trifft entkoppelt 46,8 % (30 min) und 42,6 % (60 min) -- beide unter dem
Muenzwurf. Roh saehe es mit 51,5 % besser aus; die Entkopplung (1.793 -> 124
unabhaengige Faelle) ist der ganze Unterschied.

MECHANISMUS: zum vierten Mal derselbe Fehler dieser Karte -- aus einer Aussage
ueber die STRUKTUR ("haelt dieses Level?") wird eine RICHTUNGSprognose. Das ist
Mean Reversion am Extrem, und P(break) taugt gemessen zum EXIT, nicht zum ENTRY.

URTEIL: nicht bauen. Auch kein Umschwenken auf C oder D -- die sind nur weniger
schlecht, ebenfalls negativ. Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 16:19:12 +02:00
Axel HocksandClaude Opus 5 77ed1d5572 S/R-Beschriftung: Chart und M15-Karte nannten verschiedene Zahlen (v1.35, v=169)
User: "die Beschriftung fuer S/R im Chart stimmt nicht mit der Analyse in der
M15-Karte ueberein."

Die LEVEL stimmten -- nur die Zahl daneben nicht. Live gegengeprueft: die CSV
enthielt R;82.069;69, Gate 3 der Karte meldete res 82.069 / p_break 69. Beide
kommen aus _draw_levels(), sind also per Konstruktion identisch; auch die
Distanzen sind exakt (0,477~0,48 / 0,909~0,91 / 0,455~0,45).

DER DEFEKT: das Chart schrieb die NACKTE Zahl = P(Bruch), die Karte klappte
unter 45 % still auf P(Abprall) um und nennt 45-55 % "unentschieden".

  P(Bruch) 33 %  ->  Chart "33%"   Karte "67 % Abprall"
  P(Bruch) 46 %  ->  Chart "46%"   Karte "unentschieden"
  P(Bruch) 72 %  ->  Chart "72%"   Karte "72 % Bruch"

Beide Zahlen richtig, aber die Chart-Zahl sagte nicht, WAS sie ist.
GEMESSEN in 88,1 % der Zeit verschieden (1.797 Vorhersagen / 14 Tage: 66,3 %
unter 45 %, 21,9 % im unentschiedenen Band).

Behoben im Indikator v1.35, wortgleich zu app.js. Ueber 1.678 echte
P(break)-Werte gegengeprueft: Uebereinstimmung 0 % -> 100 %.
Ins RICHTIGE Terminal kompiliert (es gibt real zwei Ordner, nur D0E8209F...
bekommt die sr_levels.csv): 0 errors, 0 warnings, .ex5 frisch, Version im
Terminal gegengeprueft.

Zwei Verdachtsmomente ausgeschlossen statt vermutet: eine stehengebliebene
Alt-Linie (der Indikator ruft ObjectsDeleteAll bei jedem Redraw) und ein falsch
einsortiertes Level (_draw_levels waehlt seit 23.07. nach Lage zum Kurs).

ZWEITER Befund derselben Klasse, ebenfalls behoben: Gate 3 und 3b nannten Level
aus VERSCHIEDENEN Zeitebenen, beide nur als "xATR" --
  3   M30-Pivots, ATR_M15, im Chart gezeichnet
  3b  M5-Pivots,  ATR_M5,  NICHT gezeichnet
Real standen "0,48xATR" und "0,45xATR" nebeneinander, die nicht vergleichbar
sind, und die Karte nannte einen "Support 81,78", den man im Chart vergeblich
sucht (alle 10 M30-Pivots lagen ueber dem Kurs).
Die Quellen-Trennung BLEIBT -- entry_room_atr=0,6 ist ueber 80k Bars auf M5
kalibriert. Geaendert wurde nur die Beschriftung plus Tooltips.

Reine Anzeige: an Gates, Gewichten und Order-Logik nichts geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 16:06:06 +02:00
Axel HocksandClaude Opus 5 95521d041c Schrift eine Stufe kleiner: -2px an der fluiden Wurzel (v=168)
User: "verkleinere alle Schriftarten um 1em".

Woertlich waere 1em = 100 % der Schriftgroesse, also null. Gemeint ist eine
Stufe -- genommen wurden -2px, exakt der Schritt, in dem die Groesse am 24.07.
zweimal HOCHgesetzt wurde. Das Handy landet damit auf dem Zwischenstand von
damals (~16px statt ~18px).

  html { font-size: clamp(15px, 14px + 0.5vw, 22px); }   (war 17/16/24)

  Fenster    v=167     v=168
   390px    17,95px   15,95px
   768px    19,84px   17,84px
  1440px    23,20px   21,20px
  ab 1600   24,00px   22,00px

Das war eine EINZIGE Zeile. Die 96 rem-Werte bleiben unberuehrt, alle
Groessenverhaeltnisse untereinander auch -- genau dafuer wurde heute frueh
umgestellt. Der Bump am 24.07. musste noch 96 Einzelwerte anfassen und
uebersah dabei drei Shorthands.

Ausgeliefert verifiziert: Wurzel = clamp(15px, 14px + 0.5vw, 22px),
93 rem-Werte, 0 px-Schriftgroessen, HTML zieht v=168, Klammern ausgeglichen.

Zurueck auf die 18er-Basis: clamp(17px, 16px + 0.5vw, 24px) -- eine Stufe
entspricht 2px in Minimum und Steigungs-Basis, der Deckel wandert mit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 11:20:18 +02:00
Axel HocksandClaude Opus 5 01916134be Schrift skaliert mit dem Fenster: 96 px-Werte -> rem + fluide Wurzel (v=167)
User-Wunsch: "Schriftarten im Dashboard auf em einstellen, damit auf jedem
Geraet oder je nach Fenstergroesse die Schriftgroesse automatisch angepasst
wird."

Umgesetzt mit rem + fluider Wurzel, NICHT mit em. Der Wunsch war richtig,
die genannte Einheit nicht: `em` ist relativ zum ELTERNelement und reagiert
auf die Fenstergroesse gar nicht -- verschachtelt multipliziert es sich sogar
(h2 mit 1,2em in einer Karte mit 1,1em landet bei 1,32x).

  html { font-size: clamp(17px, 16px + 0.5vw, 24px); }

  390px Handy -> 17,95px  (bisher 18,00 -- bewusst kein Rueckschritt)
  768px       -> 19,84px
  1440px      -> 23,20px
  ab 1600px   -> 24,00px (Deckel)

Der Anker ist so gesetzt, dass am Handy NICHTS kleiner wird -- der User hat
die Groesse am 24.07. zweimal von Hand hochgesetzt; eine Responsive-Umstellung,
die sie wieder eindampft, waere eine stille Ruecknahme seiner Entscheidung.

Verifiziert statt behauptet:
  - alle 96 Deklarationen gegen die 18px-Referenz zurueckgerechnet,
    groesster Fehler 0,0008 px
  - 93 font-size + 3 font:<weight> Npx/...-Shorthand (.ms-chip/.ms-bos-lbl/
    .sqm-badge -- die waren beim Bump am 24.07. zuerst uebersehen worden)
  - ausgeliefert: 0 px-Schriftgroessen, fluide Wurzel da, HTML zieht v=167

Zwei Vorbedingungen geprueft, nicht angenommen:
  - viewport-Meta ist gesetzt (sonst wuerde vw am Handy ~980px messen)
  - beide Media-Queries stehen in px, verschieben sich also nicht mit der
    Schrift (die klassische em-Falle bei Breakpoints)

Abstaende bleiben in px -- sie mitzuskalieren waere ein weit groesserer
Eingriff mit Layout-Risiko; die Anfrage betraf die Schrift.

Groesse global aendern = jetzt EINE Zeile statt 96 Einzelwerten.
Zurueck: web/style.css.bak-2026-08-13

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 11:12:13 +02:00
Axel HocksandClaude Opus 5 5819a9df21 Netto-Rechnung aus den ECHTEN Steuer-Buchungen statt geschaetzt
Der seit 05.08. dokumentierte Defekt ist behoben. _add_net rechnete
net_pnl = total_pnl - gross_win * 26,375 % und unterstellte, die
Quellensteuer sei endgueltig verloren. Sie wird aber taeglich per
"Tax settlement" erstattet - real zu 99 %.

all: vorher net_pnl -2.449,95 EUR, jetzt +181,00 (total +209,93, echte
Steuerlast +28,93). Verzerrung rund 2.630 EUR - sie machte aus einem
profitablen Konto ein verlustreiches. Die Schaetzung der EINBEHALTENEN
Summe war fast exakt; falsch war allein die Annahme, sie bleibe weg.

trader.steuer_buchungen() liest die WHT-/Tax-Deals direkt
(position_id == 0, sauber von Trade-Deals getrennt), unter mt5_lock,
5 min gecacht. Fail-safe: ohne MT5 Rueckfall auf die Schaetzung, das
Feld wht_quelle sagt welche Zahl drinsteht.

Kurze Zeitraeume bleiben verzerrt, in BEIDE Richtungen - die Erstattung
kommt am Folgetag. Bei "today" ist wht sogar negativ, weil die
Erstattung von gestern heute einging. Ehrlich benannt, nicht kaschiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 20:44:09 +02:00
Axel HocksandClaude Opus 5 d8839ef7c5 Tag P/L war falsch: Fehlbuchungen beim Schliessen behoben + repariert
User-Frage "ueberpruefe ob Tag P/L richtig berechnet wird". Die Formel
(realisiert + offen) war bitgenau richtig - die Datenbasis nicht:
Anzeige +14,26 EUR gegen -74,08 EUR realisiert beim Broker.

Ursache, im Log im Sekundentakt (#49926460): 20:04:10 eroeffnet ->
20:04:10 "extern geschlossen" -> "kein OUT-Deal in 1 Deals" ->
Fallback bucht 0,00 -> 20:11:42 der echte Close lief ins Leere.
Drei Defekte: (1) positions_get sieht die frische Position einen Tick
lang nicht, (2) _log_external_close buchte TROTZ "kein OUT-Deal" einen
Close - dabei ist genau das der Beweis, dass sie noch offen ist,
(3) log_trade_close fasste nur exit_time IS NULL an, die Fehlbuchung
blockierte den echten Close dauerhaft. Bei #49852362 kostete das
+5,87 statt -95,38 EUR und den falschen Tag.

Behoben: (1) Abbruch statt Fallback bei "kein OUT-Deal"; (2) eine
erkennbare Fehlbuchung (closed_by='unknown') darf von einem echten
Close korrigiert werden - eng gefasst, gute Zeilen bleiben unberuehrt.
4 Tests inkl. Gegenprobe.

Altlast: tools/repair_closes.py (Trockenlauf Standard, Backup
automatisch). 18 Zeilen ueber 60 Tage korrigiert. Heute von +7,63 auf
-72,67 (Restfehler 1,41). Gesamt-P&L von -282,78 auf +169,98.

Zeitfalle zweimal getroffen: history_deals_get filtert nach
Broker-Wallclock, und fromtimestamp(d.time, BROKER) rendert 3 h zu
spaet. Aufgefallen nur, weil eine Deal-Zeit 23:11 lautete, das Log
aber 20:11:42 sagte.

Statistik-Modul separat geprueft: Arithmetik in allen drei Zeitraeumen
bitgenau korrekt (Abweichung 0,00). Der Netto-Defekt vom 05.08. besteht
weiter und ist groesser als damals: angezeigt -2.449,95 EUR, real
verblieben -17,06 (99 % der Steuer werden erstattet). Nicht gebaut -
die Loesung ist dokumentiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 20:29:22 +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 2b668b8fa2 CLAUDE.md: 2-Halbjahres-Ergebnis zum Wiedereinstieg nachgetragen
Der vorige Commit hat das Skript gepusht, die Doku aber nicht - der
Python-Heredoc scheiterte an der Anfuehrungszeichen-Falle (ASCII-Quote
als deutsches Schlusszitat). Genau davor warnt die Projektregel: keine
mehrzeiligen Strings mit Zitaten per Heredoc, den Edit-Weg nehmen.

Inhalt: die vorab fixierte Regel ist in keiner Zeile erfuellt. Bei
0,3xATR beidhaelftig positiv (+0,119/+0,196), aber H1s KI enthaelt die
Null und der Nachbar 0,5 dreht H1 negativ. Bruchquote 32-45 % nahe der
Basisrate - die Plausibilitaetspruefung besteht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:46:57 +02:00
Axel HocksandClaude Opus 5 9e5ea22e08 Wiedereinstieg nach falschem S/R-Close gemessen - nicht gebaut
User-Frage: wenn die Linie trotz Abprall-Berechnung bricht, waere ein
Neustart des Trades logisch. Der Fall ist kein Randfall - P(break)
liegt live bei 38,7 %, das Gate schliesst 94-97 % aller Beruehrungen.

Erst ein eigener Messfehler: der erste Lauf meldete 93 % Brueche bei
einer Basisrate von 38,7 %. Ursache - ich prueft nur EINE Barriere.
Das Training entscheidet per Rennen (Bestaetigung gegen Ablehnung, wer
zuerst kommt); eine 0,5xATR-Bewegung binnen 60 min passiert fast
immer. Mit dem Rennen: 33 % Brueche, praktisch die Basisrate. Die
Plausibilitaetspruefung hat den Fehler gefangen.

Ergebnis: n=14, Treffer 71 %, OeR +0,859, ~+501 EUR - aber das
95-%-KI ist [-0,084 ... +1,788] und enthaelt die Null. Und drei Trades
tragen alles: die drei groessten Gewinne stammen alle vom 04.08.
(TP-Deckel, zusammen +529,92 EUR), die uebrigen 11 ergeben -28,63 EUR.
Der 04.08. ist der dokumentierte Ausreisser-Tag.

Urteil: nicht bauen. Die vorab fixierte Regel ist verfehlt. Fairerweise
widerlegt der bestehende Wiedereinstiegs-Cooldown die Idee nicht - er
betraf den ungegateten Sofort-Wiedereinstieg, nicht den bestaetigten
Bruch. Sauberer naechster Schritt waere ein Backtest ueber 2
Halbjahre statt 43 Live-Closes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:40:21 +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 e882d795a6 M15-Karte: Selbstmessung entkoppelt - 60 % waren 53 %
User fragte nach einer zweiten Karte auf M5. Die Antwort haengt daran,
ob die bestehende traegt - und sie misst sich seit 08.08. selbst.

Befund: die Karte zeigte 60 % Trefferquote. Zwei Gruende, warum das
nichts belegt. (1) Geclustert: m15_accuracy nahm die letzten 200
Zeilen ohne Entkopplung, bei ~990 Zustandswechseln/Tag sind das fuenf
Stunden derselben Marktlage. Aus 2.302 rohen bleiben 114 unabhaengige.
(2) Regime: das Fenster lief +4,93 $, und roh liest die Karte "auf" zu
62 % richtig und "ab" zu 46 % - das ist der Trend.

Entkoppelt: 53-54 %, KI [46 ... 63] - enthaelt die 50. Der
handlungsrelevante Zustand (gruen + gerichtet) liegt bei 45,5 %.

Behoben: m15_accuracy entkoppelt (Schluessel Level+Stunde) und meldet
beide Zahlen. Anzeige jetzt 53 % statt 60 %.

Antwort auf die M5-Frage: nein, jetzt nicht - die erste Karte hat kein
Urteil, M5 waere teurer (0,193 gegen 0,104), die M5-Information ist
grossenteils schon da (Gate 3b rechnet bereits auf M5), und eine
zweite Karte verdoppelt die Drift-Flaeche.

Offen benannt: die Karte flackert (~990 Wechsel/Tag).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:31:42 +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 a866c9cec7 S/R-Auto-Close wieder an (User-Entscheidung)
Die Funktion existierte und stand seit 06.08. auf false; der
Config-Waechter flaggte das durchgehend. Entscheidend ist die
Unterscheidung: der PAUSCHALE S/R-Close ist 2x verworfen
(Gewinner-Kappen), der P(break)-GEGATETE ist positiv (H1 +357 R,
H2 +1.418 R gegen reines Trailing).

Live kontrafaktisch nachgerechnet ueber 43 Trades ab dem
Nachtrainieren (31.07.): IST +2.171,72 EUR gegen HALTEN mit dem
kanonischen Exit +1.820,91 EUR = +350,81 EUR zugunsten sr_close,
besser in 27 von 43 Faellen. Das kehrt analyze_manual_close.py
(04.08., -530 EUR) um - jene Messung lief auf dem alten Modell.

Die 100 % Trefferquote der sr_close-Statistik ist keine Leistung,
sondern Konstruktion: geschlossen wird nur im Plus.

Vorbehalte: n=43 in einem Regime, EUR-Faktor geschaetzt, das
P(break)-Modell ist live fehlkalibriert (14,3 Pp) und das Gate
gatet kaum (94-97 % aller Beruehrungen).

Alle drei Stellen angeglichen (Snapshot, runtime_state.json, ini) -
sonst bliebe dieselbe latente Inkonsistenz, durch die auto_squeeze
unbemerkt aus war.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:18:59 +02:00
Axel HocksandClaude Opus 5 8584b2b776 Entry-Dialog beim Eroeffnen entfernt (v=163)
User-Vorgabe: "entferne auch die Warnung beim Eroeffnen von Trades".
LONG/SHORT feuern jetzt sofort.

Was wegfaellt: die 7-Punkte-Checkliste und der Ausrichtungs-Split im
Moment der Entscheidung - letzterer zeigte die einzige beidhaelftig
robuste Zahl des Projekts (gegen das Signal -6,60 EUR je Lot ueber
1.216 Trades). Bewusste User-Entscheidung, kein Messergebnis; liegt
aber auf der Linie "sichtbar machen, nicht bevormunden" (harte Blocks
waren nie eingebaut, Uebersteuerungen liefen 68 % Trefferquote).

Backend unberuehrt: _entry_checklist rechnet weiter und steht im
Snapshot, die Zahlen bleiben auswertbar. Die Verlust-Close-Abfrage
bleibt - sie schuetzt vor einem Fehlklick, nicht vor einer
Entscheidung. Zurueck: const ENTRY_DIALOG = true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:15:13 +02:00
Axel HocksandClaude Opus 5 e8de83143c M15-Karte: Klartext-Kopfzeile (v=162)
User: "kannst du die M15-Empfehlung vereinfachen, wie: jetzt long/short
zu xxx Prozent". Der Wunsch ist berechtigt - die Karte war sieben
Zeilen Technik. Die Form nicht: eine Richtungs-Prognose ist ueber 1.071
Live-Episoden mit 48-51 % Trefferquote gemessen (frei AUC 0,52
IN-sample), und die Prozentzahl war als conf_pct nicht kalibriert, in
H2 invertiert. Genau daran ist die Gesamtempfehlung gescheitert und
wurde entfernt - es waere der vierte Rueckfall dieser Karte in die
Veto->Richtung-Falle gewesen.

Gebaut ist stattdessen eine Zeile, die sagt WAS ZU TUN IST, mit der
einen kalibrierten Prozentzahl: P(break) des Einstiegs-Levels (AUC
0,65 oos) - eine Aussage ueber die Struktur, nicht ueber den Trade.

  gruen  JETZT: LONG-Order bei 78,768 (Abpraller) - haelt zu 75 %
         - Ziel 79,033 - SHORT meiden
  gelb   JETZT: warten auf das Level - erlaubt waere LONG
  gelb   JETZT: kein Trend-Veto - die Karte gibt hier keine Richtung
  rot    JETZT: nicht handeln - Spread frisst den Edge

"Erlaubt" heisst nicht "empfohlen"; belegt ist nur, dass die
Gegenrichtung kostet (-6,60 EUR/Lot). 45-55 % bleibt ohne Richtung.

Reine Formulierung, keine Aenderung der Gate-Semantik. Frontend-only,
kein Neustart noetig.

Beim Bau in die Anfuehrungszeichen-Falle gelaufen (ASCII-Quote als
deutsches Schlusszitat -> Unexpected token). node --check hat es
gefangen - genau dafuer wurde es eingebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:11:40 +02:00
Axel HocksandClaude Opus 5 661b99cc88 Trailing breiter (Richtung M15) gemessen: faellt durch
User-Frage nach einem Trade, der bei Trail 1,0xATR_M5 nach rund einer
ATR Ruecklauf auf Einstand ausgestoppt wurde.

Die Frage war nicht schon beantwortet: backtest_exit_atr_tf.py (08.08.)
stellte den GESAMTEN Exit auf ATR_M15 (simulate nimmt EINEN atr fuer
SL, Trail, TP und Breakeven - daher das verdreifachte Tail), und
backtest_trailmult.py (31.07.) traf die Frage, lief aber auf M5-Bars.
Genau davor warnt analyze_trail_resolution.py: eine Bar-Simulation
ueberschaetzt enge Trails und unterschaetzt weite - bei 1,5xATR kippte
dort sogar das Vorzeichen. Der Sweep war also mit einer Verzerrung
GEGEN weite Trails gemessen.

Diese Messung kontrolliert das: gleiche Einstiege, gleicher ATR (M5),
Trail-Abstand in Dollar identisch, nur die Exit-Aufloesung variiert;
Zeitgrenzen wall-clock gleich (200 M5-Bars = 1000 M1-Bars, Time-Stop
24 = 120 - der Altbestand kappte M1-Trades nach 200 statt 1000 min).

Ergebnis: 1,86 ("M15") faellt in H1 auf BEIDEN Populationen und BEIDEN
Aufloesungen klar durch (Treffer 25-30 %, PF 0,52-0,64).

Wichtiger Nebenertrag: der Aufloesungs-Einwand ist entkraeftet. Die
Differenz M1-M5 ist bei ENGEN Trails gross und verschwindet bei
weiten. Die feinere Aufloesung bestraft enge Trails, sie belohnt weite
nicht. Der Vorzeichenwechsel vom 05.08. kam aus willkuerlichen
Einstiegen und reproduziert mit echten nicht.

Grenzen: Squeeze n=46/47 je Haelfte, M1-Historie ~55 Tage - die zwei
Haelften sind zwei Haelften EINES Regimes. Keine Aenderung, Trail
bleibt 1,0xATR_M5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 22:07:29 +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 35e91474e8 Auto-Squeeze Zuverlaessigkeitspruefung + Wochen-Simulation
Befund 0 beantwortet die Frage vorweg: der Trader ist AUS.
runtime_state.json enthaelt "auto_squeeze": false und ueberschreibt
die ini (true) beim Start - dieselbe Falle wie am 31.07. bei
auto_signal, nur mit umgekehrtem Vorzeichen. Letzter Squeeze-Trade
06.08. 13:52, entry_count 0. Der Config-Waechter meldet es korrekt.

Befund 1: die Mechanik arbeitet. Die Simulation nutzt die echte
_squeeze_one und reproduziert 10 von 11 Live-Trades binnen 10 min
auf wenige Cent genau.

Befund 2: Woche n=47, Treffer 57 %, OeR +0,196, PF 1,37, SumR +9,20
(~+610 EUR bei 2,5 Lots) - im validierten Band. ABER: die Sim
ueberhandelt um das 2,4-fache (kein Live-Dedup/Cooldown), der Edge
stirbt bei 0,20xATR Fill-Slippage, und eine Woche ist Rauschen -
die Phase mit AUSgeschaltetem Trader war sogar die bessere.

Befund 3: auf denselben 10 Einstiegen war der LIVE-Exit 70 EUR
BESSER als der kanonische (-109,52 gegen -179,27). Das widerspricht
dem B4-Befund vom 01.08. ("die Luecke entsteht im Exit"). Der
S/R-Close rettete drei Trades. n=10, gemischt - kein Urteil, aber
ein Warnschild gegen den umgekehrten Schluss.

Befund 4: B5 bei 11/20 Trades, beide Bedingungen weit verletzt
(Verhaeltnis 0,17, PF 0,45 bei 73 % Trefferquote). Formal nicht
faellig.

Offen: zwei Live-BUYs am 06.08. 13:51/13:52 zum identischen Preis
auf einen Ausbruch - moeglicher Doppel-Einstieg, ungeprueft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:01:34 +02:00
Axel HocksandClaude Opus 5 06ebb014be Eroeffnungsluecken (close_open) gemessen: auch kein Magnet
User-Frage "vielleicht will der Kurs erst die Kursluecke schliessen?"
war berechtigt offen: der vorhandene Gap-Befund (backtest_gaps.py)
beruht auf der vacuum-Definition, und core/gaps.py sagt ausdruecklich,
dass nur die gemessen wurde. Die Klasse, die ein Mensch "Kursluecke"
nennt (Schluss -> Eroeffnung, Wochenendluecke), war nie geprueft.

124 Luecken >= 0,50 $ ueber 4.359 D1-Bars, 2 Haelften, Bootstrap-KI.
Fuellquote sieht stark aus (75-89 % in 10 Tagen) - die Kontrolle
(gleiche Distanz, gleiche Bar, GEGENrichtung) liegt praktisch gleich
auf, in H2 bei 3/5/10 Tagen exakt identisch. Alle 24 Differenz-KI
enthalten die Null. Kontrolle B: an Nicht-Luecken-Tagen laeuft der
Kurs dieselbe Strecke in 10 Tagen zu 73,5 % nach unten und 75,5 %
nach oben - die ~75-80 % sind die Basisrate, keine Gap-Eigenschaft.
Grosse Luecken >= 1,0 $ kippen zusaetzlich das Vorzeichen zwischen
den Haelften (n=22/23).

Dritte Bestaetigung derselben Lehre nach Vakuum-Gaps und Fibonacci:
die Frage ist nie "faellt/haelt es?", sondern "haeufiger als eine
willkuerliche Linie gleicher Distanz?".

Keine Aenderung - close_open bleibt reine Anzeige, fliesst weiter
NICHT in zone_lines().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 08:27:46 +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 0c81c4e651 Die zwei geratenen M15-Schwellen gemessen: beide nicht kalibrierbar
Auftrag: Reichweite (0,5xATR) und Kosten-Schwelle (0,32, von M5) messen statt
raten. 2 Halbjahre, Level-Beruehrungen M15, Fill bei Beruehrung, kanonischer
Exit, Echtkosten, Episoden-entkoppelt, mit Bootstrap je Zelle.

ZUERST EIN ARTEFAKT IM EIGENEN CODE: der erste Lauf stieg sofort zum Level-Preis
ein, auch wenn der Kurs 0,9xATR entfernt stand - die Sim schenkte sich diesen
Abstand. Ergebnis war "je weiter weg, desto besser" (+0,293 im obersten Bucket,
KI ohne Null). Mit Fill bei Beruehrung faellt es auf +0,179. Derselbe Fehler wie
beim Momentum-Test, wo OeR +2,2 den Code entlarvte.

ERGEBNIS: keine der beiden Schwellen ist kalibrierbar.
  Abstand xATR   H1 OeR   H2 OeR
  0,00-0,10      -0,227   +0,100
  0,10-0,20      -0,130   -0,115
  0,20-0,30      -0,306   -0,129
  0,30-0,50      -0,112   +0,216
  0,50-0,75      -0,039   +0,042
  0,75-1,00      -0,040   +0,179
H1 ist ueber ALLE sechs Buckets negativ. Kein Bucket besteht die vorab fixierte
Regel. Beim Kosten-Gate dasselbe: nur H2 0,06-0,10 schliesst die Null aus, H1
liegt dort bei +0,016/-0,040.

Der eigentliche Befund ist nicht "welche Schwelle", sondern: es gibt nichts zu
optimieren. Level-Beruehrungen auf M15 in HTF-Richtung sind in H1 durchgehend
negativ. Eine Schwelle kann keinen Edge erzeugen, den die Grundgesamtheit nicht
hat.

Konsequenz: die 0,5xATR bleiben eine gesetzte Zahl (ehrlich so benannt), das
Kosten-Gate bleibt auf M15 dekorativ - beides jetzt gemessen statt vermutet.
Einzige schwach gestuetzte Richtung: teuer ist schlechter (H2 0,16-0,20 ->
-0,482, KI [-0,949 ... +0,008]).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:22:53 +02:00
Axel HocksandClaude Opus 5 6a9b554d54 M15-Karte an 7 Tagen getestet: Veto haelt ueber 2 Halbjahre, Woche war Rauschen
Wochentest (test_m15_karte_woche.py, 30.07.-07.08., 93 Episoden) meldete das
Veto als FALSCH herum: MIT dem HTF OeR -0,273 / PF 0,56, GEGEN den HTF +0,258 /
PF 1,83 - Differenz -0,532 R gegen die erlaubte Richtung.

Gegenprobe ueber 2 Halbjahre auf DERSELBEN Population (Level-Beruehrungen, M15):
  H1 (n=1504)  MIT -0,072 / PF 0,87   GEGEN -0,116 / PF 0,80   -> +0,044 R
  H2 (n=1617)  MIT +0,028 / PF 1,06   GEGEN -0,012 / PF 0,98   -> +0,040 R
Beidhaelftig konsistent. Die Woche war Rauschen (n=93 gegen n=3121). Dieselbe
Falle wie bei der 15-Minuten-Regel und dem Nacht-Guard.

Der Verdacht war trotzdem berechtigt: der HTF-Filter ist auf SIGNAL-Entries
validiert (backtest_htf_filter.py), nicht auf Level-Beruehrungen. Auf der
Level-Population traegt er +0,04 R statt des dokumentierten "Edge x2" -
richtig, aber klein.

Was der Test sonst zeigt - die Karte ist zu permissiv:
  gruene Bars je Tag   22-56 von 92 (24-61 %)
  Episoden je Tag      14,7
  Kosten-Gate blockte  0 von 644 Bars
Das Kosten-Gate ist auf M15 dekorativ (Spread/ATR ~0,10, Schwelle 0,32). Die
Level-Einstiege selbst tragen kaum (OeR -0,072 / +0,028); das Veto macht sie nur
weniger schlecht. Die einzige diskriminierende Schwelle (Reichweite 0,5xATR) ist
gesetzt, nicht gemessen.

Fehler im Test selbst, dokumentiert: der erste Lauf zaehlte 46 fortlaufende
gruene Bars als 46 Trades und meldete 7 % Trefferquote - eine Bewegung 46-mal
gezaehlt. Erst die Entkopplung macht die Zahl lesbar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:18:20 +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 010007f7a3 Exit-Abstand aus M15-ATR gemessen = faellt durch, Exit bleibt am M5-ATR
Zweiter Teil der M15-Idee: M5-Einstieg behalten, nur den Exit groeber fuehren.
Schliesst zugleich den seit 31.07. in core/trailing.py offenen Punkt
("bisher misst er nur M5").

  M5-ATR (heute)  H1 +0,219 / PF 1,41 / Worst -2,17
                  H2 +0,117 / PF 1,25 / Worst -2,23
  M15-ATR         H1 +0,096 / PF 1,14 / Worst -4,26
                  H2 +0,019 / PF 1,02 / Worst -6,73

Schlechter in BEIDEN Haelften und das Tail-Risiko verdreifacht sich. Dasselbe
Muster wie bei backtest_sl_basis.py.

Zwei Methoden-Fallen, die die Messung fast entwertet haetten:

1) simulate() normiert R mit DEMSELBEN ATR, den es fuer SL/Trail/TP nutzt. Mit
   dem 1,86x groesseren M15-ATR waere dieselbe Dollar-Bewegung ein kleineres R -
   die M15-Variante haette mechanisch schlechter ausgesehen. Beide werden
   deshalb in M5-Risikoeinheiten zurueckgerechnet.

2) Der erste Lauf sammelte die Entry-Liste ueber exit_fn - das wird von scan()
   bei JEDEM Box-Ausbruch gerufen, nicht nur bei den komprimierten: 519 statt
   132 Einstiege, also die Kontrollgruppe statt des Squeeze. Behoben ueber den
   additiven Rueckruf on_entry(j, d, lvl, atr, komprimiert) in
   core/squeeze_scan.py; Bitgleichheit weiter durch tests/test_squeeze_scan.py
   belegt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 15:01:44 +02:00
Axel HocksandClaude Opus 5 b5eff2a5d6 Squeeze auf M15 gemessen = faellt durch, kein M15-Modul gebaut
User-Wunsch nach einem M15-Empfehlungsmodul. Der Squeeze ist der einzige
beidhaelftig validierte Einstieg, gemessen auf M5 und M1, nie auf M15.

DIE KONTROLLE HAT ZUERST VERSAGT - und das war der wichtigste Teil. Meine
M5-Kontrolle lieferte -0,133/+0,044 statt der dokumentierten +0,124/+0,292.
Ursache: allein der ATR-Floor.
  mein Ansatz (0,542xMedian) = 0,060 = 0,54x Median  ->  -0,108 / +0,036
  dokumentiert               = 0,120 = 1,08x Median  ->  +0,224 / +0,087
max_hold war irrelevant. Ich hatte auf M15 einen halb so strengen Filter
angelegt wie auf M5 - der relative Floor aus backtest_squeeze_multi.py diente
dort der Vergleichbarkeit zwischen INSTRUMENTEN, nicht zwischen Zeitebenen.

Deshalb ueber die ganze Floor-Spanne gemessen statt einen Wert zu waehlen:
  0,50  H1 -0,253 (n=143)   H2 -0,024
  0,75  H1 -0,290 (n=108)   H2 +0,047
  1,00  H1 -0,030 (n= 39)   H2 +0,086
  1,08  H1 +0,216 (n= 33)   H2 +0,080   <- M5-aequivalent
  1,25  H1 -0,309 (n= 16)   H2 +0,097
  1,50  H1 -0,279 (n=  7)   H2 +0,151
Die einzige beidhaelftig positive Zelle hat n=33 in H1, und BEIDE Nachbarn
kippen. Vorab fixierte Regel verfehlt: Rauschen, exakt das ORB-Muster.

Dazu: alle sechs Nachbar-Kombis sind mit den Live-Parametern in mindestens
einer Haelfte negativ, die Kontrolle "beliebige Box" ist BESSER als der
Squeeze, und der Slippage-Haertetest verschlechtert monoton.

Struktureller Grund in der n-Spalte: bei wirksamem Filter bleiben in H1 nur
33-39 Ausbrueche. Der Squeeze feuert auf M5 2-3x/Woche; M15 ist zu grob.

Positiv-Befund: Median Spread/ATR auf M15 gemessen 0,104 - besser als die
erwarteten 0,133 (M5 0,193, M1 0,319).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 14:55:17 +02:00
Axel HocksandClaude Opus 5 abd5dc0cb8 Echtes CME-Volumen (CL=F) gemessen: traegt nicht mehr als die CFD-Tick-Zaehlung
User-Idee eines Volumen-Spike-Alerts. Berechtigte Frage dahinter: das Projekt
kennt nur tick_volume vom CFD - eine Zaehlung von Preisaenderungen bei einem
Market-Maker-Broker, kein gehandeltes Volumen. Echtes NYMEX-Volumen waere die
erste Datenquelle, die NICHT aus dem Preis abgeleitet ist.

Beide Quellen auf DEMSELBEN Fenster gemessen (28.05.-07.08., 13.855 CME- gegen
14.178 CFD-Bars), gleiche Methode, Ueberschuss ueber die Drift, zwei Haelften.
Bewusst nicht gegen den dokumentierten Wert gestellt - genau dieser Vergleich
(kurzes Fenster gegen Langfrist-Mittel) war am 07.08. der Messfehler.

  Volumen     CME H1/H2         CFD H1/H2
  1,5-2,0x    +0,116 / -0,203   -0,011 / +0,152
  2,0-2,5x    -0,221 / -0,282   -0,101 / +0,589
  >=2,5x      +0,102 / +0,096   -0,267 / -0,881

Trefferquote in ALLEN Zellen 44-53 % - Muenzwurf, in beiden Quellen. Kein
monotoner Zusammenhang, Vorzeichen kippen. Die einzige beidhaelftig konsistente
Zelle (CME >=2,5x) ist mit [-0,234 ... +0,428] bzw. [-0,265 ... +0,461] klar
Rauschen.

EHRLICHE GRENZE: meine CFD-Kontrolle reproduziert den alten Befund
(-0,117/-0,204) NICHT - Populations-Unterschied, kein Widerspruch.
backtest_candles.py mass bedingt auf ein Kerzen-MUSTER, hier laeuft es unbedingt
ueber alle Kerzen. Der alte Befund gilt weiter fuer seine Population.
60 Tage = ein Regime (yfinance-Deckel), also nur ein Ausschluss-Urteil moeglich.

Konsequenz: kein Volumen-Spike-Signal. Die Datenquelle funktioniert, sie traegt
nur keine Richtungsinformation.

Telegram-Kanaele als Eingabe (Bookmap/ATAS) ohne Messung verworfen: sie
transportieren Screenshots. Ein Orderbuch-Zustand ist vorbei, sobald ihn jemand
abfotografiert.

Nebenbefund zum eingereichten Skript: das .iloc[0]-Muster ist KORREKT
(MultiIndex-Spalten), nicht wie von mir zunaechst vermutet ein Fehler. Echte
Maengel: kein Dedup, kein Handelszeit-Gate, voller Tagesabruf im 60-s-Takt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 14:36:33 +02:00
Axel HocksandClaude Opus 5 56a3fe31d8 VWAP-Baender auf M15 gemessen = verworfen (24. Signal-Eingriff)
User-Wunsch nach einem M15-Daytrading-Modul auf Profi-Methodik. Abgleich: fast
alles aus dem Werkzeugkasten ist hier schon durchgefallen (Volume Profile,
Liquidity Sweeps, Market Structure, ORB, RSI/MACD, Inter-Market);
Footprint/CVD/DOM existieren nicht (Market-Maker-Broker). VWAP war die EINZIGE
nie gemessene Zutat.

Gemessen: 26.000 M15-Bars, session-verankert auf den Berliner Kalendertag,
2 Haelften, kanonischer Exit, Echtkosten, Fill bei Beruehrung.

ZUERST DER EIGENE FEHLER: der erste Lauf zeigte Reversion mit OeR +0,13 bis
+0,27 und PF bis 1,71 in beiden Haelften - verdaechtig sauber. Das Band an Bar i
wird MIT Bar i berechnet, und getestet wurde, ob genau diese Bar es beruehrt.
Ein Ausschlag zieht das Band zu sich hin und erzeugt seine eigene Beruehrung.
Mit Band aus i-1 bleibt:
  k=2,0   +0,130/+0,130  ->  +0,041/-0,009
  k=2,5   +0,189/+0,235  ->  +0,046/+0,087
  k=3,0   +0,162/+0,272  ->  +0,024/+0,010
Der Look-ahead war 0,10-0,25 R wert.

Alle drei vorab fixierten Kriterien verfehlt:
  (b) Eine WILLKUERLICHE Linie gleicher Distanz haelt in 9 von 10 Zellen
      genauso gut oder besser (VWAP 70,3-75,1 %, Zufall 73,9-76,6 %) - der
      Fibonacci-Befund reproduziert.
  (c) k=2,0 kippt in H2, also der Nachbar der besten Zelle. Und alle sechs
      95-%-Bootstrap-Intervalle enthalten die Null (beste Zelle k=2,5 H2:
      +0,087 [-0,012 ... +0,185]).
  (a) Die Regel war von mir unterspezifiziert ("<= Squeeze-Box-Niveau" = 0 ist
      fuer ein gleitendes Band unerfuellbar). Gemessen: Median 0,03-0,05xATR je
      Bar, 90-Perzentil aber bis 0,34xATR - mehr als die Einstiegstoleranz.

Kohaerenz-Kontrolle: der Ausbruch an den Baendern ist spiegelbildlich negativ.
Reversion leicht positiv, Ausbruch klar negativ - ein stimmiges Bild.

Nichts gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 14:19:17 +02:00
Axel HocksandClaude Opus 5 dd7c4e6b15 Notfall-Stop auf 8 % der Margin aktiviert (User-Entscheidung, gegen die Messung)
auto_emergency_margin_pct 0 -> 8. Gewaehlt wurde die MILDESTE Variante: Delta
-14 EUR ueber 1022 Trades ist praktisch neutral, sie feuert bei rund 16 % der
Trades. Schuetzt wenig, kostet wenig - eine Versicherung mit kleiner Praemie.

Sizing bleibt ausdruecklich bei 95 % (margin_pct nicht mitgeaendert).

Bezugsgroesse ist die MARGIN DIESER Position, nicht das Konto: bei ~670 EUR/Lot
sind 8 % rund 54 EUR/Lot, bei den aktuellen 2,33 Lots etwa 124 EUR. Der Modus
hat Vorrang vor auto_emergency_pct und auto_emergency_loss, beide bleiben 0.

AKTIVIERUNG braucht einen Neustart - und die bereits offene Position bekommt
den Stop auch danach NICHT. Verifiziert an engine.py:884: der
Wiederherstellungs-Zweig setzt fuer ein wiedererkanntes Ticket
_emergency_margin_armed_ticket = ticket und _emergency_loss auf den
persistierten Wert (hier null), damit ein Neustart keine gesetzte Entscheidung
ueberschreibt (Fix 2026-07-17). Der 8-%-Stop greift ab der naechsten neuen
Position. Neustart daher am besten fahren, wenn das Konto flat ist.

Neu im Config-Waechter (validiert = 0), damit die Abweichung sichtbar bleibt.
Backup: oil_widget_config.ini.bak-2026-08-07-emergency

Zurueck: auto_emergency_margin_pct = 0

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 15:35:34 +02:00
Axel HocksandClaude Opus 5 cef6646a17 Verlustbegrenzung: Notfall-Stop und HTF-Flip-Close gemessen - beide durchgefallen
User-Frage nach automatischem Notfall-Close (30 %?) und alternativ einem
Flip-Close bei entgegengerichtetem Trend.

1) NOTFALL-STOP. 30 % waere ohnehin wirkungslos: Einsatz 670 EUR/Lot,
Median-Verlust 20 EUR/Lot = 3 % der Margin. 30 % erreichen 1 % aller Verluste.
Kontrafaktisch ueber 1022 echte Trades (MAE aus M5-Bars, 87 EUR/$/Lot aus den
Trades selbst geschaetzt):
  ohne Stop  +358 EUR
  3 %  -293 | 5 %  -639 | 8 %  -14 | 15 %  -416 | 30 %  -331
Keine Schwelle schlaegt "gar kein Stop". Nach Einstiegsart: bei "ohne Signal"
sieht 8-10 % mit +298/+290 gut aus, aber beide Nachbarn kippen (-292 / -106)
-> Rauschen.

2) FLIP-CLOSE AUF DEN HTF-TREND (backtest_flipclose_htf.py) - war nie gemessen.
Alle sechs Varianten in BEIDEN Haelften schlechter:
  BASIS                        H1 -548   H2 -154
  M30 ab +0,0R                    -629      -247
  M30 ab +0,5R                    -574      -234
  M30 ab +1,0R                    -549      -183
  M30 auch im Minus               -616      -327
  M30+H1 ab +0,5R                 -570      -222
  M30+H1 auch im Minus            -616      -290
Die mildeste Variante ist die, die kaum feuert - exakt das Muster der
15-Minuten-Regel.

Kontrolle: die Basis (-548/-154) reproduziert backtest_flipclose2.py
(-537/-140), die Pipeline ist in Ordnung.

Methodik: feste, geteilte Entry-Liste ueber alle Varianten.
backtest_flipclose2.py laeuft nach jedem Exit bei xb+1 weiter, wodurch jede
Variante eine andere Trade-Folge bekommt (der am 31.07. bei
backtest_exit_combo.py korrigierte Fehler). Hier von vornherein vermieden.

Mechanismus in allen Faellen derselbe: Trefferquote steigt (38->44 %, 42->51 %),
Ertrag faellt = Gewinner-Kappen. Fuenfte unabhaengige Messung dieser Klasse,
alle negativ.

Nichts gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 14:41:13 +02:00
Axel HocksandClaude Opus 5 59e9498237 G/V-Lag: 1-s-Fallback + ehrlicher Verbindungspunkt (v=151)
Zuerst gemessen, dann gedreht - und das Backend war NICHT das Problem:
  /api/snapshot   75 Abrufe in 20 s -> 21 verschiedene ts = ~1/s
  WebSocket-Push  direkt am Socket gemessen: Median 1,04 s (min 1,00 max 1,06)
  G/V-Aenderungen Ø 1,44 s - das ist der Markt, keine Verzoegerung

Die ganze Server-Kette liefert bereits 1 s. Der Lag entsteht erst am Handy:
bricht der WebSocket STILL weg (WireGuard-Aussetzer, App-Wechsel), traegt nur
noch der REST-Poll - und der stand auf 4 s.

POLL_MS 4000 -> 1000, aber mit Sperre: solange der WS liefert (lastWsMs,
Fenster WS_FRISCH_MS=2200 ms), ueberspringt der Poll den Abruf. Kein
zusaetzlicher Verkehr im Normalfall.

Denkfehler, den erst die Simulation zeigte: der erste Entwurf las die
WS-Frische aus lastRecvMs (jede Quelle) - damit drosselte sich der Poll SELBST
und kam bei totem WS nur auf 2,9 s statt 1 s. Jetzt zwei getrennte Uhren.

Simuliert: WS gesund -> 0 Zusatz-Abrufe, max. Alter 0,9 s. WS tot -> 1/s, max.
Alter 0,9 s. WS traege (5 s) -> max. 2,9 s. Vorher bei totem WS: 4,0 s.

Der Verbindungspunkt log: er wurde nur bei sock.onclose auf "off" gesetzt, aber
genau der Fall, der den Lag erzeugt, feuert KEIN onclose - der Socket haengt
still, der Punkt blieb gruen. Neu .dot.stale (bernstein, pulsierend) ab 3,5 s
ohne frischen Snapshot: gemessen wird, was ANKOMMT, nicht was der Socket ueber
sich behauptet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 14:20:42 +02:00
Axel HocksandClaude Opus 5 b14d81f412 restart_server.bat prueft jetzt auch - und zwei cmd-Fallen dabei behoben
Korrektur meiner eigenen Einordnung von vorhin: ich hatte restart_server.bat
als "Wiederanlauf-Pfad" ausgenommen. Falsch. Die Aufgabenplanung startet
start_server_hidden.vbs -> start_server.bat; restart_server.bat wird von NICHTS
automatisch aufgerufen (geprueft) und ist damit ein absichtliches Deployment.
Es prueft jetzt vor dem Kill, Notausgang --ohne-pruefung.

Nur start_server.bat bleibt ungeprueft - das ist der echte Wiederanlauf-Pfad.

Zwei cmd-Fallen, beide NUR durch den Positiv-Test gefunden:

1) `if errorlevel 1` innerhalb eines geklammerten if/else-Blocks wird zur
   PARSE-Zeit ausgewertet, nicht zur Laufzeit. Der erste Entwurf brach deshalb
   auch bei SAUBEREM Code ab - der Neustart haette nie mehr funktioniert.
   Behoben mit Sprungmarken statt Klammer-Bloecken.

2) `echo ... ^(x^)` maskiert im Block anders -> "Der Befehl [0] ist falsch
   geschrieben". Text jetzt ohne runde Klammern.

Der Negativ-Test allein sah in beiden Faellen voellig in Ordnung aus: kaputter
Code -> Abbruch, Server unangetastet, Exit 1. Erst der Positiv-Test hat es
entlarvt. Eine Sperre muss man in beide Richtungen pruefen.

Alle drei Zweige verifiziert (sauber -> weiter/rc 0, kaputt -> Abbruch/rc 1,
--ohne-pruefung -> weiter/rc 0), gegen eine Attrappe, deren Kill/Start durch ein
echo ersetzt ist - so liess sich der Durchlauf-Zweig pruefen, ohne den
laufenden Server anzufassen.

Auch der Testaufbau hatte einen Fehler: die Attrappe lag zuerst in %TEMP%, dort
macht `cd /d "%~dp0"` das Temp-Verzeichnis zum Arbeitsordner und
%~dp0tools\pre_commit.py existiert nicht -> scheinbarer Fehlschlag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 12:07:41 +02:00
Axel HocksandClaude Opus 5 0ab79f1876 Code-Pruefung ans Deployment haengen, nicht nur an den Commit
User-Frage "wird die Pipeline bei jedem Deployment ausgefuehrt?". Antwort war
NEIN:
  git commit          check_nfalle + pytest (Hook installiert)
  tools/deploy.py     prueft nur den LAUFENDEN Server, nicht den Code
  restart_server.bat  gar nichts
  Aufgabe OilTradingServer -> start_server_hidden.vbs   gar nichts

Commit und Deployment sind zwei Ereignisse und fallen beliebig auseinander:
eine geaenderte, nie committete Datei ging ueber restart_server.bat ungeprueft
live; nach einem Reboot startet die Aufgabe, was auf der Platte liegt.

"Der Server kommt hoch" ist kein Ersatz: die beiden log.-NameError in
core/trader.py sassen MONATE in except-Zweigen (einer seit dem Initial-Commit),
und der Server startete jedes Mal sauber.

deploy.py bekommt Schritt 0: check_nfalle + pytest VOR dem Kill, bei Rot
Abbruch mit Rueckgabecode 1. Die Reihenfolge ist der Punkt - ein laufender,
funktionierender Server darf fuer kaputten Code nicht abgeschossen werden.
Notausgang --ohne-pruefung.

Beide Richtungen verifiziert: mit eingebautem F821-Fehler -> ABBRUCH, Exit 1,
Server-PID vorher/nachher identisch (20892), der Prozess wurde nachweislich
nicht angefasst. Ohne Fehler laeuft es durch.

BEWUSST NICHT in restart_server.bat und die Aufgabenplanung - das sind
WIEDERANLAUF-Pfade. Wuerde ein fehlschlagender Test dort den Start verhindern,
staende eine offene Position ohne Trailing, Time-Stop und Notfall-Stop da, nur
mit dem Broker-SL. Eine Pruefung, die den Bot offline laesst, ist schlimmer als
der Fehler, den sie sucht. Der Batch gibt stattdessen einen Hinweis aus und
verweist auf deploy.py.

Regel: absichtliches Deployment blockieren, Wiederanlauf niemals.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 12:02:08 +02:00
Axel HocksandClaude Opus 5 3f1f19087d Live-Backtest-Vergleich in die Pipeline: core/stichprobe.py + Abschnitt E
Konsequenz aus dem Messfehler vom 07.08.: der Vergleich lief nur, wenn jemand
daran dachte - und als er lief, war er falsch gebaut.

1) core/stichprobe.py - die Praevention ist KONSTRUKTIV, nicht ermahnend:
   entkoppeln() / anteil_ci() / unterscheidbar() / schluessel_level_stunde().
   Regel: vor jeder berichteten Rate entkoppeln, jede Aussage ueber einen
   Unterschied mit Konfidenzintervall belegen. Die Zeilen in
   pbreak_predictions und recommendations sind nicht unabhaengig.
   8 Tests, darunter einer, der die reale Konstellation nachspielt
   (roh 77 %, entkoppelt 33 %).
   Fallstrick beim Bau, gefunden weil ich es laufen liess: ein sqlite3-Cursor
   liefert Tupel, keine dicts - die Feldangabe akzeptiert jetzt Namen UND
   Spaltennummern.

2) analyze_divergence.sec_d0 war selbst der Fehler. Es mittelte AVG(p_break)
   ueber ALLE Rohzeilen und flaggte bei Delta > 8 Pp:
     vorher  1058 rohe Zeilen, Delta +8,7 Pp -> ALARM
     jetzt   110 entkoppelte, 37,6 % liegt in [37,3 ... 55,5] % -> OK
   Der Waechter haette heute also einen Fehlalarm produziert - genau den, dem
   ich elf Hypothesen lang nachgegangen bin.

3) NEU: Abschnitt E "GLEICHES FENSTER" (--backtest). Rechnet den Backtest ueber
   genau den Live-Zeitraum und haelt ihn gegen das Intervall der entkoppelten
   Live-Rate. Erster Lauf: live 46,4 % [37,3 ... 55,5] gegen Backtest 43,9 %
   -> im Intervall, kein Befund.

4) Eingebaut in den Wochenreport (weekly_review._divergenz_section, montags
   07:30 per Mail + Telegram), mit demselben Fail-safe wie der
   Squeeze-Abschnitt. Bewusst NICHT in den pre-commit-Hook: der braucht MT5 und
   Minuten, Stufe 1 muss bei ~5 s bleiben.

Ausserdem ein Rechenfehler in meinem ersten Entwurf behoben (p_break steht in
der DB bereits in Prozent, ich hatte zusaetzlich skaliert -> "3763,9 %") und
ein \n-Heredoc-Fall, der genau gegen die dokumentierte Regel verstiess.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:55:05 +02:00
Axel HocksandClaude Opus 5 1f58049049 Die "Basisraten-Luecke" war ein Messfehler - meiner. Aufgeloest.
Nach elf einzeln gemessenen Hypothesen: es gab keinen Fehler im System. Die
14,1 Pp (Backtest 38,6 % gegen live 52,7 %) entstanden, weil ich eine
GECLUSTERTE 6-Tage-Stichprobe gegen ein 208-Tage-Mittel gehalten habe.

  Zeitraum    Backtest auf 03.-07.08. eingeschraenkt: 38,6 -> 43,4 %   +4,8 Pp
  Clusterung  live entkoppelt (max 1 je Level/Stunde): 52,7 -> 45,2 %  -7,5 Pp
  Rest                                                                 +1,8 Pp

Entkoppelt: live 45,2 % [KI 35,5 ... 54,8] gegen Backtest 43,4 % - der
Backtest-Wert liegt IM Intervall. Kein belegbarer Unterschied.

Das ist exakt der Fehler, den ich am selben Tag in der Faelligkeitsbedingung
korrigiert hatte (800 rohe statt entkoppelte Vorhersagen) - und ich habe ihn in
der Auswertung selbst noch einmal gemacht. Regel: bei pbreak_predictions immer
entkoppeln, bevor eine Rate berichtet wird.

Was bleibt:
  Basisrate "gewandert 37,8 -> 53,2 %"   ZURUECKGEZOGEN
  Kalibrierungsfehler                    BLEIBT: 14,3 Pp entkoppelt,
                                         KI [6,8 ... 25,5], Modell sagt 38,1 %,
                                         real 45,2 % -> ~7 Pp Unterschaetzung
  "oberste Klasse invertiert"            NICHT belegt (beruhte auf n=29 rohen
                                         Zeilen = wenige unabhaengige Faelle)
  AUC                                    unveraendert unentschieden

Konsequenz: nichts umbauen. Die Stichprobe ist fuer eine Reparatur zu klein -
genau deshalb steht die Faelligkeit jetzt auf 350 entkoppelten (Stand 93).

Die elf Hypothesen, alle gemessen: Niveau-Drift, Regime-Merkmal, Vola-Regime,
aktuelles Regime, Sammelart, ATR-Floor, Level-Auswahl, Beruehrungs-Erkennung,
Timeout, Auswertungs-Aufloesung M1/M5, Richtungsquelle.

Zwei Kontrollen bestaetigen die Werkzeuge: mein M1-Nachspiel reproduziert die
Live-Auswertung zu 100 %, und pb_levels30 ist live befuellt - der M5-Fallback
ist nicht aktiv.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:44:01 +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 2e89724368 P(break) Niveau-Reparatur gemessen: beide Varianten fallen durch
Folgeauftrag zur B4-Pruefung. Hypothese war: das Modell rankt brauchbar, nur
sein Niveau haengt an einer wandernden Basisrate. Geprueft wurden ein
Regime-Merkmal (ATR/gleitender Median) und ein laufend nachgefuehrter
Achsenabschnitt, Regel vorab fixiert.

collect() in backtest_pbreak_retrain.py hat dafuer einen ADDITIVEN
REG-Parameter bekommen (Default None), Ausgabe ohne ihn bitgenau geprueft
(4371 Zeilen, 0 Abweichungen).

Auf Backtest-Daten besteht die Roll-Achse (Kalib 2,61->1,95 und 10,51->3,25 Pp,
AUC leicht besser), das Regime-Merkmal faellt durch (H2->H1 schlechter).

Auf LIVE-Daten (n=921 ab 01.08.) faellt auch die Roll-Achse durch: Kalib
14,16 -> 10,64 Pp (also nicht repariert), AUC 0,531 -> 0,516 (ueber der
Toleranz), und der Nachbar n=800 kippt auf 15,14 Pp = schlechter als der
Ausgangswert.

Grund: die oberste Klasse bleibt INVERTIERT (69 % vorhergesagt, 17,2 % real).
Eine Niveau-Verschiebung kann eine invertierte Klasse nicht reparieren. Die
Ausgangshypothese ist damit widerlegt.

Drei Erklaerungen fuer die Basisraten-Luecke geprueft, alle widerlegt:
  Sammelart (live 1x je Beruehrung vs Backtest jeder Bar): -1,7 Pp, falsche
    Richtung
  Vola-Regime: Bruchrate ueber 5 Quintile flach (37,0 bis 39,2 %)
  aktuelles Regime ungewoehnlich: letzte 7 Tage Median 0,96 = normal
Der flache Vola-Befund erklaert zugleich, warum das Regime-Merkmal nichts
bringt.

Kontrolle: das Modell VOR dem 31.07. hat auf diesen Daten AUC 0,364/0,406 -
unter 0,5, also invertiert. Reproduziert exakt den Grund fuer das
Nachtrainieren.

Nichts gebaut. Naechster Schritt ist kein drittes Fitten, sondern die einzige
ungeprueft gebliebene Divergenz: die Level-Auswahl selbst (Backtest baut sie
mit pick_level/_cluster nach, live entscheidet _draw_levels).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 11:18:35 +02:00
Axel HocksandClaude Opus 5 908e20a9d0 P(break) v2 live geprueft: Kalibrierung daneben, Trennschaerfe unentschieden
Faellige B4-Messung nach dem Nachtrainieren vom 31.07. (878 Vorhersagen ab
01.08.). Drei Befunde.

1) Das Skript mischte zwei Modelle. Es trennte bei der M30-Umstellung (30.07.),
nicht beim Nachtrainieren (31.07.) - "GESAMT" las altes und neues Modell
zusammen. Derselbe Fehler wie am 02.08. in analyze_divergence.py. Neu:
MODELL_V2 mit demselben Stichtag wie die Faelligkeitsbedingung.

2) Kalibrierung messbar daneben. Die Basisrate ist gewandert: Training 37,8 %,
live 53,2 %, stabil ueber vier volle Tage (51,4 / 54,1 / 56,4 / 53,8 % bei
n=122-276). Ein Modell, dessen Niveau an 37,8 % verankert ist, muss in einem
53-%-Regime systematisch zu niedrig sagen - genau das passiert. Oberste Klasse
invertiert (69 % vorhergesagt, 17 % real).

3) Trennschaerfe NICHT entscheidbar - und das ist der wichtigere Befund.
Entkoppelt n=87, AUC 0,556, 95-%-Bootstrap-KI [0,434 ... 0,674]. Das Intervall
enthaelt den Zufall (0,50) UND die Messlatte (0,654).

Die Faelligkeitsbedingung zaehlte die falsche Groesse: 800 ROHE Vorhersagen,
die aber nicht unabhaengig sind (dieselbe Position pendelt um dasselbe Level).
Aus 878 rohen werden 87 entkoppelte - die Bedingung ueberschaetzte die
Beweismenge um rund das Zehnfache und meldete "faellig", obwohl die Messung
nichts entscheiden konnte. Jetzt 350 ENTKOPPELTE (halbiert die KI-Breite).
Stand 87/350.

Operativ kein Notfall: auto_sr_close ist seit 06.08. false, das Modell
schliesst keine Trades. Es speist nur Anzeige, Chart-Linien und
Copilot-Kontext.

Nichts umgestellt - ein drittes Fitten derselben Bauart wuerde denselben Weg
gehen; der Befund zeigt aufs Niveau, nicht zwingend auf die Rangfolge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 07:43:24 +02:00
Axel HocksandClaude Opus 5 3e8fa9fea8 Auffang-Element in app.js: ein fehlendes Element bricht nicht mehr den Render
Gemessen: 95 direkte $("id")-Zugriffe, 0 davon abgesichert - obwohl die Regel
"neue Elemente per const el = $(..); if (el) {..}" seit 01.08. in CLAUDE.md
steht. Eine Regel mit 0 Prozent Befolgung ist keine Regel, also loest es jetzt
der Code an EINER Stelle statt an 95.

$() gibt bei fehlendem Element ein detachiertes <span> zurueck statt null,
plus einmalige console.warn je ID (kein stiller Fallback - das war der
catch{}-Fehler in pollSnapshot).

?. war NICHT die Loesung: 80 der 95 Zugriffe sind Zuweisungen, und
$("x")?.y = v ist ein Syntaxfehler.

$streng() ist der wichtige Teil. Alle Eingabefelder sind type="number", und
leer heisst dort ausdruecklich "Stop entfernen" (sl: null). Mit dem
Auffang-Element waere .value undefined -> parseFloat NaN -> JSON.stringify
macht daraus wieder null: eine fehlende Eingabemaske haette den Broker-SL
einer laufenden Position stillschweigend geloescht. Betroffen war genau eine
Funktion (sendSltp); setSrMin/setEmg/setManualMargin/setMarginPct fangen NaN
bereits ab (geprueft, nicht angenommen).

Beide Richtungen an einem Minimal-DOM verifiziert, das eine alte index.html
simuliert: mit der alten $-Definition bricht der Render beim ZWEITEN Feld ab,
mit der neuen laeuft er durch. Der Order-Pfad bricht in beiden Faellen sauber
ab.

Asset-Version v=149 -> v=150.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 07:34:01 +02:00
Axel HocksandClaude Opus 5 e7112e1ab6 JS-Syntaxpruefung: node --check als Stufe B in check_nfalle
CLAUDE.md behauptete "kein node im Env" - das stimmte nicht mehr, Node
v24.18.0 ist installiert. Die Zeile hat die Frage jahrelang falsch
beantwortet.

Gemessen an 5 realistischen Fehlern findet die alte Klammern-Balance 1,
node --check findet 5 (86 ms):
  Klammer zu viel        Balance ok   node ok
  const x = ;            Balance blind
  let doppelt            Balance blind
  const doppelt          Balance blind
  return ausserhalb Fkt. Balance blind

Ein Syntaxfehler in app.js bricht den GESAMTEN Render - das Dashboard
friert auf Altwerten ein. Bei 95 direkt dereferenzierten $("id")-Zugriffen
(0 davon mit ?.) ist das kein theoretisches Risiko.

Geprueft wird als MODUL (.mjs), nicht als CommonJS: als CJS haelt Node ein
top-level return fuer legal, der Browser laedt app.js aber als klassisches
Script, wo es ein Syntaxfehler ist. Verifiziert, dass das echte app.js den
strengeren Modus ohne Anpassung besteht.

Kein npm, keine package.json, kein node_modules - node --check ist die
Laufzeit selbst. Damit entsteht NICHT die Divergenz "Pruefumgebung ist nicht
die Laufumgebung" (der .ps1-BOM-Fehler, das pre-commit-Framework): Node und
Chrome benutzen denselben Parser (V8).

Drei Richtungen verifiziert:
  sauber                -> gruen
  mit eingebautem Fehler-> Exit 1, Commit gestoppt
  ohne node im PATH     -> Rueckfall auf alte Pruefung, Exit 0

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 07:27:37 +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 Hocks a35a0e7006 Pipeline-Stufe 1 automatisiert: requirements, pre-commit-Hook, ruff
Nach Web-Recherche zum 2026er-Python-Standard umgesetzt, aber gefiltert: von
uv/Ruff/pyproject/CI passt hier nur, was zu einer Einzelmaschine mit
GUI-gebundenem MT5 und Live-Geld passt.

(1) requirements.txt (Laufzeit) + requirements-dev.txt (Werkzeuge/Messung),
    Versionen gepinnt. Bis dahin gab es GAR KEINE Liste — nach einem
    Maschinenausfall waere die Rekonstruktion Raten gewesen. Per AST ueber
    core/, server.py, tools/ ermittelt statt geraten.

(2) tools/pre_commit.py faehrt vor jedem Commit check_nfalle + pytest (~5 s).
    Einrichten: python tools/pre_commit.py --install. Notausgang
    'git commit --no-verify' ist Absicht.
    Bewusst OHNE das pre-commit-Framework: dessen Nutzen ist
    Werkzeug-Versionierung ueber mehrere Maschinen. Hier gibt es eine, und es
    wuerde eine ZWEITE ruff-Version in einer isolierten Umgebung installieren —
    genau die Divergenz 'Pruefumgebung != Laufumgebung', die heute schon einmal
    zugeschlagen hat.

(3) Ruff statt pyflakes (--select F821), ganzer Scan in 2,1 s. KEIN
    ruff format — das wuerde 161 Dateien umformatieren, darunter alle
    Backtests, und die Migrations-Regel verletzen.

⚠ VIERTER Fall der Klasse 'Erfolg melden, wo nichts geprueft wurde', und nur
durch den Test aufgefallen: --select F821,E999 laesst ruff 0.16 komplett
abbrechen (E999 wurde entfernt, Exit 2); die Meldung geht nach stderr, und weil
ich den Rueckgabecode nicht pruefte, meldete die Stufe 'keine undefinierten
Namen' — ohne irgendetwas geprueft zu haben. Ein absichtlich eingebauter
F821-Fehler kam glatt durch den Hook. Behoben: nur F821, und Exit 2 loest jetzt
den pyflakes-Rueckfall aus.

Beide Richtungen verifiziert: mit Fehler stoppt der Hook den Commit, ohne ist
er gruen. Der Test-Commit wurde zurueckgenommen (war nur lokal, ahead 1).

Nicht umgesetzt: Gitea Actions (Runner auf derselben Maschine wie der Live-Bot,
kein Mehrwert bei 5 s Pruefzeit), Container/Blue-Green (MT5 braucht eine
Desktop-Sitzung, EINE Broker-Verbindung), mypy/ty (kaum Annotationen).

Struktureller Fund: core/engine.py importiert backtest_breakout_squeeze — ein
Backtest ist Teil des LIVE-Abhaengigkeitsgraphen.
2026-08-07 07:08:02 +02:00
Axel HocksandClaude Opus 5 41e527c492 Auto-Logon aktiv — Registry-Weg, sicherer Weg blieb wirkungslos
Endstand verifiziert: AutoAdminLogon=1, DefaultUserName=ah,
DefaultDomainName=HOMEBASE, Aufgabe OilAutoLogonLock Bereit und auf
autologon_lock.ps1 zeigend. Die Boot-Luecke ist damit konfiguratorisch
geschlossen.

⚠ Der SICHERE Weg hat nicht funktioniert: Sysinternals Autologon beendete sich
mit ExitCode 0, schrieb aber nichts — weder ueber den Dialog noch ueber die
Argument-Form. Ausgeschlossen: DevicePasswordLessBuildVersion (nicht gesetzt),
fehlende Elevation, haengender Prozess. Ursache ungeklaert. Aktiv ist deshalb
der Registry-Weg, und damit steht das Passwort im KLARTEXT unter
HKLM\...\Winlogon\DefaultPassword — lesbar fuer jeden lokalen Admin und jedes
Backup-Image. Entfernen-Kommando in CLAUDE.md.

⚠ Dritter Fall derselben Fehlerklasse in diesem Skript, jetzt behoben: die
Speicherart wurde aus einer stale Variable gelesen, die VOR dem
Registry-Schreiben gefuellt war. Die Ausgabe widersprach sich direkt — erst
korrekt 'steht jetzt im KLARTEXT', zwei Zeilen spaeter 'nicht im Klartext '.
Der Zustand wird jetzt nach jedem Schreibvorgang frisch gelesen.

Lehre aus allen drei Faellen: eine Erfolgsmeldung muss den Zustand NACH der
Aktion pruefen, nicht den davor.

Offen: die Wirkung ist erst beim naechsten Reboot belegt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 06:58:02 +02:00
Axel HocksandClaude Opus 5 4c8ce18a9f Autologon: -Direkt-Weg ohne GUI-Dialog
Der GUI-Weg fuehrte zweimal zu nichts. Diagnostiziert: der Dialog OEFFNET sich
(Fenstertitel 'Autologon - Sysinternals', Prozess verifiziert), muss aber mit
ENABLE bestaetigt werden — nur schliessen tut nichts.

Neu: -Direkt. Autologon 3.10 nimmt Benutzer/Domaene/Passwort als Argumente;
das Skript fragt es per Read-Host -AsSecureString ab (unsichtbar, nicht in der
History) und ruft ohne Dialog auf. Schlaegt es fehl, nennt das Skript jetzt den
wahrscheinlichen Grund je nach Weg (Dialog nicht bestaetigt vs. falsches
Passwort).

Abwaegung dokumentiert: bei -Direkt steht das Passwort fuer den Moment des
Aufrufs in der Kommandozeile des Kindprozesses (fuer Admins kurz sichtbar). Es
landet nicht in einer Datei, nicht in der Shell-History — und anschliessend als
verschluesseltes LSA-Secret statt im Klartext in der Registry.

Mit dem echten 5.1-Parser geprueft (0 Fehler), -Direkt als Parameter erkannt,
BOM gesetzt, n-Falle-Scan sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 06:45:54 +02:00
Axel HocksandClaude Opus 5 eccc13f2cf Autologon-Skript: zwei Fehler behoben, die Erfolg meldeten wo keiner war
Der erste Lauf hat NICHTS eingerichtet — weder Auto-Logon noch die
Sperr-Aufgabe. Nachgeprueft: AutoAdminLogon, DefaultUserName und
OilAutoLogonLock allesamt nicht vorhanden.

(1) $ErrorActionPreference = 'Stop' PLUS schtasks /Delete auf eine noch nicht
    existierende Aufgabe: native Programme schreiben nach stderr, PowerShell
    macht daraus unter 'Stop' einen Abbruch. Das Skript endete, BEVOR /Create
    lief. Jetzt wird vorher per /Query geprueft.

(2) Die Erfolgsmeldung log: ein fehlendes DefaultPassword wurde als
    "LSA-Secret " ausgegeben — dabei war gar nichts gesetzt, weil der
    Autologon-Dialog ohne Enable geschlossen wurde. Abwesenheit eines
    Klartext-Passworts beweist nicht, dass der sichere Weg genommen wurde; sie
    ist auch mit "nichts passiert" vereinbar. Jetzt ist AutoAdminLogon = 1 die
    Bedingung, und erst danach wird ueber die Speicherart geurteilt. Ohne
    aktives Auto-Logon bricht das Skript mit Code 1 ab und ueberspringt
    Schritt 2.

Dazu ein Design-Fehler, der erst beim Nachdenken auffiel: die Sperre haette bei
JEDER Anmeldung gefeuert — ein ONLOGON-Trigger unterscheidet nicht zwischen
Auto-Logon und manuellem Login. 30 s nach jedem normalen Anmelden waere der
Bildschirm zugefallen. Neu: tools/autologon_lock.ps1 prueft die Systemlaufzeit
und sperrt nur, wenn der Rechner < 3 min laeuft (= Auto-Logon nach Boot).
Trocken getestet: bei 1088 min Laufzeit -> sperrt nicht.

Beide .ps1 mit BOM geschrieben und mit dem echten 5.1-Parser gegengeprueft
(0 Fehler). check_nfalle.py Stufe C2 deckt alle drei Skripte ab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 06:42:28 +02:00