Commit Graph
100 Commits
Author SHA1 Message Date
Axel HocksandClaude Opus 5 14b3fd4f64 Vierter Slot-Durchgang: Chart-Marker deckte den BRK-Slot nicht ab
User-Auftrag (vierte Runde). Diesmal die Bereiche AUSSERHALB von engine.py
geprueft - core/trader.py, server.py, der MQL5-Export und die
Zustandspersistenz.

⑦ BEHOBEN - Trade-Marker im MT5-Chart (`TR;`-Zeilen) lasen nur
   `self.trader.snapshot()`. Eine offene BRK-Position blieb im Chart also
   UNMARKIERT: die hellgruene Umrandung der Einstiegskerze fehlte. Kosmetisch,
   aber dieselbe Klasse wie Deployment-Drift Fall 8 - nicht die Strategie
   driftet, sondern ihre Beobachtbarkeit. Wer den Chart ansieht, soll sehen,
   wo der Bot eingestiegen ist. Jetzt ueber beide Slots.

DREI ENTLASTUNGEN in diesem Durchgang (geprueft, NICHT vermutet):
  - core/trader.py hat als einzige Klassen-Variable `_STEUER_TTL_S` (eine
    Konstante); der Steuer-Cache liegt als `self._steuer_cache` INSTANZWEISE
    vor. Modul-Globale sind nur die zwei Logger. Die beiden TradeManager teilen
    also KEINEN veraenderlichen Zustand - zusammen mit dem Trailing-Befund aus
    Durchgang 3 ist damit beides sauber.
  - server.py routet ueber `eng.close` (deckt seit heute beide Slots),
    `eng.toggle_trail` (ebenfalls) und `eng.set_sltp`.
  - `emergency_state.json` ist per-Ticket und betrifft nur Slot 1 - die drei
    Notfall-Modi stehen ohnehin auf 0, und der Reichweiten-Waechter meldet es,
    falls einer eingeschaltet wird, waehrend BRK eine Position haelt.

⚠ WEITER OFFEN, unveraendert und bewusst: `set_sltp()` (nur Slot 1, braucht eine
UI-Entscheidung) und `_check_auto_m15`, das `_slot()` umgeht. Neu dazu:
`_check_close_alert` (Flip-Alarm) liest ebenfalls nur Slot 1 - das ist ein
Hinweis, keine Schutzhandlung, und der Flip-Close ist aus.

91 Tests gruen, Pipeline inkl. Stufe E gruen, Deploy verifiziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:15:48 +02:00
Axel HocksandClaude Opus 5 fbc1e96b07 Trade-Leiste: alle Felder normal statt fett
User-Wunsch. `.tb-field input, .tb-field .tb-val` stand auf font-weight:700 -
das trifft ALLE Felder der Leiste auf einmal (Eingaben SL/TP/Gewinn-Close und
die Anzeige-Boxen Richtung/Lots/Einsatz/TP1/TP3). Auf 400 gesetzt, damit die
Leiste einheitlich bleibt.

⚠ Gegengeprueft, dass in der Leiste nichts anderes mehr fett ist: die acht dort
verwendeten Klassen (tb-row, tb-title, tb-dir, tb-field, tb-val, tb-runtime,
stop, gain) haben keine weitere font-weight:700-Regel, und es gibt keine <b>-
oder <strong>-Tags darin.

⚠ Der erste Versuch scheiterte am Anker: ich hatte die Zeile aus einer
sed-Ausgabe kopiert, die zwei Leerzeichen voranstellt. Nichts geschrieben
(Assertion vor dem Write) - danach ueber die Zeilennummer mit Inhaltspruefung.

Backup web/style.css.bak-2026-08-20-tbfett. Reine CSS-Aenderung (v=198), kein
Neustart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:12:19 +02:00
Axel HocksandClaude Opus 5 d59d0eeaee TP-Anzeige entwirrt: doppelten Wert entfernt, Init-Formel ehrlich beschriftet
User-Frage "unterscheidet sich TP von TP1, TP2 oder TP3?" - sie deckte zwei
Fehler auf, beide von mir aus der vorigen Aenderung.

⚠ ZUERST DIE SACHE SELBST: der TP WIRD nachgezogen, aber nach DREI Formeln:
    Init   Entry ± 3,5xATR      fest, gibt dem Trade Luft
    Trail  Bestkurs ∓ 0,5xATR   zieht mit dem Hoch mit
    Lock   Bestkurs ∓ 0,3xATR   sehr eng am Hoch
    immer  mindestens Entry ± 0,5xATR (schliesst nie im Verlust)
Er springt beim Phasenwechsel also von WEIT VOR dem Kurs auf KNAPP HINTER das
Hoch - ab Phase Trail ist er faktisch ein zweiter, engerer Ausstieg ueber dem
Stop. 63 TP-Setzungen im Log bestaetigen das.

① BEHOBEN - "TP2 · Trailing" in der Trade-Leiste zeigte DENSELBEN Wert wie das
   Feld "TP" daneben. Eine Zahl doppelt. Entfernt; uebrig bleiben TP1 (Level)
   und TP3 (Kegel) als das, was sie sind: Orientierungsmarken, die der
   Broker-TP NICHT kennt. Das Feld "TP" bleibt editierbar.

② BEHOBEN - im M15-Setup-Block stand "TP2: ... (3,5xATR - das Trailing fuehrt
   ihn nach)". Das war irrefuehrend: 3,5xATR ist NUR die Init-Formel, und ab
   Phase Trail laeuft der TP nach einer anderen Regel. Jetzt: "Init-Ziel
   3,5xATR - ab Phase Trail zieht der TP an den Bestkurs heran, ∓0,5xATR".

Verifiziert: 0 verbliebene tb-tp2-Referenzen in JS und HTML, span/div
ausgeglichen, keine doppelten IDs, node --check und Render-Probe gruen.
Reine Frontend-Aenderung (v=197), kein Neustart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:07:22 +02:00
Axel HocksandClaude Opus 5 6f1348adf3 G/V und G/V BRK in EINER Box: links Slot 1, rechts BRK
User-Wunsch. Statt zwei nebeneinanderliegender Header-Boxen jetzt eine geteilte:
linksbuendig "G/V" (Slot 1 - manuelle und M15-Trades), rechtsbuendig
"G/V · BRK" (Breakout-Autotrader, eigener Slot seit 19.08.).

⚠ Die WERTE bleiben getrennt, nur die Box ist eine. Die Slots gehoeren
verschiedenen Populationen (Mensch +1,56 gegen autonom -4,71 EUR/Lot); sie zu
ADDIEREN wuerde genau die Trennung verwischen, fuer die der zweite Slot gebaut
wurde. Die Summe steht weiterhin im TAG P/L (day_pl.open summiert beide seit
dem 19.08.).

Umgesetzt ueber flex mit `justify-content: space-between`; der Tooltip sitzt
jetzt an der Box statt zweimal an den Labels, damit die Erklaerung nicht
doppelt steht.

Verifiziert: div 89/89 ausgeglichen, keine doppelten IDs, beide Spans genau
einmal vorhanden, Render-Probe und Pipeline gruen. Reine Frontend-Aenderung
(v=196), kein Neustart - die Render-Logik (hdr-pnl / hdr-pnl-brk) ist
unveraendert, nur das Markup drumherum.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:01:57 +02:00
Axel HocksandClaude Opus 5 5925d9a527 Trade-Leiste: TP1/TP2/TP3 + Setup-Block "Entry Zone / SL / TP1-3" in der M15-Karte
User-Wunsch, mit einer Vorlage im Format "USOIL BUY SETUP: Entry Zone / Stop
Loss / Take Profit 1-3".

(1) TRADE-LEISTE — drei Anzeige-Boxen fuer die LAUFENDE Position:
    TP1 · Level     naechstes STEHENDES M30-Level in Trade-Richtung + P(haelt)
    TP2 · Trailing  der Broker-TP, den `core/trailing.py` dynamisch fuehrt
    TP3 · Kegel     Obergrenze des 80-%-Bandes auf 120 min (core/cone.py)
    Live gegengerechnet: 85.745 (67 % haelt) / 86.634 / 86.153 (trifft 75 %).

(2) M15-KARTE — Setup-Block im Format der Vorlage, direkt unter dem Banner:
    Richtung · Entry Zone (Level ± 0,15xATR) · Stop Loss (2,0xATR_M15) ·
    TP1 (Gegenlevel) · TP2 (3,5xATR) · TP3 (Kegel 120').
    Blendet sich aus, wenn kein Veto, keine Zone oder kein ATR vorliegt -
    aktuell ist genau das der Fall (M30 flach -> kein Veto -> keine erlaubte
    Richtung), und das ist korrektes Verhalten, kein Fehler.

⚠⚠ DREI LEITPLANKEN, damit daraus keine Prognose wird:
  - Die RICHTUNG kommt ausschliesslich aus dem VETO (erlaubte Richtung). Die
    Karte gibt weiterhin KEINE Richtungsprognose ab - die ist ueber 1.071
    Live-Episoden als Muenzwurf gemessen (48-51 %). Ohne Veto: kein Block.
  - Die drei TP sind ANZEIGE, nichts davon geht an den Broker. Ein FESTER TP am
    Gegenlevel ist der staerkste Gewinner-Kappen-Beleg des Projekts: er drehte
    den Squeeze von +0,102/+0,108 auf -0,066/-0,004 (backtest_trailing_sr.py).
    Deshalb steht an TP2 ausdruecklich, dass das Trailing ihn nachfuehrt.
  - NICHTS wird neu gerechnet - Zonen, ATR und Kegel stehen im Snapshot. Ein
    zweiter Rechenweg waere die Divergenz-Falle (dreimal zugeschlagen).
  - Neutral gerahmt, nicht gruen/rot: der Block sagt WO, nicht OB.

Die 0,15xATR der Entry Zone sind die im Projekt gemessene "Beruehrung"
(dieselbe Schwelle wie `at_level` im S/R-Hinweis), nicht geraten.

Reine Frontend-Aenderung (v=195), kein Neustart. node --check, Render-Probe und
die volle Pipeline gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:00:01 +02:00
Axel HocksandClaude Opus 5 5e476025d7 Dritter Slot-Durchgang: TRAIL-Knopf und Wiedereinstiegs-Sperre waren blind
User-Auftrag (dritte Runde). Diesmal die Bereiche ausserhalb der
`self.trader.`-Zugriffe geprueft. ZWEI neue Funde, beide behoben:

⑤ toggle_trail() schaltete NUR `self.trail`. Hielt allein der BRK-Slot eine
   Position, liess sich dessen Trailing per Dashboard weder ein- noch
   ausschalten. ⚠ Das ist keine Kosmetik: ohne `trail_brk` laeuft ein BRK-Trade
   in der gemessen DURCHGEFALLENEN SL-only-Variante (backtest_brk_slonly.py,
   alle zehn KI enthalten die Null, Trefferquote faellt 40 -> 21 %).
   Neu: haelt NUR BRK etwas, wird dessen Trailing geschaltet; sonst (auch bei
   zwei offenen Positionen) das von Slot 1 - die Position, die der Nutzer selbst
   geoeffnet hat.

⑥ Die Wiedereinstiegs-Sperre sah den BRK-Slot NICHT. `_check_auto_close` setzt
   `_pos_close_ts`/`_pos_close_dir` aus `self.trader.snapshot()`; schloss eine
   BRK-Position, blieb die Sperre unarmiert und der Squeeze durfte sofort in
   dieselbe Richtung neu eroeffnen. Genau die Open->Instant-Close-Kaskade, gegen
   die _SQUEEZE_REENTRY_COOLDOWN_S am 27.07. gebaut wurde.
   Neu `_check_brk_close_cooldown` im _pos_loop. ⚠ Bewusst DIESELBEN Felder wie
   Slot 1: die Sperre ist eine Aussage ueber den MARKT ("in diese Richtung
   gerade nicht"), nicht ueber einen Slot.

GEPRUEFT UND SAUBER in diesem Durchgang:
  - core/trailing.py hat KEINE Klassen-Variablen und keine veraenderlichen
    Modul-Globalen -> die zwei TrailingManager-Instanzen sind vollstaendig
    unabhaengig. Das war die groesste offene Sorge.
  - _check_close_notify arbeitet ueber history.trade_by_ticket, also DB-basiert
    und slot-unabhaengig.

⚠ WEITER OFFEN, bewusst nicht angefasst: `set_sltp()` wirkt nur auf Slot 1 (die
SL/TP-Felder koennen eine BRK-Position nicht anpassen) - das ist eine
UI-Entscheidung, welches Feld zu welchem Slot gehoert, und braucht eine Vorgabe
statt eines stillen Fixes. Ebenso `_check_auto_m15`, das `self.trader.open_long`
VOR dem `_open`-Aufruf bindet und damit `_slot()` umgeht (funktioniert derzeit
nur, weil beide dasselbe liefern).

91 Tests gruen, Pipeline inkl. der neuen Stufe E gruen, Deploy verifiziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:54:20 +02:00
Axel HocksandClaude Opus 5 2b498fc20e Pipeline Stufe E: Slot-Trennung und Attribut-Reihenfolge (tools/check_slots.py)
User: "Uebernehme die Logikpruefung auf allen Slots in die Deployment pipeline" -
nach dem Ausfall, bei dem der Serverstart komplett abbrach und zwei Minuten lang
kein Close moeglich war.

ZWEI FEHLERKLASSEN, beide binnen zwei Tagen real aufgetreten, beide von KEINER
bestehenden Stufe gefangen (py_compile, ruff F821, ty, pytest: alle gruen):

(A) ATTRIBUT VOR SEINER ZUWEISUNG. `self.trader_brk.history = self.history`
    stand in `__init__` VOR `self.trader_brk = TradeManager(...)`.
    AttributeError im Konstruktor -> Serverstart brach ab -> "Netzwerkfehler" am
    Close-Knopf. Syntaktisch korrekt, und kein Test instanziiert die Engine (sie
    braucht MT5). Gefunden hat es erst deploy.py Schritt 2 - also NACH dem Kill
    des laufenden Servers. Derselbe Fehler am Vortag mit `_margin_brk` vor
    `_load_runtime_state()`, dort sogar still.
    Die Pruefung sammelt je `self.X` die ZEILE der ersten Zuweisung und meldet
    jede Benutzung davor.

(B) SLOT-VERWECHSLUNG. BRK-Pfade (_check_auto_squeeze, _manage_squeeze_pending,
    _check_pending_fill) duerfen den SLOT-ZUSTAND von `self.trader` nicht
    anfassen (close/snapshot/open_*/set_open_context/refresh). ⚠ Bewusst eine
    WEISSE Liste der Pfade - eine schwarze wuerde jede neue Funktion still
    durchlassen. `pending_orders`/`cancel_pending`/`place_stop` sind ausdruecklich
    ERLAUBT: magic-basierte Broker-Abfragen ohne Slot-Zustand (geprueft).
    Dazu die Invariante, dass `TradingEngine.close` beide Slots erwaehnen muss -
    sonst waere eine BRK-Position per Dashboard nicht schliessbar.

DREI RICHTUNGEN VERIFIZIERT: sauber -> gruen; Reihenfolge-Fehler zurueckgebaut ->
"self.trader_brk benutzt, aber erst in Zeile 270 zugewiesen"; Slot-Verwechslung
zurueckgebaut -> "self.trader.close im BRK-Pfad". Danach wieder gruen.

Statisch (AST), kein MT5, Millisekunden. Werkzeugfehler gilt NICHT als sauber.
Laeuft ueber check_nfalle.py im pre-commit-Hook mit.

⚠ Was diese Stufe NICHT kann: ein Startfehler AUSSERHALB von __init__. Dafuer
bliebe ein echter Rauchtest mit gestubbtem MT5 - der ist nicht gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:47:28 +02:00
Axel HocksandClaude Opus 5 a652223a05 Slot-Pruefung: close() traf nur Slot 1, squeeze_reverse den falschen
User: "ueberpruefe die Trade Logiken genau auf weitere Fehler oder Widersprueche,
besonders bezogen auf die 2 Slots". Systematisch alle `self.trader.`-Zugriffe in
engine.py durchgegangen (24 Stellen, nach Funktion gruppiert). VIER Widersprueche,
alle aus dem Umbau vom 19.08.:

① BEHOBEN - `engine.close()` schloss NUR Slot 1. Hielt der BRK-Slot eine Position
   und Slot 1 war leer, tat der CLOSE-Knopf im Dashboard NICHTS. Das ist die
   gefaehrlichste Variante der Luecke: nicht eine Zahl stimmt nicht, sondern eine
   SCHUTZHANDLUNG greift ins Leere. Jetzt ueber beide Slots, Slot 1 zuerst
   (wer CLOSE drueckt, meint meist die selbst geoeffnete Position), Fehler
   gesammelt gemeldet.

③ BEHOBEN - `squeeze_reverse` rief `self.trader.close()`, traf also die MANUELLE
   Position statt der BRK-Position, die der Reverse eigentlich drehen soll.
   Dormant (auto_squeeze_reverse=false), aber falsch verdrahtet.

② GEMELDET, NICHT geaendert - `set_sltp()` wirkt nur auf Slot 1. Die SL/TP-Felder
   der Trade-Leiste koennen eine BRK-Position nicht anpassen. Das ist eine
   UI-Frage (welches Feld gehoert zu welchem Slot?) und braucht eine Entscheidung,
   keinen stillen Fix.

④ GEMELDET - `_check_auto_m15` bindet `self.trader.open_long` VOR dem Aufruf von
   `_open`, umgeht also `_slot(source)`. Funktioniert derzeit nur, weil
   `_slot("auto_m15")` ohnehin `self.trader` liefert. Fragil: bekaeme M15 je
   einen eigenen Slot, waere es still falsch.

GEPRUEFT UND KORREKT: `_manage_squeeze_pending` (pending_orders/cancel_pending/
place_stop sind magic-basierte BROKER-Abfragen, kein Slot-Zustand),
`_broker_offset_s` (Zeitzone), `snapshot()` (position / position_brk getrennt),
Circuit-Breaker (summiert und schliesst beide).

⚠ Beim Bau eine Einrueckung zerschossen - Stufe A der Pipeline hat es sofort
gefangen (IndentationError + ty invalid-syntax + pytest). Genau dafuer ist sie da.

91 Tests gruen, Deploy verifiziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:37:11 +02:00
Axel HocksandClaude Opus 5 c33227664c Trade-Leiste: Auto-Close-Feld entfernt (war doppelt)
User-Wunsch. Der Schalter existierte zweimal: in der Trade-Leiste und seit dem
19.08. als Knopf "S/R" in der Aktionsleiste. Die Aktionsleisten-Variante ist die
brauchbarere - die Trade-Leiste erscheint NUR bei offener Position, man konnte
den Auto-Close dort also gar nicht VOR einem Trade setzen. Genau deshalb war der
zweite Knopf am 19.08. dazugekommen.

Entfernt: das `<span class="tb-field">` mit `#srclose-btn`, der Render-Block, der
seinen Zustand schrieb, und der onclick-Handler. `srAuto` bleibt - es speist
weiter den Knopf `btn-sr` und die Hinweistexte.

⚠ Die beiden JS-Zugriffe haetten dank Auffang-`$` keinen Absturz erzeugt, aber
sie waeren toter Code gewesen, der je ID eine Konsolen-Warnung ausloest.
Deshalb mitentfernt statt liegengelassen: 0 Treffer in app.js UND index.html.

Backend, Endpoint /api/srclose und der Zustand `auto_sr_close` unveraendert.

Reine Frontend-Aenderung (v=193), kein Neustart. node --check und die
Render-Probe (Stufe B2) gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:33:49 +02:00
Axel HocksandClaude Opus 5 c081bdc734 SL/TP nicht mehr am S/R verankert + Squeeze-Market-Fallback auf den BRK-Slot
User: "SL/TP sollte nicht am S/R verankert werden sondern immer dynamisch
berechnet werden" - nach dem Fund, dass Trades wiederholt am Level schlossen.

(1) PIVOT-ANKER DES INITIAL-SL ENTFERNT (`_SL_PIVOT_ANKER = False`).
`_calc_sl_tp` legte den SL an den naechsten M15-Pivot (LONG: pivot_low − Puffer,
SHORT: pivot_high + Puffer) und klemmte ihn erst DANACH auf 1,8–2,2×ATR. Der
Stop lag damit fuer einen LONG direkt unter der UNTERSTUETZUNG. Ueber 69
geloggte Orders war der Pivot in 4 % massgeblich (59 % gekappt, 36 % geweitet) -
und in genau diesen Faellen stand der Stop auf dem Level, an dem der Markt
ohnehin am haeufigsten durchwickt.
⚠ Der TP erbte das INDIREKT: er ist `2,0 × SL-Distanz`, skalierte also mit dem
Pivot-Abstand. Beide sind jetzt rein ATR-dynamisch (Mitte des Bandes = 2,0×ATR).

VORHER GEMESSEN (`backtest_sl_pivot.py`, 60k M5, 2 Halbjahre, gleiche
Einstiege, NUR die SL-Methode variiert, kanonischer Exit, Echtkosten):
    PIVOT  H1 -0,054 / H2 -0,040   PF 0,93 / 0,95
    FIX    H1 -0,040 / H2 +0,004   PF 0,95 / 1,01
FIX ist in BEIDEN Haelften besser (+0,014 / +0,043 R), der Worst-Case wird nicht
groesser - die vorab fixierte Regel ist erfuellt.
⚠ EHRLICH: beide KI enthalten die Null, es ist KEIN belegter Ertragsgewinn. Der
Punkt ist, dass die Verankerung nichts nuetzt UND den Stop auf das Level legt.
Das bestaetigt `backtest_sl_method.py` ("gedeckelt sind alle Methoden
gleichwertig") auf dem heutigen Exit - dort war es nur nie als NACHTEIL sichtbar.
Zurueck: `_SL_PIVOT_ANKER = True`.

(2) LUECKE AUS DEM ZWEI-SLOT-UMBAU, vom Deploy-Schritt 5 aufgedeckt:
"Auto-Squeeze-Entry fehlgeschlagen: Position bereits offen!". `engine.open_long`
routete IMMER auf `self.trader` - der Market-Fallback des Squeeze lief also
weiter ueber Slot 1 und scheiterte, sobald ein manueller Trade lief. FLAT-Check
und Pending-Manager waren gestern umgehaengt, der BESTELLWEG nicht.
Neu `_slot(source)`: auto_squeeze -> trader_brk, alles andere -> trader. Auch
der Bot-Marker (`_bot_open_ticket`) holt das Ticket jetzt vom richtigen Slot.
⚠ Genau die Fehlerklasse von Deployment-Drift Fall 8 - ein Umbau, der den
Bestellweg aendert, muss ALLE Bestellwege mitnehmen.

91 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:32:21 +02:00
Axel HocksandClaude Opus 5 e01ecde3a3 Order-Knopf warnt sichtbar, wenn der Raum zum Ziel-Level fehlt
User: "und wieder am Widerstand geschlossen. Das ist kein Zufall mehr."

⚠⚠ ZUERST DER AUSSCHLUSS - im Exit gibt es KEINEN S/R-Anker:
  - S/R-Auto-Close ist seit 19.08. aus
  - `trail.set_sr(...)` uebergibt die Level zwar, aber `_sr_data` wird in
    core/trailing.py NIRGENDS benutzt (toter Parameter)
  - Trailing-Stop = Bestkurs ∓ 1,0xATR, TP = Entry ± 3,5xATR - beides reines ATR
Kein Codepfad kann an einem Level schliessen.

DIE URSACHE LIEGT AM EINSTIEG, und sie ist in der eigenen Telemetrie sichtbar
(ctx_dist_res_atr / ctx_dist_sup_atr, Abstand zum ZIEL-Level beim Eroeffnen):
   19.08 20:00 BUY  0,25xATR   -5,44
   19.08 20:05 BUY  0,29xATR   -4,20
   19.08 20:11 BUY  0,46xATR  -23,29
   19.08 20:59 SELL 0,52xATR   -4,47
   19.08 21:18 BUY -0,03xATR   -0,67   (Widerstand bereits ueberschritten)
FUENF von zwoelf Trades unter dem Gate 0,6, zusammen -38,07 EUR.
Der Kurs erreicht das Level nach wenigen Cent, dreht, und der Trail (1xATR
dahinter) nimmt mit. Der Exit SIEHT nach "am Widerstand" aus, weil der EINSTIEG
dort lag. Genau das misst entry_room_atr: OeR -0,119/-0,067 bei PF 0,42/0,66 -
79 % Trefferquote und trotzdem Verlust, weil der Gewinn am Level gedeckelt ist
und der Verlust bis zum Stop laeuft.

Warum es niemand sah: `entry_room` blockt nur die EMPFEHLUNG, manuelle Orders
laufen ungehindert (so gewollt, Uebersteuerungen liefen 68 % WR). Seit dem
Entfernen des Entry-Dialogs (11.08.) fehlte die Zahl im Moment des Klicks; sie
stand nur in Gate ③b - und das ist seit gestern im zugeklappten Akkordeon.

GEBAUT: der Order-Knopf selbst wird markiert (Umriss in Akzentfarbe, gedaempfte
Flaeche, Raum-Zahl fett), sobald `frei === false`. Live gegengeprueft: bei Raum
0,04 / 0,28 xATR sind beide Knoepfe gewarnt.
⚠ KEIN Block, KEINE Abfrage - sichtbar machen, nicht bevormunden.
⚠ Die Zahl wird NICHT neu gerechnet; `rm` liegt bereits vor. Ein zweiter
Rechenweg waere die Divergenz-Falle, die im Projekt dreimal zugeschlagen hat.
⚠ Der Knopf hat keine id, sondern data-side - deshalb ueber `closest()` statt
ueber eine ID (erster Versuch griff ins Leere).

Reine Frontend-Aenderung (v=192), kein Neustart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:25:33 +02:00
Axel HocksandClaude Opus 5 834bd0bba3 Header: eigene G/V-Box fuer den BRK-Slot, rechts neben dem ersten
User-Wunsch. Seit dem Zwei-Slot-Umbau vom 19.08. kann der Breakout-Autotrader
parallel zu manuellen und M15-Trades eine eigene Position halten - im Header war
davon nichts zu sehen. Neue Box "G/V · BRK" (#hdr-pnl-brk) direkt neben "G/V",
mit Ticket, Lots, Einstieg und Trailing-Zustand im Tooltip. Zeigt "—", wenn BRK
nichts haelt.

⚠ BEWUSST ZWEI BOXEN statt einer Summe: die Slots gehoeren verschiedenen
Populationen (Mensch +1,56 gegen autonom -4,71 EUR/Lot), und sie in EINEM Feld
zusammenzurechnen wuerde genau die Trennung verwischen, fuer die der zweite Slot
ueberhaupt gebaut wurde.

Die SUMME steht dort, wo der User sie angefragt hat: im TAG P/L. Geprueft statt
angenommen - `day_pl["open"]` summiert seit dem 19.08. bereits beide Slots
(engine.py:4537), es war also nichts nachzuruesten. Live gegengerechnet:
Slot 1 +4,18 / BRK leer / day_pl.open 4,18.

Die WHT-Behandlung ist identisch zur ersten Box (Abzug nur auf Gewinne) - eine
zweite Rechenart im selben Header waere eine Divergenz, die niemand erwartet.

Reine Frontend-Aenderung (v=191), kein Neustart. div 87/87 ausgeglichen, keine
doppelten IDs, node --check und die Render-Probe gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:14:26 +02:00
Axel HocksandClaude Opus 5 d87bda1461 FIX: setup-Nachtrag bei Pending-Fill scheiterte an einem Rennen
User: "dann sieh dir die Luecke an" (nach "DB-Nachtrag fehlgeschlagen" im Log,
20.08. 07:40:12, T=50371599).

URSACHE - ein Rennen zwischen zwei Pfaden: _check_pending_fill erkennt den Fill
aus trader_brk.snapshot(), die DB-ZEILE schreibt aber trader._refresh_locked ->
log_trade_open. War der noch nicht durch, traf das UPDATE keine Zeile und der
Nachtrag scheiterte STILL. Der Trade blieb setup=NULL und war damit von einem
manuellen nicht unterscheidbar - genau die Buchfuehrungs-Luecke, gegen die
tag_bot_trade ueberhaupt gebaut wurde (Deployment-Drift Fall 8), nur eine Ebene
tiefer. Folge: squeeze_entry_count blieb 0, der Trade fehlte in B4/B5.

BEHOBEN: gescheiterte Nachtraege landen in `_tag_nachtrag` und werden im
_pos_loop wiederholt, bis die Zeile da ist - dasselbe Retry-Muster wie beim
Gewinn-Close (23.07.). Nach 60 Versuchen (~1 min) wird aufgegeben und LAUT
gemeldet: eine Zeile, die nach einer Minute nicht existiert, kommt nicht mehr,
und dann soll es nicht still bleiben.

T=50371599 nachgetragen (DB-Backup oil_widget_history.db.bak-2026-08-20).

 NEBENBEFUND, und zwar ein guter: derselbe Logausschnitt enthaelt
"🧷 BRK-Slot uebernimmt Pending-Fill T=50371599" - das ist der ERSTE
Live-Beleg, dass der Zwei-Slot-Umbau vom 19.08. funktioniert. Der BRK-Slot hat
die gefuellte Pending-Order korrekt uebernommen.

⚠ ZWEITER NEBENBEFUND, NICHT behoben (User-Entscheidung): die Order wurde mit
0,01 Lots platziert. Das ist die direkte Folge von margin_brk = 10 % auf eine
fast erschoepfte freie Margin - die Einstellung wirkt also, nur vermutlich
anders als gedacht. Dazu steht margin_pct in runtime_state auf 95, waehrend die
ini 40 sagt (runtime gewinnt). Beides gemeldet, nichts geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:12:15 +02:00
Axel HocksandClaude Opus 5 4ebc55c49b Trailing: ATR fest auf M5 (Drift behoben) + trail_start 0,3 -> 1,3
User: "ueberpruefe die trailing logik und passe ggf an", nach drei Trades in
Folge, die per nachgezogenem Stop schlossen. Beide Aenderungen auf Zustimmung.

(1) DEPLOYMENT-DRIFT: der Trail-ATR kam aus der WELLEN-Zeitebene, und die
    wechselt. Gemessen an 90 echten Aktivierungen im Log:
        M5   Ø ATR 0,1877  n=51   -> 1,00x wie validiert
        M15  Ø ATR 0,2586  n= 9   -> 1,38x
        M30  Ø ATR 0,4751  n=30   -> 2,53x
    In 43 % der Faelle lief der Trail also mit einem Abstand, der NIE gemessen
    wurde. `backtest_trailmult.py` misst mult=1,0 auf M5-Bars mit M5-ATR; auf
    M30 entspricht das effektiv ~2,5 in M5-Einheiten, und 2,5 ist dort KLAR
    schlechter gemessen (H1 ΣR -1174 gegen -73 bei 1,0).
    ⚠⚠ Am 31.07. wurde `_MULT_BY_TF` GENAU gegen diese Fehlerklasse auf
    durchgehend 1,0 geglaettet. Der Multiplikator war aber nie die Ursache - es
    ist der ATR. Die Variabilitaet kam durch die Hintertuer zurueck.
    `_atr_tf_override` bleibt unberuehrt: den setzt engine bewusst, das ist eine
    explizite Vorgabe und kein Automatismus. Zurueck: vier auskommentierte
    Zeilen in `_pick_tf` wieder aktivieren.

(2) trail_start 0,3 -> 1,3. `backtest_trail_start.py` (14.08.) zaehlt den Anteil
    "war im Plus, schloss im Minus": 0,3 -> 47,6 % / 38,2 %, bei 1,3 -> 0,0 % /
    0,5 %. ⚠ Der ERTRAG unterscheidet sich gepaart NICHT messbar - alle zwoelf
    KI enthalten die Null. Es ist also eine KOMFORT-Entscheidung, und sie ist
    gemessen gratis. Mechanik: der Trail sitzt mult×ATR (=1,0) hinter dem
    Bestkurs und erreicht den Einstand erst bei 1,0×ATR Gewinn; mit Start bei
    0,3 lag der Stop im Band dazwischen zwangslaeufig auf der VERLUSTSEITE.

⚠⚠ FOLGE FUER DIE BACKTESTS, ausdruecklich benannt: `LIVE` ist die GETEILTE
Quelle. Alle Skripte, die sie nutzen, rechnen ab jetzt mit trail_start 1,3 -
ihre dokumentierten Zahlen wurden mit 0,3 erzeugt und reproduzieren daher NICHT
mehr. Wer eine alte Zahl nachrechnen will, muss `LIVE.with_(trail_start=0.3)`
pinnen. Das ist der Preis der geteilten Quelle und zugleich ihr Zweck: Live und
Messung bewegen sich gemeinsam. Der veraltete Kommentar "start 0,3" in
exit_model.py wurde mitgezogen, damit die Begruendung nicht gegen die
Einstellung steht.

⚠ Am Verlust-Trade von heute frueh (-22,36) haette KEINE der beiden etwas
geaendert: er war nie im Plus und traf den regulaeren Initial-SL. Dort ist die
Schraube die Positionsgroesse, nicht der Exit.

91 Tests gruen, Deploy ueber tools/deploy.py --feld position_brk.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:01:20 +02:00
Axel HocksandClaude Opus 5 d3d613068c M15-Karte: Pruefkette als Akkordeon in drei Abschnitten
User-Wunsch. Die Karte war auf zehn Zeilen gewachsen und dominierte das
Dashboard; jetzt sind sie in drei aufklappbare Gruppen sortiert:

  ① - ④  Pruefkette                        (offen)   Bias · Kosten · Zone · Reichweite
  ⑤      Kontext - Motor · M5 · RSI        (zu)      Motor/Raum · M5-Zustand · RSI
  ⑥ - ⑦  Selbstmessung · Ausfuehrung · Veto (zu)      Track · Exec · Veto

Das Status-Banner bleibt IMMER sichtbar - es ist die eine Zeile, die eine
Handlungsaussage traegt, und es bestaetigt ausdruecklich auch das Nicht-Handeln.

⚠⚠ NATIVES <details>/<summary>, kein JS fuer das Klappen. Entscheidend ist, dass
die Elemente IM DOM bleiben: der Render schreibt weiter in alle zehn IDs, auch
wenn ein Abschnitt zugeklappt ist. Ein Container, der die Elemente ENTFERNT,
haette den Render abbrechen lassen - genau der Ausfall von gestern Abend, als
ein ReferenceError in renderM15 das halbe Dashboard auf "—" stehen liess.

JS macht nur EINES: den Auf-/Zu-Zustand in localStorage merken. Ohne das waere
jeder Reload ein Rueckschritt - und die Seite wird bei jedem ?v=-Bump neu
geladen. Faellt localStorage aus (privater Modus), greift der Default.

Verifiziert: 10 m15-Items unveraendert vorhanden, keine doppelten IDs,
div 86/86 und details 3/3 ausgeglichen, node --check gruen, Render-Probe
(Stufe B2) gruen. Reine Frontend-Aenderung (v=190), kein Neustart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 00:11:17 +02:00
Axel HocksandClaude Opus 5 5684589878 FIX: SL/TP-Feld rundete auf 2 Nachkommastellen - Stop verschob sich beim Speichern
User: "SL war auf 84,86 laut Dashboard" (nach dem Close von T=50360258).

ZWEI BEFUNDE, und der zweite ist der eigentliche:

(1) Die 84,86 gehoerten zum NAECHSTEN Trade. Der geschlossene T=50360258 hatte
    SL 84,776; 26 s spaeter lief bereits T=50360505 mit SL 84,863. Kein Fehler,
    nur Verwechslung durch die schnelle Folge.

(2) ABER dabei faellt ein echter Anzeigefehler auf: das SL/TP-Feld der
    Trade-Leiste formatierte mit `fmt(x, 2)`. WTI notiert DREISTELLIG - aus dem
    echten Stop 84,776 wurde die Anzeige 84,78.
    ⚠⚠ Das ist nicht kosmetisch: das Feld ist BESCHREIBBAR, und ein Enter darauf
    schickt den gerundeten Wert per /api/sltp an den Broker. Der Stop verschiebt
    sich also still um bis zu 0,5 Cent - bei einem Trail von 11 Cent (ATR_M5
    0,1104 in dieser Nacht) sind das 5 % der Distanz. Zusaetzlich schaltet
    /api/sltp das Trailing ab, der Nutzer wuerde also einen leicht falschen Stop
    festschreiben und die Nachfuehrung verlieren.

Behoben auf 3 Stellen. Gegengeprueft, dass es kein weiteres Preisfeld mit
`, 2)` gibt.

Reine Frontend-Aenderung (v=189), kein Neustart. node --check und die neue
Render-Probe (Stufe B2) gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 00:04:20 +02:00
Axel HocksandClaude Opus 5 f02fd43b39 Telegram: ALLE Trade-Opens und -Closes + Reichweiten-Waechter fuer den 2. Slot
(1) User-Vorgabe: "Alle Trade Closes und Opens sollen per Telegram gemeldet
werden".
 - close_notify_min_eur 50 -> 0, also jeder Close ohne Schwelle
   (Backup oil_widget_config.ini.bak-2026-08-19-tgopen)
 - neuer _check_open_notify: meldet jede Eroeffnung, ueber BEIDE Slots. Der
   BRK-Slot ist ausdruecklich dabei - ein autonomer Entry soll nicht unbemerkt
   bleiben, genau dafuer wurde der zweite Slot gebaut; die Meldung nennt den
   Slot mit.
 - _TG_ERLAUBT um "Trade eroeffnet" erweitert (das Gate ist EINE Filterstelle,
   nicht 17 Einzeleingriffe).
 ⚠ 1x je Ticket ueber _open_notify_gemeldet - ohne den Merker feuerte es im
   1-s-Takt weiter, solange die Position offen ist.
 ⚠ In der Startup-Schonfrist wird nur GEMERKT, nicht gemeldet: nach einem
   Neustart erkennt der Trader eine BESTEHENDE Position wieder, und das ist
   keine Eroeffnung.

(2) Reichweiten-Waechter (_check_slot_reichweite). Gemessener Befund: von den
Schutz-Checks ist NUR _check_circuit_breaker slot-faehig. _check_auto_close
(Notfall-Stop, haengt an 4 Ticket-Variablen), _check_sr_close, _check_adverse15
und _check_flip_close kennen nur Slot 1. Heute folgenlos, weil alle vier AUS
sind - aber wird einer eingeschaltet, waehrend eine BRK-Position laeuft, gilt er
stillschweigend nur fuer Slot 1, und im Dashboard saehe alles normal aus.
Dieselbe Klasse wie Deployment-Drift Fall 8: nicht die Strategie driftet,
sondern ihre REICHWEITE. Der Waechter macht das Loch LAUT (Log-Warnung 1x je
Ticket + Snapshot-Feld `slot_luecke`), bis die vier slot-faehig sind.

⚠ Die volle Parametrisierung der vier Checks steht AUS. _check_auto_close allein
haengt an vier Ticket-Variablen und ist der Notfall-Stop - das gehoert in eine
eigene Sitzung mit Tests, nicht ans Ende einer langen.

⚠ EIGENER FEHLER auf dem Weg: der erste Bauversuch lief per Heredoc und riss das
Telegram-Format-Literal an einem \n auseinander (SyntaxError). Das ist exakt die
im Projekt dokumentierte \n-Falle - "mehrzeilige Strings mit \n NIE per Heredoc
schreiben, den Edit-Weg nehmen". Ich habe die eigene Regel verletzt; engine.py
wurde per git checkout zurueckgesetzt und sauber ueber Edit neu gebaut.

Deploy ueber tools/deploy.py --feld position_brk, alle 5 Schritte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:23:01 +02:00
Axel HocksandClaude Opus 5 0fe51dea48 Pipeline: zwei neue Pruefstufen vor dem Commit (Typaritaet + JS-Render)
User: "baue alle und integriere in die pipeline vor dem commit". Beide Stufen
schliessen Luecken, die HEUTE real zugeschlagen haben.

A3) TYPPRUEFUNG (ty 0.0.73, Konfiguration in ty.toml)
Anlass: `paarweise(d)` wurde mit 1 von 2 Pflichtargumenten gerufen. py_compile
sah nichts (Syntax ok), ruff F821 auch nicht (der Name IST definiert), kein Test
deckte den Pfad ab - der Fehler schlug erst zur Laufzeit zu.
⚠ BEWUSST ENGES REGELSET: der volle ty-Lauf meldet 172 Befunde, davon 97
`unresolved-attribute` aus fehlenden MetaTrader5-Stubs. Eine Stufe mit
Dauer-Treffern wird ignoriert, und mit ihr die eine echte Meldung (die Lehre vom
07.08.). Aktiv sind nur die Aritaets-Regeln. `call-non-callable` und
`not-iterable` sind AUS - beide melden hier ausschliesslich Falsch-Positive aus
heterogenen dicts (`c["have"]()`, `"up" in c`); geprueft, nicht angenommen.
⚠ Der dokumentierte Einwand "Pruefumgebung != Laufumgebung" greift NICHT: ein
Typchecker fuehrt nichts aus, er kann also nicht divergieren. Er braucht auch
kein MT5.
⚠ Nebenbefund: die CLAUDE.md-Begruendung gegen mypy ("kaum Annotationen
vorhanden") ist veraltet - gemessen sind 305 von 443 Funktionen annotiert (69 %).

B2) RENDER-PROBE (tools/render_check.mjs gegen tests/fixtures/snapshot.json)
Anlass: `node --check` prueft nur SYNTAX. Der ReferenceError von heute Abend
(RSI-Zeile griff in renderM15(s) auf d.market zu) war syntaktisch einwandfrei
und brach im Browser den GESAMTEN Render ab - sechs leere Zeilen und eine leere
Breakout-Karte. Fuer Python gibt es ruff F821, fuer JS gab es nichts.
⚠ Laeuft gegen einen GESPEICHERTEN Snapshot, nicht gegen den laufenden Server -
der Hook darf nicht davon abhaengen, ob gerade ein Server laeuft.
⚠ KEIN ESLint: das braeuchte npm und node_modules, gegen die dokumentierte
Entscheidung ("kein npm, keine package.json").

BEIDE RICHTUNGEN VERIFIZIERT, je Stufe:
  A3  Aritaetsfehler eingebaut -> "FEHLER too-many-positional-arguments",
      1 Befund; zurueck -> gruen
  B2  d.market zurueckgebaut   -> " EXCEPTION: d is not defined",
      1 Befund; zurueck -> gruen
Beide haengen an tools/check_nfalle.py und laufen damit im pre-commit-Hook mit.
Fehlt das Werkzeug (ty nicht installiert, node nicht im PATH, Fixture fehlt),
wird die Stufe uebersprungen statt zu blockieren - eine frische Maschine darf am
Hook nicht haengenbleiben. Ein WERKZEUGFEHLER (Exit != 0/1) gilt dagegen
ausdruecklich NICHT als sauber.

ty in requirements-dev.txt gepinnt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:14:43 +02:00
Axel HocksandClaude Opus 5 95b22e2add FIX: Render brach ab - RSI-Zeile griff im falschen Scope zu (Dashboard kaputt)
User-Screenshot: sechs leere "—"-Zeilen in der M15-Karte unter Gate ④ und eine
komplett leere Breakout-Karte.

URSACHE, mein Fehler von heute Abend: `renderM15(s)` bekommt NUR `m15_setup`.
Meine RSI-Zeile griff aber auf `d.market.rsi_m15` zu - `d` existiert in diesem
Scope nicht. ReferenceError mitten im Render: alles ab der Fehlerstelle blieb
auf dem Initialwert "—", und die danach gerufenen Renderer (u.a. renderBrk)
liefen gar nicht mehr. Genau die Signatur im Screenshot.

⚠⚠ WARUM DIE PIPELINE ES DURCHGELASSEN HAT: `node --check` prueft nur SYNTAX.
Ein ReferenceError ist syntaktisch einwandfrei. Python hat dafuer ruff F821 -
fuer JS gab es nichts Vergleichbares. Das ist die Luecke, nicht ein
Einzelversehen: es ist der ZWEITE Fall derselben Klasse heute (vorhin `d5.m5`
statt `s.m5`, den hatte ich beim Bauen selbst bemerkt).

BEHOBEN: renderM15(s, snap) bekommt den vollen Snapshot mit, Aufrufer angepasst,
Zugriff auf ((snap||{}).market||{}).rsi_m15. Ein Kommentar an der Signatur haelt
fest, warum `d.` dort verboten ist.

NEU: tools/render_check.mjs - laesst renderM15 und renderBrk gegen ein
Minimal-DOM mit einem ECHTEN Snapshot laufen und meldet jede Exception.
Mutationsprobe bestanden: Fehler zurueckgebaut -> " d is not defined",
zurueck -> gruen. Alle vier Zeilen rendern wieder korrekt (RSI, M5-Kontext,
Gate ③b, BRK-Position).

v=188, damit der Browser das Update sicher zieht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:07:52 +02:00
Axel HocksandClaude Opus 5 621c82bab8 Walk-Forward auf dem Live-Trail: 1,0 gegen 1,5 stabil, gegen 0,8 unentschieden
Zweite der drei benannten offenen Messungen. Der Trail betrifft JEDEN Trade -
nach dem Walk-Forward-Befund vom selben Tag (Squeeze nur 4 von 8 Bloecken
positiv, obwohl "beidhaelftig positiv") war offen, ob LIVE.mult = 1,0 ueber die
Zeitachse haelt oder nur ueber zwei Haelften.

GEPAART gerechnet: alle Multiplikatoren auf DENSELBEN Einstiegen, verglichen
wird die Differenz je Trade. Der sequentielle Vergleich waere ungueltig - ein
anderer Exit laesst ANDERE Trades in den einen Slot, das ist ein Selektions-
und kein Exit-Effekt (die Falle vom 14.08. beim trail_start-Sweep).

ERGEBNIS ueber 8 Bloecke (~35 Tage je Block):
  1,5 gegen 1,0   Vorzeichen  - - + + - - - -    nur 2 von 8 fuer 1,5
  0,8 gegen 1,0   Vorzeichen  - + + + + - + -    5 von 8 fuer 0,8

 Gegen den WEITEREN Trail ist 1,0 stabil bestaetigt: 6 von 8 Bloecken, und die
beiden Gegenbloecke liegen beieinander (3 und 4). Die Entscheidung vom 31.07.
haelt also nicht nur ueber zwei Haelften, sondern ueber die Zeitachse.

⚠ Gegen den ENGEREN Trail ist es unentschieden - 5:3 fuer 0,8, aber das
Vorzeichen kippt dreimal, und ALLE Deltas liegen zwischen -0,026 und +0,097 R.
Damit ist die dokumentierte Aussage "enger ist monoton besser"
(backtest_trailmult.py) als Blocksicht NICHT bestaetigt: sie beschreibt zwei
Regime, keine Stabilitaet. Eine Umstellung auf 0,8 waere nicht gedeckt.

⚠ Effektgroesse: typisch ±0,03 R je Trade. Der Trail ist damit keine
Stellschraube mit Hebel, sondern eine, die man richtig stehen lassen sollte.
Keine Aenderung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 23:00:53 +02:00
Axel HocksandClaude Opus 5 e3e8a6b9fd RSI als Filter auf dem GEGATETEN Signal - die neue Achse traegt auch nicht
User: "neue achse" -> "messe". Das war die einzige nie gepruefte RSI-Population:
alle bisherigen Laeufe massen RSI als EIGENSTAENDIGEN Einstieg
(backtest_rsi_v2.py heute) oder als Konfluenz-Beitrag auf dem UNGEGATETEN
_build-Signal mit altem Exit (backtest_confluence.py). Hier laeuft er auf den
Signalen, die den VOLLEN Live-Gate-Stack passieren - 1344/2038 statt ~1700/2500.

AUFBAU: echte Gate-Pipeline aus backtest_entryroom_level.sammle (kein Nachbau,
inkl. set_entry_room - die Lehre vom 05.08.), RSI-Serie gegen calc_rsi
verifiziert, kanonischer Exit, Echtkosten, 2 Halbjahre, 95-%-KI, beide
Ausfuehrungen, 3 Schwellen als Nachbar-Robustheit.

ERGEBNIS: KEINE der 12 Zellen erfuellt die vorab fixierte Regel. Die Effekte
sind winzig - alle Deltas gegen die Basis liegen bei ±0,06 R, ausser in den
Extrem-Baendern, und die haben n=10 bis 50 (Rauschen).

⚠ Die Projekt-Hypothese "RSI GEGEN die Richtung = doppelter Edge" reproduziert
NICHT: am Markt +0,040 in H2 aber -0,021 in H1, an der Order genau umgekehrt
(+0,010 / -0,041). Vorzeichen kippt in beiden Ausfuehrungen. Der Pullback-Effekt
existiert, aber der RSI ist nicht das Werkzeug, ihn zu greifen - im Bot laeuft er
ueber die EMA-Distanz.

 EIN robuster Befund bleibt, und er ist die Bestaetigung einer vorhandenen
Regel: MIT RSI>70 an der ruhenden Order ist in H2 OeR -0,683 mit KI
[-1,041 .. -0,310], also signifikant NEGATIV. In eine Richtung einzusteigen,
waehrend der RSI dort schon extrem steht, ist messbar schaedlich - genau das,
was die Anti-Ueberdehnung (_STRETCH_MAX 3,5) bereits abfaengt. Kein neuer Filter
noetig, die Wirkung ist schon da.

30. verworfener Signal-Eingriff. RSI bleibt reine Anzeige.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 21:05:11 +02:00
Axel HocksandClaude Opus 5 3839fd5dc0 RSI-Zeile im Dashboard - reine Anzeige, bewusst ohne Ampel
User-Wunsch nach der Messung. `market.rsi_m15` stand bereits im Snapshot
(core/mt5data.py:246 ruft calc_rsi), es ist also eine reine Frontend-Aenderung
(v=187), kein Neustart, die offene Position unberuehrt.

⚠⚠ BEWUSST NEUTRAL und OHNE gruen/rot: die Lehrbuch-Lesart ist am selben Tag
gemessen und durchgefallen (backtest_rsi_v2.py: 24 Zellen ueber 80k M5-Bars und
2 Halbjahre, KEINE besteht, vier sind signifikant negativ; auch die Umkehrung
traegt standalone nicht). Eine Ampel wuerde hier systematisch falsch stupsen -
dieselbe Korrektur wie bei der Kerzen-Anatomie (Lehrbuch-Lesart invertiert) und
bei der Ueberdehnungs-Anzeige, die aus genau diesem Grund "Ueberdehnung" heisst
und nicht "Bounce".

Die Zeile NENNT die Zone (hoch / mittleres Band / tief), bewertet sie aber
nicht. Der Tooltip traegt die Messung samt Skriptnamen und den Hinweis, dass der
WIRKSAME Teil - der Pullback-Effekt - im Bot bereits ueber die EMA-Distanz
laeuft (Konfidenz-Bonus "tiefer Pullback" +15) und ueber die Ueberdehnung. RSI
waere dort eine zweite Verpackung derselben Aussage.

Kein Verdict-Gewicht, kein Trade-Trigger.

Verifiziert: div ausgeglichen, keine doppelten IDs, node --check gruen, v=187
ausgeliefert, Live-Wert 38,2 -> "mittleres Band".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 21:02:46 +02:00
Axel HocksandClaude Opus 5 de801e5f40 S/R-Auto-Close aus: ini nachgezogen und Waechter-Anker gedreht
User hat SR ueber das Dashboard abgeschaltet. Snapshot und runtime_state standen
danach auf false, die INI aber noch auf true - verhalten korrekt (runtime
gewinnt beim Start), aber genau die latente Inkonsistenz, durch die
auto_squeeze am 11.08. unbemerkt aus und auto_m15 am 19.08. unbemerkt AN war.
Ein geloeschtes runtime_state.json haette SR zurueckgeholt. Jetzt alle drei
konsistent false (Backup oil_widget_config.ini.bak-2026-08-19-srclose-aus).

Zusaetzlich der Config-Waechter-Anker gedreht: auto_sr_close validiert jetzt
gegen false statt true. Begruendung ist der Inversions-Befund vom selben Tag -
solange P(break) live rueckwaerts rankt (AUC 0,452, Klassen monoton invertiert),
ist der gegatete S/R-Close faktisch ein pauschaler, und der ist 2x gemessen und
verworfen. Ein Wiedereinschalten ist damit eine Abweichung von der Messung und
soll auffallen.

⚠ Die P(break)-Anzeigen (Chart-Linien, #pos-srhint, stop_approach,
Copilot-Kontext) bleiben aktiv und tragen dieselbe Inversion - sie sind Kontext,
kein Urteil. Das Live-Tracking laeuft weiter, damit ein Neubau eine Messgrundlage
hat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:58:05 +02:00
Axel HocksandClaude Opus 5 a7a024aa20 BEFUND: P(break) ist live INVERTIERT - und steuert per S/R-Auto-Close echtes Geld
Die faellige Messung ist entscheidbar geworden (n=530 entkoppelt gegen Latte 350).

AUC live 0,452, 95-%-KI [0,405 .. 0,504]. Die Messlatte aus dem Nachtrainieren
vom 31.07. war 0,654 - sie liegt weit ausserhalb des Intervalls.

Die Klassentabelle zeigt eine MONOTONE UMKEHRUNG: die Klasse 0-19 (Modell sagt
8,3 % Bruch) bricht real zu 45,2 %, die Klasse 65-100 (sagt 72,5 %) nur zu
37,9 %. Das ist kein Kalibrierungsfehler mehr - das Modell rankt rueckwaerts.

OPERATIV BRISANT: die Entwarnung in CLAUDE.md ("kein Notfall, auto_sr_close ist
aus seit 06.08.") ist STALE - er wurde am 11.08. wieder eingeschaltet. Das Gate
feuert bei p_break < 0,35 ("Level haelt, Gewinn mitnehmen"), und genau diese
Klassen haben die HOECHSTE reale Bruchrate. Damit ist der S/R-Auto-Close
faktisch ungegatet, und der pauschale S/R-Close ist 2x gemessen und verworfen.

Die Live-Bilanz (13 sr_close seit 11.08., +226,71 EUR) ist KEIN Gegenbeleg:
_check_sr_close schliesst konstruktiv nur im Plus, die Zahl ist per Bauart
positiv.

Ein dritter Fit waere nicht die Loesung: am 07.08. wurde die Niveau-Hypothese
gemessen und widerlegt (Roll-Achse faellt live durch, Regime-Merkmal ebenso).
Eine Inversion laesst sich durch Niveau-Verschiebung nicht beheben.

Nichts geschaltet - das ist eine User-Entscheidung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:56:09 +02:00
Axel HocksandClaude Opus 5 d7dc997eee RSI zum vierten Mal gemessen - faellt in allen 24 Zellen durch
User: "messe ihn nochmal". Kein blosses Wiederholen: die drei alten RSI-Laeufe
stiegen alle am Bar-Close zum MARKTPREIS ein. Genau diese Annahme hat am
05./06.08. Squeeze und Auto-Signal von negativ auf positiv gedreht (+0,32 bzw.
+0,61 R - mehr als alle Signal-Ideen zusammen). Fuer RSI war die
Ausfuehrungs-Achse nie geprueft.

AUFBAU: 80k M5, 2 Halbjahre, kanonischer Exit, Echtkosten, 95-%-Bootstrap.
2 Lesarten (Lehrbuch-Reversion und die Umkehrung) x 3 Schwellenpaare
(70/30, 75/25, 80/20) x 2 Ausfuehrungen (Markt / ruhende Order am Extrem mit
Fill bei Beruehrung) = 24 Zellen.

⚠ KEIN NACHBAU des Indikators: `calc_rsi` ist ein Wilder-RSI mit Rekursion ueber
die GANZE Reihe, ein Slice waere also nicht dasselbe. Die Serie wird inkrementell
gerechnet und an 200 Zufallsstichproben gegen die echte Funktion verifiziert;
bei Abweichung bricht das Skript ab. Groesste gemessene Abweichung: unter 1e-6.

ERGEBNIS: KEINE einzige Zelle erfuellt die vorab fixierte Regel (beidhaelftig
OeR > 0 UND PF > 1 UND KI ohne die Null UND Nachbarn gleichgerichtet). Vier
Zellen sind sogar beidseitig SIGNIFIKANT NEGATIV (KI komplett unter null):
REV 70/30 am Markt und MOM 75/25 an der Order.

⚠⚠ DIE AUSFUEHRUNGS-ACHSE HILFT HIER NICHT - und das war vorab so vorhergesagt.
Bei REV 75/25 hebt die ruhende Order zwar von -0,107/-0,014 auf +0,006/+0,075,
aber beide Intervalle enthalten weiter die Null, und die Nachbarn kippen
(80/20: H1 -0,181). Das bestaetigt den Mechanismus aus
`backtest_candle_fade2.py`: eine ruhende Order hilft bei MOMENTUM-Entries und
schadet bei REVERSIONS-Entries, weil eine Limit-Order am Extrem nur fuellt, wenn
sich die Bewegung weiter ausdehnt - also genau dann, wenn man falsch liegt.

⚠ Auch die im Projekt dokumentierte Umkehrung ("RSI gegen die Richtung =
doppelter Edge") traegt STANDALONE nicht: die MOM-Zeilen sind ueberwiegend
schlechter als die REV-Zeilen. Der Pullback-Effekt existiert, aber als
Konfidenz-Beitrag im gegateten Signal, nicht als eigenstaendiger Einstieg.

29. verworfener Signal-Eingriff. RSI bleibt draussen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:52:37 +02:00
Axel HocksandClaude Opus 5 33cc451e52 Globales Einsatz-Feld zurueck - es steuert die MANUELLEN Trades
User: "der einsatz wird immer noch nicht uebernommen, siehe aktueller trade",
danach Wahl von Variante A.

DIAGNOSE - kein Defekt, sondern eine Luecke, die ich selbst gerissen habe. Der
laufende Trade war setup=WAVE, also MANUELL; Slot 2 leer; und die Logzeile
"Einsatz fuer <pfad>" existierte kein einziges Mal. Die Pfad-Felder wirken
ausschliesslich auf die beiden AUTONOMEN Pfade - M15 ist aus, BRK hat seit dem
Einbau nicht gefeuert (Circuit-Breaker hat heute dreimal ausgeloest). Das Feld
hatte also nie eine Gelegenheit zu greifen.

Manuelle Trades laufen bewusst auf dem GLOBALEN Wert (der Mensch ist die
gemessen bessere Population, +1,56 gegen -4,71 EUR/Lot - seine Groesse gehoert
ihm). Nur: das globale Feld war am 19.08. auf Wunsch entfernt worden, und
danach kamen die Pfad-Felder dazu. Damit hatte ausgerechnet die Schraube, die
die eigenen Eroeffnungen steuert, keine UI mehr - erreichbar nur noch ueber die
ini plus Neustart. Das habe ich beim Bau der Pfad-Felder nicht mitgedacht.

Behoben: Feld "Einsatz global %" als drittes in derselben Zeile. Endpoint
/api/marginpct, set_margin_pct und die Persistenz existierten bereits - reine
Frontend-Aenderung (v=186), kein Neustart, die offene Position unberuehrt.

⚠ Semantik bewusst ANDERS als bei den Pfad-Feldern: dort heisst leer/0
ausdruecklich "globaler Wert", hier gibt es kein "aus" - ein Einsatz MUSS
gelten. Deshalb echte Untergrenze 1 statt der 0-Semantik.

Verifiziert: 45 gesetzt -> Snapshot -> persistiert -> zurueck auf 40; span
51/51 ausgeglichen, keine doppelten IDs, node --check gruen, v=186 ausgeliefert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:15:21 +02:00
Axel HocksandClaude Opus 5 5593f270cc Dashboard-Zeile fuer Slot 2 + Doku des Zwei-Slot-Umbaus
Die vom Breakout-Trader gehaltene Position ist jetzt sichtbar (#brk-pos in der
Breakout-Karte): Richtung, Lots, Einstieg, P&L - und vor allem der
Trailing-Zustand.

⚠ Der Trailing-Hinweis ist der wichtigste Teil der Zeile: steht er auf
"⚠ TRAILING AUS - nur Broker-SL!", laeuft der Trade in der gemessen
DURCHGEFALLENEN SL-only-Variante (backtest_brk_slonly.py: alle zehn
Konfidenzintervalle enthalten die Null, Trefferquote faellt 40 -> 21 %). Ohne
diese Anzeige waere das im Betrieb nicht bemerkbar - genau Deployment-Drift
Fall 8 (nicht die Strategie driftet, sondern ihre Beobachtbarkeit).

Richtung wird aus SL/TP abgeleitet statt ein weiteres Snapshot-Feld zu bauen -
place_stop setzt immer einen SL. Damit bleibt es eine reine Frontend-Aenderung
(v=185), kein Neustart noetig, die offene Position unberuehrt.

Verifiziert: v=185 wird ausgeliefert, div 85/85 ausgeglichen, keine doppelten
IDs, keine verwaisten JS-Referenzen, node --check gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:12:26 +02:00
Axel HocksandClaude Opus 5 a9a6c487d2 Circuit-Breaker und Tages-P&L summieren jetzt BEIDE Positions-Slots
Letzte offene Luecke des Zwei-Slot-Umbaus (User: "ja").

WARUM ES ZWINGEND IST: nach dem Umbau kann BRK parallel zu einer manuellen oder
M15-Position laufen. Haette der Tages-P&L weiter nur den ersten Slot gesehen,
waere eine offene BRK-Position unsichtbar geblieben - der Breaker griffe also
genau dann zu spaet, wenn zwei Positionen gleichzeitig laufen und das Risiko
doppelt ist. Bei 40 % Einsatz je Position sind 80 % der Margin gebunden.

GEAENDERT:
- snapshot(): day_pl["open"] summiert beide Slots
- _check_circuit_breaker(): dieselbe Summe als Ausloeser
- und der Breaker schliesst jetzt BEIDE Positionen - eine Notbremse, die nur
  die Haelfte schliesst, ist keine. Fehlschlag am zweiten Slot wird geloggt,
  nicht verschluckt.

91 Tests gruen, Deploy ueber tools/deploy.py --feld position_brk.

⚠ NEBENBEFUND beim Verifizieren, NICHT von dieser Aenderung verursacht: der
Circuit-Breaker steht auf 8 % (runtime_state cb_limit_pct = 8.0) und hat heute
dreimal ausgeloest (19:17, 20:03, 20:07). Der Tages-P&L liegt bei -178,89 EUR
gegen ein Limit von -55,89 EUR. Damit sind fuer heute KEINE autonomen Trades mehr
moeglich - auch BRK nicht. Manuelle Orders bleiben frei (so gebaut).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:10:31 +02:00
Axel HocksandClaude Opus 5 f04ae4d9d9 Fix: Einsatz je Pfad ueberlebte keinen Neustart (Reihenfolge-Fehler)
User: "Einsatz BRK % / Einsatz M15 % hat keine Auswirkung, die Eingabe bleibt
wirkungslos, in den Feldern erscheint 'global'".

URSACHE - mein Fehler beim Bau: die Default-Initialisierung
(self._margin_brk = 0.0) stand in Zeile 631, `_load_runtime_state()` laeuft aber
in Zeile 553. Der geladene Wert wurde also unmittelbar danach mit 0
ueberschrieben. Die Eingabe WIRKTE (POST kam an, Wert stand im Snapshot, wurde
auf Platte geschrieben) - sie war nach dem naechsten Neustart weg, und das Feld
zeigte wieder den Platzhalter "global". Real am 19.08.: BRK 10 / M15 85 gesetzt,
nach dem Deploy beide 0.

Behoben: Defaults stehen jetzt VOR dem Laden. Reihenfolge ist immer
Default setzen -> runtime_state laedt darueber.

⚠ EIGENER FEHLALARM beim Verifizieren, dokumentiert weil er lehrreich ist: mein
Persistenz-Test setzte 55/30, und nach dem Neustart standen 85/10 - ich habe das
als "VERLOREN" und sogar als Vertauschung gelesen. Die Logzeitstempel zeigen
etwas anderes: um 20:06:04 und 20:06:06 hat der Browser des Users zwei weitere
POSTs geschickt (85/30, dann 85/10), waehrend mein Test lief. Persistiert wurde
also korrekt der ZULETZT gesetzte Wert. Lehre: bei einer Live-Verifikation gegen
ein System, das der Nutzer gleichzeitig bedient, gehoert die Logspur mitgelesen
- sonst hält man fremde Eingaben fuer einen Defekt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:07:33 +02:00
Axel HocksandClaude Opus 5 9b5b20e713 BRK bekommt einen EIGENEN Positions-Slot - unabhaengig von manuell und M15
User-Vorgabe: "der brk trade soll komplett unabhaengig von m15 oder manuellen
trades laufen". Entwurf: docs/brk-eigener-slot.md

DER BEFUND, DER DEN UMBAU KLEIN MACHT: TrailingManager.__init__ nimmt bereits
SEINEN Trader entgegen und liest ausschliesslich ueber dessen snapshot() - es
haengt also nicht an einer globalen Position. Damit entfaellt der
29-Stellen-Umbau in engine.py. Stattdessen:

    engine.trader      - TradeManager()                 - trail      - manuell + M15
    engine.trader_brk  - TradeManager(nur_ticket=True)  - trail_brk  - nur BRK

Der validierte Pfad bleibt damit vollstaendig unangetastet - kein
Regressionsrisiko auf der gemessen besseren Population (+1,56 gegen -4,71/Lot).

DIE ZWEI KRITISCHEN STELLEN, beide gebaut:
(1) ADOPTION. TradeManager.refresh() greift per Default jede Position auf dem
    Symbol (gewollt: ein von Hand eroeffneter Trade bekommt so den Schutz-Stack).
    Mit zwei Managern wuerden sich BEIDE dieselbe Position schnappen. Neu:
    `nur_ticket=True` sucht sich nichts, und der adoptierende Manager bekommt
    ueber `fremde_tickets` eine Sperrliste (BRK-Ticket + liegende Pendings).
(2) DER FILL. Eine ruhende Order fuellt IM BROKER; der ticket-gebundene Slot
    kann sie nicht finden. Neu `TradeManager.bind(ticket, sym)`, aufgerufen aus
    _check_pending_fill - es sieht direkt am Broker nach, welches der liegenden
    Tickets zu einer Position geworden ist.

WEITER GEAENDERT: _check_auto_squeeze und _manage_squeeze_pending lesen den
EIGENEN Slot (eine manuelle oder M15-Position storniert die Pendings nicht mehr
- real am 19.08. waren es 5 Fenster mit zusammen ~2 min am Markt, 3 davon vom
M15-Trader); trail_brk wird in _price_loop mit Preisen versorgt (ohne das liefe
BRK in der gemessen DURCHGEFALLENEN SL-only-Variante); Snapshot-Feld
`position_brk` macht den zweiten Slot sichtbar - ohne das waere es
Deployment-Drift Fall 8 in neuer Form (nicht die Strategie driftet, sondern
ihre Beobachtbarkeit).

TESTS: 91 gruen. tests/test_pending_fill.py auf den BRK-Slot umgestellt - die
Aussagen bleiben unveraendert (fremde Quelle wird NICHT getaggt, derselbe Fill
zaehlt nur einmal), nur der Slot ist ein anderer. Die Tests wurden NICHT
abgeschwaecht; sie sichern weiter Deployment-Drift Fall 8.

LIVE VERIFIZIERT: Slot 1 fuehrt die offene Position (T=50349215) unveraendert
weiter, Slot 2 ist leer und wartet auf einen Squeeze. Deploy ueber
tools/deploy.py --feld position_brk, alle 5 Schritte.

⚠ OFFEN und bewusst NICHT in diesem Zug: Circuit-Breaker und Tages-P&L summieren
noch nicht BEIDE Slots, und die Dashboard-Zeile fuer den zweiten Slot fehlt. Mit
zwei Positionen sind bei 40 % je Position 80 % der Margin gebunden - der Breaker
(aktuell AUS) waere dann keine Kuer mehr.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 20:03:45 +02:00
Axel HocksandClaude Opus 5 815b6a77b8 Entwurf: BRK mit eigenem Positions-Slot (docs/brk-eigener-slot.md)
User: "der brk trade soll komplett unabhaengig von m15 oder manuellen trades
laufen". Der Entwurf ist am echten Code verifiziert, aber NICHT gebaut -
Umsetzung gehoert in eine eigene Sitzung mit flachem Konto.

DER ENTSCHEIDENDE BEFUND macht den Umbau viel kleiner als gedacht:
TrailingManager.__init__ nimmt BEREITS einen Trader entgegen (trailing.py:146)
und liest ausschliesslich ueber self.trader.snapshot(). Es haengt also nicht an
einer globalen Position, sondern an SEINEM Trader. Damit ist die Loesung ein
ZWEITER, ticket-gebundener TradeManager fuer BRK samt eigenem Trailing - statt
29 Stellen in engine.py umzubauen. Der validierte Pfad (manuell + M15) bleibt
dabei vollstaendig unangetastet, also kein Regressionsrisiko auf der gemessen
besseren Population.

DER KRITISCHE PUNKT ist die Adoption: TradeManager.refresh() greift heute jede
Position auf dem Symbol (positions_get(symbol=sym) mit Fallback auf alle). Mit
zwei Managern wuerden sich beide dieselbe Position schnappen. Der BRK-Manager
muss deshalb STRIKT ticket-gebunden sein - das ist die eine Aenderung, an der
der ganze Entwurf haengt.

Dokumentiert sind ausserdem die sieben Bauschritte in Reihenfolge, vier
Vorbedingungen (flaches Konto, RETAIL_HEDGING bestaetigt, doppeltes Risiko und
damit die Breaker-Frage, Margin-Semantik des Feldes "Einsatz je Pfad") und die
Erfolgskontrolle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:54:08 +02:00
Axel HocksandClaude Opus 5 5f4d66bcaf Doku: auto_m15 aus, und die Messung die den kleinen Umbau ausschliesst
Zwei Eintraege. (1) Warum kein BRK-Trade zustande kam: fuenf Pending-Fenster,
zusammen rund 2 Minuten am Markt, drei davon vom M15-Trader storniert - einmal
in derselben Sekunde. (2) Die Messung, ob BRK ohne Trailing laufen koennte
(backtest_brk_slonly.py): keine der fuenf Varianten erfuellt die vorab fixierte
Regel, alle zehn KI enthalten die Null.

Festgehalten sind ausdruecklich auch die beiden Grenzen: die Kontrolle
reproduziert NICHT (Absolutwerte unbrauchbar, nur der interne Vergleich zaehlt),
und das scheinbar bessere SL-only ist ein Varianz-Befund (WR 40 -> 21 %,
KI-Breite vervierfacht).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:51:43 +02:00
Axel HocksandClaude Opus 5 3e4a181c00 Messung: was bleibt vom BRK-Edge ohne Trailing? Ergebnis: kleiner Umbau faellt aus
User-Wunsch "BRK soll auch eroeffnen wenn M15 aktiv ist" + Entscheidung fuer
Variante 1+3 (erst messen, dann grosser Umbau in eigener Sitzung).

WARUM DIESE MESSUNG DIE BAUWEISE ENTSCHEIDET. Der KLEINE Umbau (Pendings nicht
mehr stornieren, open_* nicht mehr bei self.ticket abweisen) waere an einem
Abend gemacht - aber der zweite Trade haette dann nur den Broker-SL. `trader`
haelt EIN Ticket, und Trailing, Breakeven, Time-Stop, Notfall-Stop und
S/R-Close haengen alle daran (29 Stellen in engine.py). Die dokumentierten
Squeeze-Zahlen sind MIT dem kanonischen Exit gemessen; SL-only ist eine andere,
nie gemessene Konfiguration - Deployment-Drift per Konstruktion.

AUFBAU. Echte core.squeeze_scan-Regel, LIVE-Parameter (⚠ ATR-Floor 0,06, nicht
der Modul-Default 0,12), ruhende Stop-Order mit Fill bei BERUEHRUNG, Echtkosten,
80k M5, 2 Halbjahre, 95-%-Bootstrap, feste GETEILTE Einstiegsliste (alle
Varianten auf DENSELBEN Trades - sonst vergleicht man Populationen statt Exits).
⚠ KEINE Exit-Kopie: SL-only entsteht aus LIVE.with_(trail_start=999, be=999) -
der Trade bleibt in Phase "Init" und verlaesst sie nur ueber SL oder max_hold.
Es laeuft derselbe kanonische Code. Eine eigene Schleife waere das fuenfte
Exit-Modell gewesen.

ERGEBNIS (H1 / H2, OeR):
  A) kanonisch (heute)   -0,145 / +0,036    PF 0,76 / 1,07   WR 40 / 44 %
  B) SL only             -0,132 / +0,464    PF 0,92 / 1,27   WR 21 / 19 %
  C) SL + Time-Stop      -0,157 / +0,138    PF 0,87 / 1,12
  D) SL + TP             -0,188 / +0,073    PF 0,86 / 1,06
  E) SL + Time + TP      -0,212 / +0,064    PF 0,81 / 1,06

KEINE Variante erfuellt die vorab fixierte Regel (beidhaelftig OeR > 0 UND
PF > 1 UND 95-%-KI ohne die Null). H1 ist durchgehend negativ, und ALLE zehn
Intervalle enthalten die Null. Die vorab fixierte Antwort lautet damit:
GROSSER Umbau, nicht kleiner. Das deckt sich mit der Entscheidung des Users.

⚠⚠ GRENZE, die nicht ueberspielt werden darf: die KONTROLLE reproduziert NICHT.
Variante A liefert -0,145/+0,036, dokumentiert sind +0,124/+0,292
(backtest_squeeze_touchfill.py), und meine Einstiegszahl ist 362/559 gegen
1092/1807. Meine Auswahl ist also deutlich strenger. Damit sind die
ABSOLUTWERTE unbrauchbar; belastbar ist allein der INTERNE Vergleich, weil alle
Varianten auf derselben Entry-Liste laufen und sich nur im Exit unterscheiden.
Derselbe Vorbehalt wie am 13.08. bei backtest_squeeze_srclose2.py.

⚠⚠ UND DER INTERNE VERGLEICH IST KONTRAINTUITIV: SL-only sieht im OeR NICHT
schlechter aus (H1 -0,132 gegen -0,145, H2 +0,464 gegen +0,036). Das ist aber
kein Argument fuer den kleinen Umbau, sondern ein Varianz-Befund:
  - Trefferquote faellt 40 -> 21 % bzw. 44 -> 19 %. Vier von fuenf Trades laufen
    in den vollen -2R-Stop.
  - Die KI-Breite explodiert: [-0,108 .. +1,115] gegen [-0,081 .. +0,148] beim
    kanonischen Exit - rund das Vierfache.
Der Ertrag haengt an wenigen sehr langen Laeufern (max_hold 200 Bars = 16,7 h
ohne jede Absicherung). Unter 40-%-Margin-Sizing ist "81 % der Trades verlieren
volle 2R" eine ganz andere Risikoklasse als die gemessene - und statistisch
nicht von null zu unterscheiden.

FAZIT: nichts gebaut, nichts umgeschaltet. Der grosse Umbau (Trailing je Ticket)
bleibt der Weg, und er gehoert in eine eigene Sitzung mit FLACHEM Konto - ein
halb fertiger Ticket-Umbau laesst den Schutz-Stack an der falschen der beiden
Positionen haengen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:48:35 +02:00
Axel HocksandClaude Opus 5 a07ad942c1 Gesamtpruefung: drei echte Fehler behoben, alle drei aus meinem eigenen Code
Dritter vollstaendiger Durchlauf nach docs/review-prompt.md (nach 02.08. und
11.08.). Bemerkenswert: alle drei Funde stammen aus Aenderungen der letzten zwei
Tage, und alle drei sind DIESELBE Klasse - ein vorhandenes Muster nicht kopiert,
sondern ein eigenes erfunden.

FUND 1 (kritisch) - DER CONFIG-WAECHTER WAR TOT.
Mein CONFIG_DEPS-Eintrag fuer auto_m15 vom 19.08. trug das Feld "soll", die
anderen 15 Eintraege tragen "validated". config_drift() lief in einen KeyError
und warf - damit meldeten ALLE 16 Anker nichts mehr, seit gestern. Der Waechter,
der die auto_m15-Abweichung haette melden sollen, war durch genau diesen
Eintrag erledigt.
Behoben: Feldname angeglichen UND config_drift gehaertet - ein defekter Eintrag
wird jetzt uebersprungen und als eigener Befund GEMELDET statt den ganzen
Waechter zu toeten. Ein Waechter, der still stirbt, ist schlimmer als keiner
(dieselbe Klasse wie der ruff-Exit-2-Fall vom 07.08.).
Der Waechter meldet seitdem wieder: margin_buffer_pct 40 gegen 95,
auto_m15 true gegen false, auto_squeeze true gegen false - alle drei sind
dokumentierte User-Entscheidungen, aber sie waren unsichtbar geworden.

FUND 2 (Geld) - DER EINSATZ JE PFAD WAR FUER BRK WIRKUNGSLOS.
engine._open setzt den Einsatz je Pfad - aber _manage_squeeze_pending legt
ruhende Stop-Orders ueber trader.place_stop -> calc_lots, also NICHT ueber
_open. Gemessen fuellen 7 von 8 BRK-Trades per ruhender Order (seit dem
Pending-Umbau 05.08.). Das Feld haette also genau an der Stelle nicht gegriffen,
fuer die es gebaut wurde - und das faellt im Betrieb nur auf, wenn jemand die
Lots nachrechnet.

FUND 3 (Geld, Race) - GLOBALE MUTATION UEBER EINE LOCK-GRENZE.
Der erste Entwurf setzte config.MARGIN_BUFFER temporaer. Der Global wirkt
prozessweit, und zwischen dem Setzen in _open und dem mt5_lock in trader._send
liegt ein Fenster von bis zu 15 s (Lock-Timeout). Eine gleichzeitige MANUELLE
Order haette darin mit dem Prozentsatz des AUTONOMEN Pfads gesized.

FUND 2 und 3 gemeinsam behoben: calc_lots bekommt einen EXPLIZITEN Parameter
buffer_pct (Default None = global), durchgereicht ueber _send/_send_locked/
open_long/open_short/place_stop. Keine Mutation mehr, und beide Bestellwege
tragen denselben Wert.

TESTS - und eine Luecke in meinem eigenen Test, die erst die Mutationsprobe zeigte:
tests/test_buffer_pct.py, 6 Tests. Die erste Fassung bildete die Regel NACH
(_buf) statt die echte Funktion zu pruefen - die Mutation "calc_lots ignoriert
den Parameter wieder" lief damit GRUEN durch. Das ist die dokumentierte
Nachbau-Falle, diesmal in einem TEST. Ergaenzt um eine AST-Pruefung, dass
calc_lots den Parameter im Rumpf wirklich benutzt. Beide Mutationen werden jetzt
gefangen (Parameter aus place_stop entfernt -> rot; calc_lots ignoriert ihn ->
rot).

OHNE BEFUND (geprueft, sauber): check_nfalle, ruff F821, 91 Tests, node --check;
100 JS-Zugriffe gegen 124 HTML-IDs -> 0 fehlend (die 4 gemeldeten waren
Falsch-Positive meiner Regex: zwei stehen in Kommentaren, raum-* wird dynamisch
als $("raum-" + st) gebaut, tb-dur ueber getElementById); 2 Config-Schluessel
ohne Leser (beide [zones], dokumentiert schlafend); 14 Snapshot-Felder ohne
app.js-Leser (dokumentiert als Diagnose-Oberflaeche, deploy.py --feld braucht
sie); Snapshot-Median 15,7 ms bei p90 25,7 ms - unveraendert zum 11.08. und weit
unter dem 1-s-Budget, keine Massnahme.

TELEMETRIE-PULS: alle 7 Logger schreiben. rec_outcomes steht bei 72 Zeilen -
beim Review am 11.08. stand es auf "hat NIE geschrieben", der Fix vom 12.08. hat
also gewirkt.

DIVERGENZ-WAECHTER: A) WARTEN +16,6 Pp ueber der Erwartung (bekannt, wird von
den Live-only-Gates getragen); D) mom3 -0,55 Sigma - knapp ueber der bewusst
tiefen 0,5-Sigma-Schwelle, beobachten.

⚠ NICHT ANGEFASST (User-Entscheidungen, nur berichtet): auto_m15 laeuft live
ueber runtime_state.json gegen die ini; Circuit Breaker aus (cb_limit_pct 0
gegen ini 8); BRK an trotz gefallener B5-Regel.

Deploy ueber tools/deploy.py --feld margin_brk, alle 5 Schritte gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:38:56 +02:00
Axel HocksandClaude Opus 5 027267063d Einsatz-je-Pfad-Feld war nicht bedienbar - auf das bewaehrte Muster umgebaut
User: "Einsatz je Pfad kann ich nichts eingeben".

URSACHE - mein erster Entwurf hat ein EIGENES Markup erfunden, statt das zu
nehmen, das im Projekt nachweislich funktioniert. Zwei Fehler darin:

(1) KEIN `inputmode`. Alle funktionierenden Felder des Projekts (SL, TP,
    Gewinn-Close, Notfall-Close) tragen `inputmode="decimal"` - am Handy
    erscheint sonst keine brauchbare Zahlentastatur. Das allein macht ein Feld
    praktisch unbedienbar, obwohl es sichtbar und technisch "aktiv" ist.
(2) Die Inputs steckten in einem <b> innerhalb einer `.kv`-Zeile. `.kv` ist
    `display:flex; align-items:baseline` und fuer das Muster
    <span>Label</span><b>Wert</b> gebaut - also fuer TEXT, nicht fuer
    Formularelemente.

BEHOBEN: identisches Markup wie die Trade-Leiste (`.tb-row` > `.tb-field` mit
<label> ueber <input>), plus `inputmode="decimal"` und `placeholder="global"`
statt "BRK"/"M15" - das macht zugleich sichtbar, was LEER bedeutet.

Zusaetzlich den Render gehaertet, damit der 1-s-Snapshot die Eingabe nicht
fressen kann: Feld mit Fokus wird gar nicht angefasst, und geschrieben wird nur
bei tatsaechlicher Aenderung (eine Zuweisung setzt sonst auch bei identischem
Text die Cursorposition zurueck).

⚠ LEHRE, die ueber diesen Fall hinausgeht: es gab in derselben Datei vier
funktionierende Vorbilder, und ich habe keines davon angesehen, bevor ich ein
neues Muster erfunden habe. Beim Hinzufuegen eines Bedienelements gehoert das
vorhandene Muster kopiert - dieselbe Klasse wie die dokumentierte Regel, beim
Wiederverwenden eines Backtest-Kerns die Live-KONFIGURATION mitzukopieren.

Reine Frontend-Aenderung (HTML/CSS/JS + v=184) - kein Neustart noetig, statische
Dateien werden je Request frisch von der Platte gelesen. Verifiziert: Tags
ausgeglichen (div 84/84, span 49/49), keine doppelten IDs, node --check gruen,
beide Felder mit inputmode im ausgelieferten HTML, v=184 wird ausgeliefert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:22:56 +02:00
Axel Hocks 8bbc58f336 Doku: M5-Kontextzeile und die vorab fixierte Bedingung, die sie ersetzt hat 2026-08-19 19:17:55 +02:00
Axel HocksandClaude Opus 5 7915e171d0 M5-Kontextzeile in der M15-Karte statt einer eigenen M5-Setup-Karte
User fragte nach einer M1- oder M5-Setup-Karte und hat der hier gebauten
Variante zugestimmt: eine reine ZUSTANDS-Zeile, ohne Richtung und ohne Banner.

WARUM KEINE ZWEITE KARTE - und diesmal entscheidet eine frische Messung, nicht
eine Meinung. Die entkoppelte Selbstmessung der BESTEHENDEN Karte steht bei
n=342 (gruen + gerichtet, ab dem Hysterese-Stichtag 12.08.):
    30 min  53,5 %  KI [48,2 .. 58,8]   -> enthaelt 50 %
    60 min  49,3 %  KI [44,0 .. 54,5]   -> enthaelt 50 %, liegt DARUNTER
Am 12.08. war die Bedingung fuer ein Ja VORAB fixiert worden: ">=350 Faelle,
Trefferquote ueber 50 %, KI ohne die 50". Die Stichprobe ist jetzt da, die
Bedingung ist NICHT erfuellt. Das ist kein "noch zu wenig Daten" mehr.
Dazu die Messung vom 13.08.: als Handelsregel faellt die Karte durch
(backtest_m15_auto.py, OeR -0,162/-0,094, beide KI ohne Null, schlechter als
die HTF-Richtung UND schlechter als ihr eigenes Gegenteil).

M1 scheitert zusaetzlich an der Arithmetik: Spread/ATR Median 0,319 gegen 0,193
(M5) und 0,104 (M15). Feiner aufloesen macht die EINZIGE gemessene Staerke der
M15-Karte - die Kosten - monoton schlechter. Um 01:00 ist der Spread
1,051xATR_M1, also groesser als die mittlere Kerze; und die M1-Historie ist bei
80 Tagen gedeckelt, zwei Stichproben laegen im selben Regime.

GEBAUT ist deshalb Zustand ohne Urteil: Squeeze-Lage (armiert/Ausbruch/keine
Kompression + Box), Kosten in xATR_M5 mit den Schwellen aus
backtest_realcosts.py (Median 0,193, ab 0,32 Kostenfalle) und der ATR.
Der M5-RAUM wird bewusst NICHT wiederholt - Gate 3b rechnet ohnehin auf M5.

⚠ NUR ZUSAMMENGESETZT, nichts neu gerechnet: wave.squeeze und bid/ask/ATR_M5
stehen im Snapshot ohnehin. Ein zweiter Rechenweg war der Fehler des
Konsens-Pfeils (komplettes zweites _verdict im 5-s-Takt) und ist die Quelle
jeder Divergenz zwischen Karte und Chart.

⚠ Kein Verdict-Gewicht, kein Trade-Trigger, keine Farbampel - dieselbe
Zurueckhaltung wie bei der Kerzen-Anatomie und der Ueberdehnungs-Anzeige.

Live verifiziert: "M5 · keine Kompression (Box 3.52xATR) · Kosten 0.15xATR_M5
guenstig · ATR 0.165". Deploy ueber tools/deploy.py --feld m15_setup.m5
(Punktpfad), alle 5 Schritte gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:17:18 +02:00
Axel HocksandClaude Opus 5 618f3a4bee Doku: Einsatz je Pfad, MQL5 v1.44 und drei neue Fehlerklassen
Pflege-Regel. Festgehalten sind neben den beiden Features vor allem drei
Fallen, die heute real zugeschlagen haben:

1. Ein fehlgeschlagener MQL5-Compile LOESCHT die .ex5 - und der Default-Log
   des Terminals wird dabei nicht ueberschrieben. Ich habe daraufhin "0 errors"
   aus einem stale Log gemeldet, waehrend der Chart gar keinen Indikator hatte.
   Regel: eigener Logpfad je Compile, Pruefung auf "Result: N errors" PLUS
   .ex5-Zeitstempel.
2. Backticks in einer Bash-Commit-Nachricht werden als Kommando ausgefuehrt.
3. "git commit --amend -F <fehlende Datei>" nimmt eine stale COMMIT_EDITMSG,
   also die Nachricht eines fremden Commits.

Asset-Version auf v=182 nachgezogen (stand noch auf 169).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:07:13 +02:00
Axel HocksandClaude Opus 5 0a465f9258 Einsatz-Prozentsatz je autonomem Pfad (BRK / M15) + Dashboard-Feld
User: "Baue ein Eingabefeld im Dashboard ein in welchem ich das Margin
Verhaeltnis von M15 / BRK manuell setzen kann".

⚠⚠ EHRLICHE EINORDNUNG, weil die Umsetzung NICHT ist, wonach es klingt: eine
GLEICHZEITIGE Aufteilung (z.B. 40 % manuell / 50 % reserviert fuer BRK) ist
heute nicht baubar. Der Bot haelt EINE Position - _check_auto_squeeze feuert
"nur FLAT", und Trailing, Notfall-Stop, S/R-Close, Time-Stop und Breaker
verwalten je EINE Position (42 Einzel-Positions-Annahmen in engine.py, 25 in
trader.py). Mit zwei Positionen auf demselben Symbol haengt der GESAMTE
Schutz-Stack an einer davon, die andere liefe ungeschuetzt. Das ist kein
Aufwands-, sondern ein Sicherheitsargument.

GEBAUT ist deshalb das, was heute wirkt und dieselbe Frage beantwortet: je Pfad
ein eigener Einsatz-Prozentsatz. 0 = globaler Wert (bisheriges Verhalten).
Quellen-abhaengig verdrahtet wie die SL-Zeitebene seit 05.08.: _open() setzt
config.MARGIN_BUFFER fuer die Dauer des einen Aufrufs und stellt ihn im
finally-Zweig zurueck. Manuelle Trades bleiben beim globalen Wert (der Mensch
ist die gemessen bessere Population, +1,56 gegen -4,71 EUR/Lot).

⚠ Direkt gesetzt statt ueber set_margin_buffer(): das loggt je Trade eine
Zeile UND wuerde den globalen Wert dauerhaft ueberschreiben.

⚠⚠ ZWEI ECHTE FEHLER VOM LINTER GEFANGEN, die py_compile durchgewinkt hat:
"config" war in engine.py gar nicht importiert (nur Einzelnamen via
"from core.config import ..."), und in server.py hiess die Engine "eng" statt
"app.state.engine". Beide sassen in Pfaden, die erst beim ERSTEN autonomen
Trade bzw. beim ersten Klick gefeuert haetten - also genau die Klasse, fuer
die ruff F821 am 07.08. eingebaut wurde.

⚠ Frontend: $streng statt $, weil LEER hier ausdruecklich 0 = "global" bedeutet
und nicht "unveraendert"; mit dem Auffang-Element waere .value undefined -> NaN
-> null. Der Render ueberschreibt das Feld nicht, solange es den Fokus hat
(sonst frisst der 1-s-Snapshot die laufende Eingabe).

⚠ Beim Committen selbst zweimal danebengegriffen, beides dokumentiert weil es
Fehlerklassen sind: (a) Backticks in einer Bash-Commit-Nachricht werden als
Kommando-Substitution ausgefuehrt und loeschen die eingeklammerten Namen aus
dem Text; (b) ein Bash-Pfad (/c/Users/...) an Python uebergeben schlaegt fehl,
und "git commit --amend -F <fehlende Datei>" nahm daraufhin eine STALE
COMMIT_EDITMSG - die Nachricht eines fremden Commits. Der Code war davon nie
betroffen (Arbeitsbaum sauber, Remote synchron), nur die Beschriftung.

Ende-zu-Ende geprueft: 50/25 gesetzt -> Snapshot -> persistiert; 150 abgelehnt;
0/0 zurueck. Deploy ueber tools/deploy.py --feld margin_brk, alle 5 Schritte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:06:25 +02:00
Axel HocksandClaude Opus 5 8e7223f6ce MQL5 v1.44: Zeilenhoehe der Meldungen MESSEN statt schaetzen
User: 'die zeilenabstaende sind immer noch zu gering' (nach v1.43).

ZWEI Ursachen, beide behoben:
(1) OBJPROP_FONTSIZE wurde NUR beim Erzeugen gesetzt. Ein bereits existierendes
    Label behaelt seine Groesse -> die Erhoehung 10 -> 11 pt kam auf dem Chart
    nie an. Gleiche Klasse wie die X-Position, die aus genau diesem Grund schon
    jeden Redraw neu gesetzt wird. Jetzt auch die Schriftgroesse.
(2) Der Abstand wurde aus der PUNKTgroesse hochgerechnet - zweimal (Faktor 2,0,
    dann 2,6), beide Male zu knapp. Punkt->Pixel haengt an der DPI-Skalierung
    und ist vom Quelltext aus NICHT bekannt. Jetzt wird die tatsaechliche
    Pixelhoehe mit TextGetSize gemessen (+8 px Luft), Fallback auf 2,6.

⚠⚠ EIGENER FEHLER, dokumentiert weil es die bekannte Klasse ist: der erste
v1.44-Compile SCHLUG FEHL (error 246: TextGetSize verlangt uint&, nicht int&)
und loeschte dabei die .ex5 - der Chart hatte kurzzeitig GAR KEINEN Indikator.
Ich habe trotzdem '0 errors' gemeldet, weil ich einen STALE Logfile gelesen
habe (erkennbar an identischen 894 ms). Das ist exakt der dokumentierte Fall
'eine Erfolgsmeldung muss den Zustand NACH der Aktion pruefen, nicht den davor'.
Aufgefallen nur, weil die .ex5-Zeitstempelpruefung danebenstand.
Jetzt: eigener Logpfad je Compile + Pruefung auf 'Result: N errors' + .ex5-Alter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 19:00:01 +02:00
Axel HocksandClaude Opus 5 1b5bdf98e4 MQL5 v1.43: Meldungen groesser (10->11 pt) und Zeilenabstand 2.0 -> 2.6
User: 'die meldungen sind eine schriftgroesse zu klein und ueberlagern sich im MT5'.

Zwei Aenderungen an derselben Stelle, weil beide Symptome dieselbe Ursache haben:
OBJPROP_FONTSIZE ist in PUNKT, nicht Pixel. 11 pt rendern je nach DPI 18-24 px
hoch - mit Faktor 2.0 (=22 px) beruehren sich zwei Zeilen bereits. Faktor 2.6
(=28 px bei 11 pt) traegt auch 125 % DPI.

⚠ Die Schriftgroesse zu erhoehen OHNE den Abstand mitzuziehen haette die
Ueberlagerung VERSCHLIMMERT - der Abstand haengt am Faktor, nicht am Absolutwert.

Kompiliert ins RICHTIGE Terminal (D0E8209F.., das mit sr_levels.csv - der
dokumentierte Fallstrick): 0 errors, 0 warnings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:53:05 +02:00
Axel HocksandClaude Opus 5 444ed27ade Nachtrag: die drei falschen M15-Trades liefen alle ueber den alten Code
Zeitachse: 18:03:25 / 18:11:04 / 18:13:18 alle SHORT, Engine erst 18:13:31 neu
gestartet. Beweis ist das Log-Format der 18:13:17-Zeile ('Lesart ab, Level ...'
statt des neuen 'erlaubt, verboten=...'). Der Neustart kam 14 Sekunden zu spaet.

Zwei Fehler, beide meine: (1) der erste Bau nahm die Lesart statt des Vetos;
(2) ich habe den Schalter testbereit stehen lassen, waehrend der Fix noch nicht
deployt war -- der User schaltete ein und der alte Code feuerte sofort. Regel:
ein autonomer Pfad mit bekanntem Defekt gehoert hart aus, nicht nur 'nicht
eingeschaltet'.

Noch nicht live belegt: dass die neue Richtung korrekt eroeffnet. Der erste
echte Entry ist die Verifikation -- die Logzeile muss 'erlaubt, verboten=...'
enthalten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:15:32 +02:00
Axel HocksandClaude Opus 5 c5190e77fd M15-Auto-Entry: Richtung aus dem Veto + Abbruchregel verankert
(1) Der Auto-Entry nimmt die Richtung jetzt aus bias.verboten (= die ERLAUBTE
Richtung), also genau das, was die Karte anzeigt (app.js:504 nimmt erl). Kein
Veto -> kein Entry, weil die Karte dort ausdruecklich keine Richtung gibt.
Gegenprobe an der Live-Lage: verboten=SHORT, lesart=ab -> alt SHORT (die
verbotene!), neu LONG = identisch zur Anzeige. Damit entspricht der Pfad der
gemessenen Kontrolle C (-0,085/-0,030), der am wenigsten schlechten Variante --
aber weiterhin negativ. Die Korrektur behebt den Widerspruch, nicht den
fehlenden Edge.

(2) measurement_reminder.py: neue Messung m15_abbruch (>=20 AUTOM15_*-Trades,
Latte Verhaeltnis < 1,0 ODER PF < 1) und Config-Anker auto_m15 (validiert
false), dazu der Helfer _zaehle_setup(). Der Zaehler zaehlt nur geschlossene
Trades. Damit kann die vorab fixierte Regel nicht mehr unbemerkt verfallen --
genau das war bei B5 wochenlang der Fall.

Aktivierung steht aus: Backend-Aenderung, braucht einen Neustart. auto_m15 ist
aus, also keine Eile -- der Neustart wartet, bis das Konto flat ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:10:07 +02:00
Axel HocksandClaude Opus 5 412aab706d M15-Auto-Entry handelte die VERBOTENE Richtung -- abgeschaltet
User: 'der auto trader hat short eroeffnet obwohl long angezeigt wurde'.
Bestaetigt. auto_m15 = false, auch in runtime_state. Ein Trade betroffen
(18:03:24, SHORT 0,39 Lot @ 86,266).

Widerspruch: die Anzeige (app.js:504) nimmt bias.verboten -> die ERLAUBTE
Richtung (LONG), mein _check_auto_m15 nahm die P(break)-lesart (SHORT). Damit
hat der Bot die VERBOTENE Richtung eroeffnet -- und das Veto ist die einzige
beidhaelftig robuste Aussage der Karte (-6,60 EUR/Lot gegen das Signal).

Ursache: ich habe die Richtung gegen backtest_m15_auto.py geprueft und damit
dessen Variante A gebaut. Uebersehen: derselbe Backtest hat eine Variante B
(Lesart + veto-konform, -0,104/-0,051), und die Karte zeigt B. A gebaut, B
angezeigt. Geprueft hatte ich nur gegen den Backtest, nicht gegen die Anzeige.
Lehre: bei einem Auto-Entry auf eine ANGEZEIGTE Empfehlung ist die Anzeige die
zu pruefende Referenz.

Position laeuft auf User-Entscheidung weiter (Trailing an). Offen: ob der Trader
auf die angezeigte Richtung (Variante B) umgebaut wird. Zweiter offener Punkt:
die vorab fixierte M15-Abbruchregel ist noch nicht in measurement_reminder.py
verankert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:06:35 +02:00
Axel HocksandClaude Opus 5 bd65bdaad0 M15-Auto-Entry gebaut (Default AUS) -- gegen die Messung, auf User-Wunsch
User wollte den Auto-Trade testen, nach vollstaendiger Information ueber die
Beleglage. backtest_m15_auto.py (13.08.): die gehandelte Lesart ist in BEIDEN
Halbjahren negativ (OeR -0,162/-0,094, PF 0,72/0,84), beide KI schliessen die
Null aus, Nachbarn monoton schlechter, und sie ist schlechter als die
HTF-Richtung UND als ihr eigenes Gegenteil. Live entkoppelt 46,8 % Treffer.

_check_auto_m15 im _pos_loop: Ausloeser gruen + gerichtet, Richtung exakt wie im
Backtest (auf->LONG, ab->SHORT), Dedup 1x je Episode ueber (Richtung, Level),
nur FLAT, Setup-Tag AUTOM15_*. Erbt die VOLLE Guard-Kette ueber
_auto_guard('m15') -- der Parameter war laut Docstring genau dafuer vorgesehen,
nachgebaut wurde nichts.

Abweichung ausdruecklich benannt: gemessen wurde der Einstieg AM Level mit Fill
bei Beruehrung, gebaut ist der Markt-Einstieg. Der ist hier mehrfach als der
schlechtere gemessen -- die Live-Zahlen sind eher noch unter -0,16/-0,09 zu
erwarten.

Abbruchregel VORAB fixiert: nach >=20 AUTOM15_*-Trades Verhaeltnis < 1,0 ODER
PF < 1 -> auto_m15 = false. Dieselbe Latte wie B5, damit sie nicht nachtraeglich
wandert.

Verifiziert: Toggle, Snapshot-Felder, Deploy mit --feld auto_m15, ruff F821
(neuer Code sitzt in einem except -- der dokumentierte blinde Fleck), 85 Tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 18:01:52 +02:00
Axel HocksandClaude Opus 5 cc3a710752 Praezisierung: der Squeeze-Backtest unterstellt keinen Flat-Entry
User bat um Ueberpruefung der Aussage 'Reverse nie validiert -- der
Squeeze-Backtest unterstellt Flat-Entry'. Die Sache stimmt, die Begruendung war
ungenau.

squeeze_scan.scan hat ueberhaupt keinen Positions-Zustand: nach jedem Ausbruch
springt i = j + cooldown (3 Bars), nicht bis zum Exit. Jeder Ausbruch ist ein
isolierter Trade, Trades duerfen sich ueberlappen. Der Backtest unterstellt also
nicht Flatness -- die Lage 'Gegen-Position offen, wird gedreht' kann darin
schlicht nicht vorkommen. Gegengeprueft: kein einziger backtest_squeeze*.py
enthaelt das Wort 'reverse'; gemessen wurde nur die Exit-only-Halbvariante
(3x, alle negativ).

Zweite Folge, wichtiger: weil kein Slot modelliert wird, unterstellen die
dokumentierten Squeeze-Zahlen, dass man jeden Ausbruch nehmen kann -- live gibt
es EINEN Slot (die Sim ueberhandelt um das 2,4-fache, Befund vom 11.08.).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:31:28 +02:00
Axel HocksandClaude Opus 5 eedef26673 Close-Alarm hoerbar vom Empfehlungston getrennt (v=180)
User: 'beim akustischen Signal blinkt der Close-Button nicht'. Code und CSS sind
korrekt -- Blinken und Close-Ton haengen an derselben Variablen (closeAlert) und
koennen nicht auseinanderlaufen. Der gehoerte Ton war der EMPFEHLUNGSton, der
nur bei FLAT spielt und sich alle 30 s wiederholt; CLOSE blieb dabei korrekt
dunkel, weil es nichts zu schliessen gibt.

Der eigentliche Fehler ist die Aehnlichkeit: SHORT-Empfehlung 780->520 Hz und
Close-Alarm 880->620 Hz sind beide fallende Zweiklaenge, nur ~100 Hz auseinander.
Der Close-Alarm ist jetzt DREI kurze Pulse auf gleicher Tonhoehe (1046 Hz) --
Rhythmus unterscheidet zuverlaessiger als Tonhoehe.

Keine Logikaenderung, nur die Klangfarbe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:26:15 +02:00
Axel HocksandClaude Opus 5 602d8978dd Circuit Breaker bleibt aus (User) + .tmp aus dem Repo
Zustand festgehalten: runtime_state cb_limit_pct=0 (gewinnt beim Start),
cb_remember=8, ini 8. Der Config-Waechter wird die Abweichung melden -- korrekt.
Betriebszustand: BRK an, S/R-Auto-Close an, Einsatz 40 %, Tagesstopp aus.

Dritter Encoding-Abbruch desselben Musters heute, diesmal OHNE Schaden: die
.tmp+os.replace-Regel hat gehalten, CLAUDE.md blieb unversehrt. Uebrig blieb nur
eine leere .tmp-Leiche, die mitcommittet wurde -- *.tmp steht jetzt in
.gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:22:57 +02:00
Axel HocksandClaude Opus 5 8733f3957b Circuit Breaker bleibt aus (User-Entscheidung)
Auf den Hinweis, dass BRK an und die Notbremse aus ist, kam ein ausdrueckliches
'nein'. Zustand festgehalten: runtime_state cb_limit_pct=0 (gewinnt beim Start),
cb_remember=8, ini daily_loss_limit_pct=8. Der Config-Waechter wird die
Abweichung melden -- das ist korrekt und keine Stoerung.

Betriebszustand: BRK an, S/R-Auto-Close an, Einsatz 40 %, Tagesverlust-Stopp aus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:22:04 +02:00
Axel HocksandClaude Opus 5 a1ca9cfc33 Zehntes Buch per OCR geprueft + Umfang der 50-%-Reserve vermessen
(1) '[Main title here].pdf' war ein reiner Scan ohne Textebene. OCR aufgesetzt
(Tesseract 5.4.0 via winget, pymupdf + pytesseract; deutsche Sprachdaten in ein
schreibbares Verzeichnis, weil Program Files ohne Elevation gesperrt ist).
Identifiziert als 'TRADING 1X1 -- Der komplette Leitfaden fuer ANFAENGER'
(Kozalla). Stichprobe 38 Seiten OCR: Psychologie 14x, Steuern/Broker/Depot 8x,
Risiko-je-Trade 5x -- kein potenziell neuer Begriff. Zehn Buecher, keine neue
pruefbare Idee. Damit ist es geprueft statt ungeprueft.

(2) Die 50-%-Breakout-Reserve exakt vermessen, aber NICHT gebaut: 42
Einzel-Positions-Zustaende in engine.py, 25 Zugriffe in trader.py, 21 Aufrufe
von trader.snapshot/pnl/close.

Der entscheidende Punkt ist kein Aufwand, sondern eine Gefahr:
trader._refresh_locked bestimmt ueber positions_get(symbol=sym) 'die eine'
Position. Bei ZWEI Positionen auf demselben Symbol haengen Trailing,
Notfall-Stop, S/R-Close, Time-Stop und Circuit-Breaker an genau einer davon --
der Bot koennte sein Trailing auf die manuelle Position legen und seine eigene
Squeeze-Position ungeschuetzt laufen lassen. Die richtige Reihenfolge ist daher
erst 'die Position mit Ticket X' statt 'DIE Position', dann die FLAT-Bedingung.
Gehoert in eine eigene Sitzung mit flachem Konto.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:17:16 +02:00
Axel HocksandClaude Opus 5 71e85ca37c Drei weitere ebooks ausgewertet: nichts Neues, eines ohne Textebene
Drei PDFs kamen um 16:32-16:35 dazu, gleiches Vorgehen (Text extrahiert, gegen
das Gemessene gescannt).

- 'Trading - Dein sicherer Weg' (149 S.): Einsteiger-Einfuehrung, Psychologie
  166x, Risiko-je-Trade 9x, CRV 10x -- alles gemessen oder User-Entscheidung.
- 'Trading Strategien' (281 S.): Fibonacci 77x, Swing-Trading 40x, RSI/MACD 33x.
  Fibonacci ist hier gemessen schlechter als eine Zufallslinie; Swing-Trading
  ist bei 12-18 min Haltedauer strukturell gegenstandslos.
- '[Main title here].pdf': 230 Seiten, aber nur 2.530 extrahierbare Woerter --
  ein Bild-PDF ohne Textebene. Ohne OCR ungeprueft; das wird ausdruecklich als
  'ungeprueft' vermerkt, nicht als 'geprueft und nichts gefunden'.

Keine neue pruefbare Idee. Damit sind neun Buecher ausgewertet und der Bestand
als Ideenquelle erschoepft. Nichts am Trader geaendert -- eine 'Optimierung' aus
einer Quelle ohne neuen Inhalt abzuleiten waere genau der Fehler, gegen den die
2-Stichproben-Regel gebaut ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:10:30 +02:00
Axel HocksandClaude Opus 5 d9ff48b5be Knopf 'STOPP' in 'CIRCUIT BREAKER' umbenannt (v=179)
Nur Beschriftung: Button-Label, Toast-Text und die beiden Tooltip-Varianten.
Funktion, Endpunkt und Persistenz unveraendert. Dazu eine CSS-Zeile, damit das
laengere Label auf schmalen Displays umbricht statt ueberzulaufen -- sechs
Knoepfe teilen sich die Leistenbreite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:07:49 +02:00
Axel HocksandClaude Opus 5 c0293ece01 S/R-Auto-Close-Schalter in die Aktionsleiste + Doku nachgetragen (v=178)
Den S/R-Schalter gab es nur in der Trade-Leiste -- die ist aber nur bei OFFENER
Position sichtbar, also genau dann nicht, wenn man ihn VOR einem Trade setzen
will. Jetzt zusaetzlich in der Aktionsleiste neben STOPP. Der alte Knopf bleibt;
beide lesen auto_sr_close aus demselben Snapshot und koennen nicht
auseinanderlaufen. Live getestet: aus -> an, Endzustand AN.

Ausserdem die Doku zu den heutigen UI-/Telegram-Aenderungen nachgetragen, die
beim vorigen Versuch am Encoding-Fehler gescheitert war -- inklusive der Lehre:
Emoji nie als getrennte Unicode-Escapes, immer erst nach .tmp schreiben und die
Groesse gegen das Original pruefen, und eine Syntaxpruefung ersetzt die
Groessenpruefung nicht (eine leere Datei besteht node --check und jeden Hook).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:06:49 +02:00
Axel HocksandClaude Opus 5 880bf1075e CLAUDE.md wiederhergestellt + UI/Telegram-Aenderungen dokumentiert
Der vorige Commit hat CLAUDE.md mit 0 Bytes eingecheckt: ein Emoji als zwei
getrennte \u-Escapes erzeugt in Python lone surrogates, die sich nicht nach
UTF-8 kodieren lassen -- und io.open(p,'w') kuerzt die Datei VOR dem Schreiben.
Der pre-commit-Hook prueft Python und JS, nicht die Doku, also ging der Commit
gruen durch. Inhalt aus HEAD~1 wiederhergestellt.

Zweiter Totalverlust derselben Ursache am selben Tag (vorher web/app.js).
Regel ab hier ausnahmslos: keine Emoji als getrennte \u-Surrogate; immer erst
nach .tmp schreiben, Groesse gegen das Original pruefen, dann os.replace. Eine
Syntaxpruefung ersetzt die Groessenpruefung nicht -- eine leere Datei besteht
node --check und jeden Hook.

Inhaltlich dokumentiert: Einsatz-Felder entfernt, BRK-Schalter durch
Circuit-Breaker-Schalter ersetzt, Telegram auf 'Trade geschlossen' reduziert
(eine Filterstelle, ein Bypass fuer die FEHLGESCHLAGEN-Meldung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:04:56 +02:00
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 32c064a1a6 Einsatz 95 % -> 40 % + Breakout-Karte aktiv (v=176)
Nach dem Schliessen der Position ausgefuehrt. Der Trade schloss mit rund -152 EUR
(Equity 877 -> 725) -- genau die Groessenordnung, die diese Aenderung adressiert.

margin_buffer_pct in ini UND runtime_state auf 40. Bei 725 EUR freier Margin
sind das ~0,41 statt ~0,97 Lot, Risiko je 2xATR-Stop ~20 statt ~46 EUR. Gilt
fuer alle neuen Positionen, auch die autonomen.

Beide Stellen angeglichen: set_margin_pct persistiert als 'margin_pct' (nicht
'margin_buffer_pct'), _load_runtime_state (Z.487) laeuft nach dem ini-Lesen
(Z.176) und gewinnt. Die ini wurde mitgezogen, damit ein geloeschtes
runtime_state.json nicht still auf 95 % zurueckfaellt.

Karte #card-brk live: squeeze_b5 liefert n=11/20, ratio 0,14, PF 0,39,
-173,46 EUR. Deploy ueber tools/deploy.py --feld squeeze_b5, alle fuenf Schritte
gruen.

Offen bleibt Punkt 2 der User-Idee (50 % Reserve): technisch moeglich, aber
Kern-Umbau und gegen die Messung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:54:31 +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 3affe51030 BRK bleibt an (User): Zustand konsistent, 13-Tage-Flaute war kein Defekt
User-Auftrag: Breakout-Squeeze an lassen, neu rechnen und pruefen.

Zustand: ini / runtime_state.json / Snapshot stehen alle drei auf true --
nichts umzuschalten. Die Doku-Zeile vom 17.08. ('bleibt FALSE') war stale.

Auffaellig war: seit 06.08. kein Squeeze-Trade. Drei Hypothesen geprueft:
- Markt? Nein: die echte squeeze_scan liefert 57 Ausbrueche in 19,5 Tagen,
  53 ausserhalb des Nachtfensters (~19/Woche), zuletzt 14./17./18.08.
- Slot belegt? Nein: flat zu 57,8 %.
- Pending-Pfad defekt? Nein: SQZ-STOP 0, 'nicht platzierbar' 0, 0 ERROR.
Die Logzeile loest es: '2026-08-19 11:03:18 [WEB] Auto-Squeeze-Entry AN' --
er war vom 11.08. 14:10 bis heute schlicht AUS.

Nebenbefund: der Circuit-Breaker hat am 17.08. 18:35 zum ersten Mal ausgeloest
(-82,42 <= -81,45 EUR, Position geschlossen), zwei Tage nach dem Scharfstellen.

B5 unveraendert 11/20: Verhaeltnis 0,14, PF 0,39, Summe -173,46 EUR. Die Latte
ist rechnerisch unerreichbar (12,2x den Oe-Gewinn bzw. 2,1x den Rekord, neunmal
in Folge). Die -173 EUR kommen aus drei planmaessigen 2xATR_M15-Stops mal
Positionsgroesse, nicht aus dem Exit -- sr_close trug +15,98 EUR bei.

B5 wird NICHT nachtraeglich gesenkt, sondern als durch User-Entscheidung
ueberstimmt vermerkt. Eine Ersatzregel muesste vorab und auf einem neuen
Zaehlfenster fixiert werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:23:03 +02:00
Axel HocksandClaude Opus 5 496d65aab5 Vier weitere ebooks ausgewertet: drei ohne Ertrag, das vierte widerlegt eine Projekt-Regel
Sechs PDFs in ebooks/, zwei davon heute schon ausgewertet. Die vier neuen als
Text extrahiert (346k Woerter) und gegen das Gemessene gescannt statt gelesen.

- 'Day-Trading Attention' ist KEIN Trading-Buch: Vaynerchuks Social-Media-
  Marketing-Titel, ein Wortspiel. Null TA-Begriffe im ganzen Text.
- 'Die Kunst des technischen und algorithmischen Tradings' (656 S.): RSI/MACD/
  ADX 165x, Elliott 35x, Kerzen 37x, Fibonacci 18x, Bollinger 17x -- alles hier
  bereits gemessen und verworfen. Keine pruefbare Regel, kein CRV-Kapitel.
- 'KDP968 4 in 1': ausdruecklich fuer Einsteiger, unter dem Projektstand.
- 'Ein Fuchs namens Risiko': das einzige mit pruefbaren Aussagen, weil seine
  Kapitel ueber REIHENFOLGE und ABSTAND von Trades sprechen.

Gemessen auf 1.318 eigenen Trades (analyze_verhalten.py, je Lot, Bootstrap-KI):
keine der vier Behauptungen reproduziert. Revenge-Trading und Overtrading zeigen
sogar in die Gegenrichtung (< 5 min nach Verlust -1,53 gegen > 2 h -16,16;
3.-5. Trade -7,23 gegen 11.+ +1,00).

DER EIGENTLICHE BEFUND: die Projekt-eigene Checklisten-Regel 'nach 2 Losses
Session beenden' (seit 30.07. Punkt 6) ist auf den eigenen Trades NICHT
gestuetzt -- keine monotone Verschlechterung, der 3.-Verlust-Bucket ist wieder
positiv, alle vier KI enthalten die Null. Uebernommen aus der Literatur, nie
geprueft.

Nicht ueberinterpretieren: ~20 Zellen getestet, ~1 Fehlalarm erwartbar, zwei
schliessen die Null aus. Beobachtungsdaten, keine Zuweisung. Nichts gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:15:49 +02:00
Axel HocksandClaude Opus 5 af5190cf9e Raum je Richtung auf die Order-Knoepfe (v=175)
Gemessen auf 27 eigenen manuellen Trades: Raum < 0,6xATR zum naechsten Level in
Trade-Richtung = 79 % Trefferquote und trotzdem -7,57 bzw. -11,51 EUR/Lot. Das
ist die Klein-Close-Falle (Gewinn am Level gedeckelt, Verlust laeuft bis zum
Stop), ueber 80k Bars als PF 0,42/0,66 belegt.

Die Zahl stand nur in Gate 3b der M15-Karte -- seit dem Entfernen des
Entry-Dialogs am 11.08. war sie im Moment des Klicks unsichtbar. Jetzt als
zweite Zeile auf dem LONG-/SHORT-Knopf, bernstein unter dem Gate.

REINE ANZEIGE: kein Block, keine Sperre, kein Dialog -- Uebersteuerungen laufen
gemessen 68 % WR.

Kein Backend, kein Neustart: die Daten lagen bereits im Snapshot
(m15_setup.motor.raum) und werden NICHT neu gerechnet. Bewusst kein eigener
Layout-Block, weil #actions ein flex ohne wrap ist.

Verifiziert: node --check als Modul, check_nfalle sauber, beide IDs im
ausgelieferten HTML, live LONG 0,07xATR (unter Gate) / SHORT 1,49xATR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:08:31 +02:00
Axel HocksandClaude Opus 5 5eec4517f8 KI-Buch (Illab) ausgewertet: Workflow statt Signale, echte Luecke ist die Validierungsmethode
Zweites eingereichtes Buch, anderes Genre: Co-Piloten, No-Code-Bots, Scanner,
Agenten-Pipelines. Triage gegen den Projektstand: 10 von 12 Kapitel-Konzepten
sind gebaut (Copilot, Circuit-Breaker, Logs, Slippage-Messung, Dedup,
Tagesreport, Provider-Fallback) oder gemessen verworfen (Muster, Momentum,
Sentiment). Alt-Daten und Rebalancing sind fuer einen WTI-CFD gegenstandslos.

DIE EINE ECHTE LUECKE: Kap. 9.2 empfiehlt WALK-FORWARD, dieses Projekt prueft
mit ZWEI STICHPROBEN -- das Wort kommt in CLAUDE.md nie vor. Zwei Haelften haben
genau zwei Vorzeichen; ein Setup, das in der Haelfte aller Zeitbloecke negativ
ist, kann trotzdem 'beidhaelftig positiv' aussehen. Genau so ist das
P(break)-Modell ausgefallen (H1->H2 AUC 0,715, live 0,368).

Gemessen am Squeeze, gleiche Daten/Regel/Exit, variiert nur die Zeitaufteilung:
  2 Haelften: H1 -0,134 / H2 +0,036
  8 Bloecke:  - - - + + + - +   = 4 von 8 positiv, Spanne -0,301 .. +0,214
Die einzigen zwei Bloecke mit KI ohne Null sind BEIDE negativ. Kein Block ist
gesichert positiv. Die Haelften-Sicht verdeckt nichts, zeigt aber auch nichts.

Keine Code-Aenderung: die 2-Stichproben-Regel bleibt die Mindesthuerde (sie hat
28 Eingriffe korrekt abgewiesen), ist aber eine Aussage ueber zwei Regime, nicht
ueber Stabilitaet ueber die Zeit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 08:36:11 +02:00
Axel HocksandClaude Opus 5 adda5b0ccc Trading-Buch ausgewertet: 17/20 schon gemessen, die 3 Luecken fallen durch
User reichte 'Praktisches Trading 2.0' (Risueno Gomez) ein. Triage statt alles
nachmessen: 17 der ~20 Konzepte sind im Projekt bereits gemessen und ueberwiegend
verworfen. Ungemessen waren genau drei -- Bollinger, RSI-Divergenz, Drei
Soldaten/Kraehen. Alle drei mit Kontrollgruppe gemessen, keines besteht.

1 Bollinger-Squeeze ist SCHLECHTER als die live laufende ATR-Box (H2 -0,133 gegen
  -0,031, bei halb so vielen Trades). Der wertvollste Test, weil es kein neues
  Signal ist, sondern eine Variante des einzigen validierten Setups.
2 RSI-Divergenz kippt; die Gegenrichtung schlaegt sie in H1 mit KI ohne Null.
3 Drei Soldaten/Kraehen beidhaelftig negativ, Gegenrichtung besser.

In ALLEN DREI ist die Kontrollgruppe besser als die Buch-Lesart -- fuenfte
Bestaetigung derselben Inversion (Kerzen 4x, Winkel, Reversal).

Die Erfolgsraten-Tabelle S. 203 (Kopf-Schulter 83 %) ist unbelegt und
widerspricht der eigenen Messung (Ziel-Trefferquote 13-38 %).

Was das Buch BESTAETIGT ist sein Risikomanagement-Kapitel: nicht die
Trefferquote entscheidet, sondern OeGewinn/OeVerlust und 1-2 % Risiko je Trade.
Genau das misst dieses Projekt unabhaengig (Squeeze 73 % Treffer, PF 0,39,
Verhaeltnis 0,14; MaxDD 82,8 % gegen 22,2 % bei 0,5 % Risiko) -- und es ist der
einzige Punkt, an dem noch nichts umgesetzt ist.

26., 27. und 28. verworfener Signal-Eingriff. 40k Bars = Ausschluss-Urteil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 08:04:00 +02:00
Axel HocksandClaude Opus 5 71bd836f56 Klein-Close-Falle auf eigenen Trades belegt + Breaker-Korrektur
Suche nach weiteren Optimierungen. Zwei Befunde:

1 ctx_*-Telemetrie erstmals auf der Ausfuehrungs-Achse ausgewertet (121 manuelle
  Trades, je Lot). Die beiden entry_room-Zonen (<0,6xATR) sind die einzigen mit
  zweistellig negativem Ertrag: -7,57 und -11,51 EUR/Lot -- bei 79 % bzw. 54 %
  Trefferquote. Das ist die ueber 80k Bars gemessene Klein-Close-Falle, jetzt auf
  eigenem Geld. Kontrolle auf der Gegen-Seite zeigt das Muster NICHT, es ist also
  spezifisch die Ziel-Seite. n=14/13, Intervalle breit -> Bestaetigung, kein Beleg.
  Die Zahl ist seit dem Entfernen des Entry-Dialogs (11.08.) im Moment der
  Entscheidung unsichtbar. Vorschlag (nicht gebaut): Raum je Richtung in die
  Order-Leiste -- sichtbar machen, nicht bevormunden.

2 KORREKTUR zu meinem Eintrag vom 17.08.: die zitierten +739 EUR stammen aus einer
  Simulation, die nach dem Ausloesen ALLE Trades des Tages sperrt. Live sperrt der
  Breaker nur die autonomen -- und die sind 36 von 461 (7,8 %). Die sperrende
  Haelfte ist damit praktisch inert. Das SCHLIESSEN der offenen Position wirkt
  weiter und war der groesste Posten der Simulation. 8 % bleiben gesetzt, die
  erwartete Wirkung ist kleiner als zitiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 01:12:48 +02:00
Axel HocksandClaude Opus 5 f15a36138f Konfidenz-Schwelle und M15-Selektivitaet gemessen: keine Aenderung
(2) conf_pct trennt im Markt-Modus NICHT: der Bandverlauf ist nicht
gleichgerichtet (H1 bestes Band 0-44, schlechtestes 55-64), und die Schwelle
bewegt nichts -- >=0 liefert H1 -0,189, >=55 liefert -0,197. 11,4 % Signalmenge
fuer 0,017 R. Mit ruhender Order trennt die obere Haelfte: >=75 schlaegt die
Live-Schwelle im OeR beidhaelftig (-0,001/+0,147 gegen -0,070/+0,081), aber die
Summe faellt (+82,8 gegen +146,1). Regel verlangte beides -> nicht geaendert,
Regel NICHT nachtraeglich gelockert. 27. verworfener Signal-Eingriff.

Dritte unabhaengige Bestaetigung des Ausfuehrungs-Hebels am selben Tag:
Level gegen Markt +0,127/+0,096 R, groessengleich zu backtest_entryroom_level.

(3) M15-Karte steht 37,8 % der ZEIT gruen (in Wechseln gerechnet waeren es 49 %
-- gruene Phasen sind kuerzer). Handlungsrelevanter Zustand entkoppelt 54,1 % /
51,5 %, beide KI enthalten die 50 %. 205 von 350 unabhaengigen Faellen, also in
gut zwei Wochen entscheidbar. Die Hysterese vom 12.08. wirkt (53 -> 54,1 %).
Gate 3b ins Banner zu ziehen ist durch den Entry-Raum-Lauf schon beantwortet:
diese Dimension trennt nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 01:09:12 +02:00
Axel HocksandClaude Opus 5 be9f444507 Entry-Raum-Gate gegen Ausfuehrung gemessen: nicht gebaut
User fragte nach Verbesserungen der Empfehlung. entry_room blockt 60,6 % (gerichtet
nur 2,7 %) und ist damit der groesste Blocker -- kalibriert aber 2026-07-16 mit
MARKT-Einstieg. Seit 05./06.08. ist belegt, dass eine ruhende Order AM Level etwas
Gegenteiliges ist (in die Wand kaufen vs. aus ihr ausbrechen). Das Gate blockt beide.

Regel vorab fixiert, verfehlt: H1 bleibt in allen Varianten und ueber alle vier
Nachbarn negativ. Nichts gebaut. 26. verworfener Signal-Eingriff.

Drei Befunde, die mehr wiegen als die Ausgangsfrage:
 1 Die ruhende Order ist auf DENSELBEN Signalen beidhaelftig besser als der Markt
   (+0,109 / +0,088 R). Der Ausfuehrungs-Hebel ist real, reicht aber nicht.
 2 Das Gate ist in Wahrheit BINAER: von 4258 Signalen fallen 4 in 'Level vorhanden
   aber weit genug'. Es fragt praktisch nur, OB ein M5-Pivot existiert.
 3 Was es durchlaesst, ist selbst beidhaelftig negativ (-0,145 / -0,071) und in H2
   schlechter als die geblockte Gruppe. Das Gate sortiert Verluste um.

Deckt sich mit rec_outcomes (49,2 % / 48,3 % Treffer, n=61), das den Muenzwurf-Befund
jetzt live reproduziert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 01:04:55 +02:00
Axel HocksandClaude Opus 5 5b01610634 Einsatz-Feld: feste Breiten durch mitwachsende ersetzt (v=174)
User: das Einsatz-Feld ist nicht breit genug.

Die Trade-Leiste hatte width:88px fest, die Order-Leiste 74px. Der Einsatz zeigt
Betraege wie '712.84 EUR' -- bei fett und 0,94rem passt das in 88px nicht (das
sind ~9,7 Zeichen Platz bei 10 benoetigten).

Jetzt in ch statt px: 1ch ist die Breite einer Ziffer und haengt damit an der
Schriftgroesse -- skaliert also mit der fluiden Wurzel mit, was ein px-Wert
nicht tut. Anzeige-Werte bekommen width:auto + min-width:7.5ch und duerfen bei
laengeren Betraegen darueber hinaus wachsen statt abzuschneiden; Eingabefelder
bleiben bei 8ch als feste, aber mitskalierende Basis. Order-Leiste 74px -> 7ch.

Das war dieselbe Klasse wie die px-Abstaende von heute frueh: eine feste
Pixelzahl in einem Layout, dessen Schrift skaliert.

Verifiziert: min-width:7.5ch im ausgelieferten CSS, HTML zieht v=174.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:44:44 +02:00
Axel HocksandClaude Opus 5 496713b396 Meldungen vor Marktkontext (v=173)
User-Wunsch. Reihenfolge im Dashboard war: Trade-Leiste -> M15 -> Marktkontext
-> Meldungen. Jetzt: Trade-Leiste -> M15 -> Meldungen -> Marktkontext.

Sachlich passend: die Meldungen sind der LIVE-Strom zum laufenden Trade
(Squeeze, Ueberdehnung, S/R-Naehe, News-Konflikt), der Marktkontext dagegen
Hintergrund ohne Handlungsbezug. Was handlungsrelevant ist, gehoert nach oben.

Umgesetzt als reiner Markup-Umzug (kompletter <section>-Block inkl. passendem
</section> ueber Tiefenzaehlung, nicht per Zeilennummer). Von hinten nach vorn
ersetzt, sonst verschieben sich die Indizes.

Verifiziert: Tag-Balance 18/18, 0 doppelte IDs, 0 verwaiste app.js-Referenzen,
ausgeliefert steht card-pos jetzt vor card-kontext.
Backup index.html.bak-2026-08-19-reihenfolge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:42:46 +02:00
Axel HocksandClaude Opus 5 3b5706c6bb Picos Formular-Hoehe zurueckgenommen (v=172)
User: die Textfelder des laufenden Trades sind viel zu hoch.

ZWEI Pico-Regeln waren schuld:
 (1) input{height:calc(1rem*line-height + spacing-vertical*2 + border*2)} --
     mit --pico-form-element-spacing-vertical:0.75rem sind das ~3rem = 48px.
     Unsere .tb-field-Regel setzt nur padding, KEINE Hoehe -- also gewann Pico.
 (2) input{margin-bottom:var(--pico-spacing)} -- nochmal 0,7rem darunter.

height:auto laesst wieder das eigene Padding die Hoehe bestimmen; margin-bottom:0
entfernt den Formular-Abstand. Checkbox/Radio/Range ausgenommen (eigene
Groessenlogik).

Rechnerisch am Handy (Wurzel 16px): vorher ~50px, jetzt ~30px.

Das ist die erste Stelle, an der Pico sichtbar durchgeschlagen hat -- genau der
Fall, den ich beim Einbau angekuendigt habe. Die Bruecke im Kopf von style.css
ist der Ort fuer weitere solche Ruecknahmen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:41:48 +02:00
Axel HocksandClaude Opus 5 572c6c0253 PicoCSS v2.1.1 als Basisschicht eingebunden (v=171)
User-Wunsch "schreibe auf pico css um".

⚠ EHRLICH ZUM UMFANG: Pico ist KLASSENLOS -- es stylt semantisches HTML
(button, input, article, nav), nicht die ~60 Trading-Klassen (.card, .tb-field,
.m15-item, .px ...). Ein echtes "Umschreiben" ist damit gar nicht moeglich; was
geht, ist eine SCHICHT: Pico liefert Typografie, Formulare, Buttons und
Fokus-Ringe, style.css steht DANACH und gewinnt bei Konflikten.

LOKAL eingebunden (83 KB), kein CDN: die PWA laeuft ueber WireGuard und muss
offline funktionieren; ein CDN-Link waere zudem CSP-blockiert.

Damit Pico das Dashboard nicht in sein Standard-Blau umfaerbt, sind seine
Variablen auf die BESTEHENDE Palette gemappt (--pico-* -> --bg/--card/--accent
...). Zwei Pico-Defaults bewusst ausgeschaltet:
 - --pico-font-size: 100% -- Picos eigene fluide Schrift wuerde sich mit
   html{font-size:clamp(...)} vom 13.08. MULTIPLIZIEREN.
 - Block-Abstaende auf 0,7rem gezaehmt; die Karten bringen ihre eigenen mit.
Dazu drei Ruecknahmen, wo Picos Container-Regeln mit dem Grid kollidieren.

Verifiziert am laufenden Server: pico.min.css HTTP 200 (83.319 Bytes),
style.css 200, data-theme=dark im ausgelieferten HTML, und die Reihenfolge
stimmt (Pico Zeile 14, style.css Zeile 15).

Nebenbefund: das CDN antwortete sofort -- das Netz ist in Ordnung, nur Gitea
ist weiterhin nicht erreichbar.

Backups: index.html.bak-2026-08-19-pico, style.css.bak-2026-08-19

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:36:11 +02:00
Axel HocksandClaude Opus 5 d03d6a1a50 Dashboard wirklich responsive: Hauptgitter selbstregelnd, Abstaende in rem (v=170)
User: am Handy passen sich die Groessen nicht an.

HAUPTBEFUND: main hatte FESTE 2 Spalten und brach erst bei <=360px um --
moderne Handys haben 390-430 CSS-Pixel. Auf dem Geraet standen also zwei
Spalten a ~190px nebeneinander. Der Breakpoint war schlicht zu schmal geraten.

Jetzt selbstregelnd, ohne geratenen Breakpoint:
  main{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
  360/390/430px -> 1 Spalte · 768 -> 2 · 1024 -> 3 · 1440 -> 4

ZWEITER BEFUND: 138 Abstaende in px, 0 in rem -- die Schrift skalierte seit dem
13.08., die Polster nicht. Damit sass der Text am Handy eng und auf dem Desktop
verloren. Jetzt 122 von 138 auf rem umgestellt (Basis 18px, passend zur fluiden
Wurzel); die verbleibenden 29 sind Werte < 4px, wo Rundung mehr schadet als
nuetzt. Rahmen, Radien und Punktgroessen bleiben BEWUSST px -- die sollen nicht
mitwachsen.

Auch .trades (5 feste Spalten, sprengte 390px) auf auto-fit umgestellt.

Ausgeliefert verifiziert: auto-fit im CSS, 122 rem-Abstaende, HTML zieht v=170.
Backup web/style.css.bak-2026-08-19.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:32:07 +02:00
Axel HocksandClaude Opus 5 3a1d8f7687 Y-Stapel oben rechts: gemessen statt geschaetzt (Indikator v1.42)
User: oben rechts ueberlagern die Texte immer noch.

ZWEI Fehler in meinem eigenen v1.41-Fix:
 (1) Die Y-Zuweisungen standen INNERHALB von if(ObjectFind < 0) -- sie griffen
     also nur beim ERZEUGEN. Ein bereits vorhandenes Label behielt seine alte
     Position. Denselben Fehler hatte ich bei der X-Zentrierung schon gefangen
     und hier trotzdem wiederholt.
 (2) Der Faktor 1,8 px je Punkt war nur die NAECHSTE Schaetzung. Bei anderer
     DPI-Skalierung waere er wieder falsch gewesen.

Jetzt: LabelH() misst die TATSAECHLICHE Pixelhoehe ueber TextGetSize
(TextSetFont nimmt 1/10 Punkt bei negativer Groesse) und gibt sie +6 px Luft
zurueck; Rueckfall size*2, falls die Messung 0 liefert. Y wird bei JEDEM Redraw
gesetzt.

⚠ TextGetSize verlangt uint& -- mit int& kompiliert es nicht (error 246).

Kompiliert ins richtige Terminal: 0 errors, 0 warnings, .ex5 frisch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:25:11 +02:00
Axel HocksandClaude Opus 5 e1a671a137 Y-Stapel oben rechts korrigiert (Indikator v1.41)
User: oben rechts die Texte ueberlagern sich. Dieselbe Punkt-statt-Pixel-
Rechnung wie gestern links -- OBJPROP_FONTSIZE ist in PUNKT, die alten Formeln
behandelten sie wie Pixel.

Bei InpPriceSize=20 stand:
  Kurs  y=14, 20 pt -> belegt 14..50
  G/V   y=44        -> lag MITTEN im Kurs
  HL    y=56        -> lag MITTEN im G/V

Jetzt gestapelt mit Faktor 1,8 px je Punkt (konservativ zwischen 1,6 und 2,0,
traegt auch 125 % DPI):
  Kurs 14 · G/V 50 · HL 78

Die Positionen werden deterministisch aus den Schriftgroessen berechnet, nicht
ueber eine laufende Variable -- die CSV-Zeilen kommen nicht in garantierter
Reihenfolge, ein Akkumulator waere davon abhaengig.

Kompiliert ins richtige Terminal: 0 errors, 0 warnings, .ex5 frisch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:13:55 +02:00
Axel HocksandClaude Opus 5 e471170b01 Meldungen zentriert statt oben links (Indikator v1.40)
User-Wunsch. MT5 kennt keine 'Mitte'-Ecke: der Bezugspunkt bleibt
CORNER_LEFT_UPPER, aber der ANKER wird auf ANCHOR_UPPER (Text-Oberkante mittig)
gesetzt und X auf die halbe Chartbreite. Damit waechst der Text nach beiden
Seiten und bleibt bei jeder Fensterbreite zentriert.

X wird bei JEDEM Redraw neu gesetzt, nicht nur beim Erzeugen -- sonst haengt die
Zentrierung nach einer Fenster-Groessenaenderung auf der alten Breite fest.

Startabstand von oben 40 -> 24, weil MT5s eigene Symbol-/Zeitrahmen-Zeile links
steht und mittig nicht mehr im Weg ist. Weiterhin ueber InpMeldungY einstellbar,
Zeilenabstand bleibt Faktor 2,0 der Schriftgroesse (v1.39).

Kompiliert ins richtige Terminal: 0 errors, 0 warnings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:10:56 +02:00
Axel HocksandClaude Opus 5 046d9c6948 Meldungen oben links neu positioniert (Indikator v1.39)
User: die Anzeigetexte oben links ueberlagern sich. Zwei Fehler im alten
'16 + i*(size+6)':
 (1) START zu hoch -- MT5 zeichnet oben links SELBST die Symbol-/Zeitrahmen-
     Zeile; y=16 landete mitten darin. Beleg: es ueberlagerte sich, obwohl nur
     EINE MS-Zeile aktiv war -- es konnten also gar nicht zwei Meldungen sein.
 (2) ABSTAND zu knapp -- OBJPROP_FONTSIZE ist PUNKT, nicht Pixel; 10 pt rendern
     je nach DPI 16-20 px. Bei 16 px Zeilenabstand ueberlappen mehrere
     Meldungen zwangslaeufig.
Jetzt Startabstand ueber InpMeldungY (40) und Zeilenabstand Faktor 2,0.
Kompiliert ins richtige Terminal: 0 errors, 0 warnings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:07:49 +02:00
Axel HocksandClaude Opus 5 adcae09317 Ruhende Messungen als RUHT markieren statt als "sammelt"
Zwei Messungen brauchen SQUEEZE-Trades, und auto_squeeze ist seit dem 11.08.
aus -- seit dem 17.08. auch begruendet (B5-Regel gefallen). Ihre Zaehler stehen
seither still: Stop-Order-Umbau 8/12, Nacht-Fenster 3/15.

Als "sammelt (67 %)" angezeigt suggerierten sie einen Fortschritt, den es nicht
gibt: sie laufen NIE ab. Jetzt erscheinen sie als

  ⏸ ... [RUHT]   8/12 ... -- steht STILL
     braucht SQUEEZE-Trades -- auto_squeeze ist AUS ...

RUHEND heisst: die Messung ist nicht langsam, sie ist BLOCKIERT -- und die
Blockade ist eine ENTSCHEIDUNG, keine Datenfrage. Wer den Trader wieder
einschaltet, laesst beide automatisch weiterlaufen; es ist nichts nachzuholen.

Umsetzung: RUHT-Tabelle mit je einer Pruef-Funktion; _auto_squeeze_an() liest
core.live_config (ini + runtime_state in der Vorrangfolge des Engine-Starts).
Faellt die Pruefung aus, gilt "nicht ruhend" -- lieber ein Zaehler zu viel als
eine still verschwundene Messung.

Die sechs uebrigen Messungen laufen unveraendert als "sammelt".

⚠ Beim Bau in die dokumentierte \n-Falle gelaufen: ein per Heredoc geschriebenes
f"\n..." wurde zum echten Umbruch im String-Literal (SyntaxError). CLAUDE.md
sagt genau das ("NIE per Heredoc -- den Edit-Weg nehmen"); ueber den Edit-Weg
behoben, check_nfalle laeuft sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:31:52 +02:00
Axel HocksandClaude Opus 5 7a832c4f40 Zwei Waechter-Fehlalarme behoben (auto_squeeze-Erwartung, candles_m1-Vorbedingung)
Bei der Durchsicht offener Punkte gefunden -- beide derselben Klasse: ein
Waechter, der dauerhaft warnt, wird ignoriert, und mit ihm die eine echte
Meldung (so ist der Divergenz-Waechter verstummt).

(1) Config-Waechter erwartete auto_squeeze='true' und meldete deshalb seit dem
    11.08. taeglich eine Abweichung -- obwohl FALSE inzwischen der begruendete
    Zustand ist: die B5-Regel ist am 17.08. rechnerisch gefallen (Verhaeltnis
    0,14 gegen Latte 1,0, PF 0,39, Latte unerreichbar). Erwartung auf 'false'
    gedreht, mit dem Hinweis, dass ein Wiedereinschalten eine NEUE Entscheidung
    mit NEUER Latte waere -- dann gehoert der Eintrag zurueckgedreht.

(2) Telemetrie-Puls meldete candles_m1 als Ausfall ("letzte Zeile vor 0,5 h").
    Real war der Markt zu -- Pepperstone schliesst ~23:00 und das ganze
    Wochenende. Der Logger hatte gestern erst die Vorbedingungs-Kennzeichnung
    fuer pbreak_predictions/rec_outcomes bekommen; candles_m1 stand noch auf
    "unbedingt". Jetzt mit Vorbedingung -> erscheint als Hinweis statt Ausfall.
    0 Zeilen bleibt weiterhin IMMER ein Befund.

Verifiziert: Puls zeigt beide als Hinweis, Config-Waechter still.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:28:24 +02:00
Axel HocksandClaude Opus 5 30ed913678 Beschriftung der Konsolidierungs-Box entfernt (Indikator v1.38)
User-Wunsch. Die sichtbare Beschriftung ("Konsolidierung (10-Bar-Spanne)" bzw.
"Konsolidierung - komprimiert, Ausbruch steht bevor") kam in v1.30 auf die Frage
"was bedeutet die graue Box" und stand seither dauerhaft im Chart.

Der erklaerende Text bleibt als TOOLTIP an der Box -- die Information geht also
nicht verloren, sie draengt sich nur nicht mehr auf. Die Box selbst und ihre
Farbgebung (komprimiert/normal) bleiben unveraendert.

Ein evtl. noch vorhandenes Alt-Objekt aus v1.30-v1.37 wird beim ersten Redraw
geloescht: ObjectsDeleteAll(0, PFX) raeumt zwar ohnehin, aber nur solange der
Indikator laeuft -- nach einem Versionswechsel ohne Redraw bliebe es sonst
stehen (dieselbe Alt-Objekt-Falle wie bei den HL-Pfeilen).

Kompiliert ins richtige Terminal: 0 errors, 0 warnings, .ex5 frisch, Version im
Terminal gegengeprueft, nur noch die Loeschzeile enthaelt TCONSOL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 22:26:21 +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 8d17cf08e0 Verdict-Module gemessen (2. Durchgang) + Faelligkeitsschwelle zaehlte die falsche Groesse
FAELLIGE MESSUNG (30.282 Zeilen). Horizont 60 min, gegen die Drift-Null,
Episoden statt Rohzeilen:

  Welle      3,0    254 Ep.  +0,158 / +0,419  61 %  beide +
  Liq-Trend  0,5    297 Ep.  +0,310 / +0,175  52 %  beide +
  Squeeze    2,0    249 Ep.  +0,110 / +0,254  48 %  beide +
  Orderbuch  0,5  2.712 Ep.  -0,039 / -0,100  49 %  beide -
  Elliott    1,0  1.388 Ep.  kippt            49 %
  M30/Muster/H1                kippen
  H1         1,5     50 Ep.  -1,165 / +1,937  66 %  kippt

Meine Vermutung vom 07.08. war FALSCH: Liq-Trend besteht (+0,310/+0,175 ueber
297 Episoden). Ich hatte ihn verdaechtigt, weil er dieselbe HL-Quelle nutzt wie
das entmachtete Orderbuch -- das war Analogie, keine Messung. Bleibt bei 0,5.

Orderbuch bestaetigt: beidhaelftig negativ ueber 2.712 Episoden, die groesste
Stichprobe und der einzige konsistent falsche Beitrag. Entmachtung war richtig.

SCHAERFSTER BEFUND: H1 traegt 41,2 % des Nadel-Einflusses auf 50 Episoden, die
das Vorzeichen kippen. Hoechster Einfluss, duennste Beleglage. Live folgenlos
(die Nadel ist reine Anzeige), aber wer sie liest, sollte es wissen.

FAELLIGKEITSSCHWELLE KORRIGIERT: stand auf 25.000 ZEILEN -- bei Minutentakt in
12 Tagen erreicht, waehrend die auswertbare Einheit Episoden sind (je Modul nur
50 bis 2.712). Dieselbe Klasse wie pbreak_accuracy_v2. Jetzt 400
Headline-Episoden als Proxy, mit dem ausdruecklichen Hinweis, dass es je Modul
deutlich weniger sind.

PUNKT 2 (Stop-Order-Umbau, 8/12): DERSELBE DEADLOCK wie B5. Alle acht Bot-Trades
stammen vom 06.08.; seit auto_squeeze am 11.08. aus ist, kommt keiner mehr dazu.
Was die 8 zeigen, bleibt gueltig und positiv: 7 von 8 fuellten per ruhender
Order, Market-Fallback praktisch weg (n=1 bei +0,148xATR). Die formale
Faelligkeit haengt an derselben Entscheidung wie B5, nicht an weiteren Daten.

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:04:54 +02:00
Axel HocksandClaude Opus 5 f3e7eeff6c Doku: Netto-Steuerrechnung war faelschlich als 'nicht gebaut' gefuehrt
Bei der Durchsicht offener Punkte gefunden: CLAUDE.md fuehrte die Umstellung auf
die echten WHT-/Tax-settlement-Buchungen weiter als offen -- sie ist seit dem
12.08. gebaut (trader.steuer_buchungen + server._add_net + Feld wht_quelle,
Ergebnis: all von -2.449,95 auf +181,00 EUR). Stelle korrigiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:01: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 55dc69ef42 Kerzenmuster fuer die Richtung der naechsten Kerze = nein (4. Messung der Klasse)
User-Anschlussfrage. Gemessen mit den ECHTEN Muster-Schwellen aus
core/candles.py (1:1 importiert, kein Nachbau), 80k M5-Bars, 2 Halbjahre,
unveraenderte Schlusskurse ausgeschlossen, 95-%-Intervall je Zelle. Bewertet
wird die Lehrbuch-Lesart, damit sichtbar wird, ob sie stimmt.

  Marubozu             46,5 % / 45,2 %   beide KI unter 50
  Engulfing            47,4 % / 49,5 %
  Outside Bar          47,3 % / 48,9 %
  langer Koerper       48,5 % / 47,6 %
  langer Docht OBEN    49,4 % / 47,8 %
  langer Docht UNTEN   50,6 % / 50,6 %   beide KI enthalten 50

KEIN Muster erfuellt die vorab fixierte Regel. Trefferquoten 45,2-50,6 %, fuenf
Zellen mit Intervall komplett unter 50 -- in der Lehrbuch-Lesart also
verlaesslich falsch. Die einzige beidhaelftig ueber 50 kippt beim Vorzeichen der
Bewegung (+0,0004 / -0,0037).

Das reproduziert den 60-Minuten-Befund vom 31.07. ("Lehrbuch-Lesart in beiden
Haelften invertiert") jetzt auf dem 1-Bar-Horizont, mit den echten Klassen statt
grober Proxys. Vierte Messung der Kerzen-Klasse.

Und selbst umgedreht zahlt es nicht: groesste Oe-Bewegung 0,0077 $, kippt in der
anderen Haelfte auf -0,0019; halber Spread 0,0100 $, Median-Kerze 0,0400 $.

URTEIL: der Pfeil bleibt bei der kalibrierten Level-Aussage. Nichts geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 08:49:08 +02:00
Axel HocksandClaude Opus 5 eec28e3382 Pfeil "naechste Kerze" gemessen: Effekt existiert, ist aber 50-100x zu klein
User: der Pfeil an der aktuellen Kerze zeigt die Abprall-Wahrscheinlichkeit des
S/R -- er soll stattdessen die Richtung der naechsten Kerze schaetzen.

Die Beobachtung stimmt und ist Absicht: live steht AR;L;81.815;81.983;62%
Abprall -- der L-Pfeil, seit v1.32 bewusst als BEDINGTE, kalibrierte Groesse
gebaut (haelt DIESES Level, AUC 0,65 oos) statt als freie Prognose.

Trotzdem neu gemessen statt abgelehnt: die bisherigen Richtungs-Messungen liefen
ueber 60-360 Minuten, die naechste M5-Kerze ist ein kuerzerer Horizont mit
eigener Mikrostruktur.

80k M5-Bars, 2 Halbjahre, 5 Praediktoren:

  EMA-Trend            49,6 % / 49,6 %
  Momentum 3 Bars      48,3 % / 48,3 %
  letzte Kerze fort    48,6 % / 48,8 %
  letzte Kerze UMKEHR  51,4 % / 51,2 %   <- beide KI ueber 50
  langer Docht         49,5 % / 49,3 %

Es GIBT einen Effekt, und zwar den umgekehrten: 1-Bar-Mean-Reversion trifft
beidhaelftig ueber 50 %. Trendfolge und Momentum liegen darunter.

ABER die oekonomische Bedingung faellt katastrophal durch: die Oe-Bewegung in
Vorhersagerichtung ist +-0,0002 $, der halbe Spread 0,0100 $ -- der Effekt ist
50-100x zu klein. Eine M5-Kerze bewegt sich im Median 0,0400 $, der Spread ist
0,0200 $ = 50 % davon.

URTEIL: der Pfeil bleibt. Ein "naechste Kerze"-Pfeil waere technisch wahr und
praktisch wertlos -- und muesste nach der Messung GEGEN die letzte Kerze zeigen,
was jeder Mensch als Fehler lesen wuerde.

EIGENER MESSFEHLER, dokumentiert weil er eine Klasse ist: der erste Lauf zaehlte
unveraenderte Schlusskurse als Fehltreffer, wodurch ein Praediktor UND sein
Gegenteil beide unter 50 % lagen (43,4 + 45,8 = 89,2) -- arithmetisch unmoeglich
und damit der Verraeter. Real sind ~11 % der M5-Kerzen unveraendert.
Merksatz: wenn A und Nicht-A sich nicht zu 100 % addieren, ist die Messung
kaputt, nicht der Markt.

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 08:44:58 +02:00
Axel HocksandClaude Opus 5 792355e8f9 Sieben Verbesserungen umgesetzt: Breaker scharf, B5 entschieden, 5 Werkzeuge
1) CIRCUIT-BREAKER SCHARF -- daily_loss_limit_pct 0 -> 8. Live verifiziert:
   enabled=True, limit_eur 89,44. Steht nicht in runtime_state.json, die ini
   greift direkt. Begruendung: MaxDD 82,8 % auf dem gemessenen IST-Pfad,
   schlechtester Einzeltrade -381 EUR.

2) B5-DEADLOCK RECHNERISCH AUFGELOEST -- die Regel ist ENTSCHIEDEN, nicht
   vertagt. Stand 11/20: Verhaeltnis 0,14 (Latte 1,0), PF 0,39 (Latte 1,0).
   Was die 9 Rest-Trades leisten muessten:
     9/0 Gewinner -> 165,72 EUR je Trade = 12,2x der bisherige Schnitt
     7/2          -> 186,17 EUR
     5/4          -> 222,99 EUR
   Der groesste Squeeze-Gewinn des Zeitraums war 77,34 EUR -- selbst der beste
   Fall verlangt 2,1x den Rekord, neunmal in Folge. Latte nicht mehr erreichbar.
   auto_squeeze bleibt FALSE. Wiederaufnahme waere eine NEUE Entscheidung mit
   NEUER, vorab fixierter Latte.

3) core/kontrolle.py -- Kontroll-Fixture mit den Referenzwerten. Bricht bewusst
   NICHT ab: ein Backtest darf abweichen, er muss es nur wissen und sagen.

4) core/live_config.py -- EINE Quelle der Live-Parameter (ini + runtime_state in
   der Vorrangfolge des Engine-Starts). Dritte Instanz derselben Fehlerklasse:
   ATRMIN_STD 0,12 statt 0,06, fehlendes set_entry_room, nachgebauter Cluster.

5) stichprobe.paarweise()/zeig_paarweise() -- gepaarter Vergleich. Anlass:
   trail_start sah sequentiell besser aus, gepaart kippte das Vorzeichen
   (Selektions- statt Exit-Effekt). Selbsttest in drei Richtungen bestanden.

6) tools/check_konstanten.py -- Waechter fuer veraltete Zahlen.
   Erster Lauf: zwei Befunde, BEIDE Fehler in meiner eigenen Ableitung (Margin
   aus Balance geschaetzt statt vom Broker gelesen; Elliott ohne
   Gueltigkeitsfenster gezaehlt). Beide korrigiert.
   Danach ein ECHTER Fund: meine am 13.08. notierten "~405 EUR/Lot" sind falsch,
   der exakte Broker-Wert ist 712,84 -- die urspruenglich notierten 670 lagen
   naeher als meine Korrektur. Lehre: eine abgeleitete Zahl ist keine gemessene.
   Stand jetzt 0 Befunde.

7) Puls-Waechter bedingungs-bewusst: PULS traegt je Zeile die Vorbedingung,
   bedingte Tabellen erscheinen als Hinweis statt als Ausfall. 0 Zeilen bleibt
   IMMER ein Befund (der rec_outcomes-Fall). Grund: ein Waechter mit
   Fehlalarmen wird ignoriert -- so ist der Divergenz-Waechter verstummt.

Pipeline gruen (85 Tests), Deployment ueber deploy.py --feld circuit_breaker
verifiziert, genau eine Instanz je Port.
Nicht angefasst: Sizing (User-Entscheidung) und die 44 Backtests mit eigener
Exit-Kopie (Migrations-Regel).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 00:57:38 +02:00
Axel HocksandClaude Opus 5 9dbc5d0452 Recherche neue Datenquellen: keine empfohlen -- und eine Projektzahl korrigiert
User-Frage nach weiteren Quellen (Websites, Newsfeed, Telegram, X).

DER ENTSCHEIDENDE FILTER IST DIE HALTEDAUER (12-18 min). Damit faellt die
gesamte Fundamentaldaten-Welt weg, sie ist woechentlich:
  EIA-Lager / API-Bulletin   woechentlich   -> nur Event-Blackout (gebaut)
  CFTC COT                   woechentlich   -> nein
  Baker-Hughes Rig Count     woechentlich   -> nein
  OPEC / IEA                 monatlich      -> nein
  Tanker/Satellit            taeglich       -> zu grob UND Enterprise-Preis
Als Event-Gate ist genau das bereits umgesetzt (EIA-Blackout + econ_calendar
ueber Forex Factory). oilpriceapi.com (10k Anfragen gratis) buendelt EIA/Baker
Hughes/OPEC bequem, liefert aber dieselben woechentlichen Zahlen.

KORREKTUR EINER PROJEKTZAHL: die dokumentierten "X-API Basic 200 $/Monat, Pro
5.000 $" gelten nicht mehr. Seit Februar 2026 ist X auf pay-per-use umgestellt:
0,005 $ je gelesenem Post, Deckel 2 Mio./Monat, alte Abo-Stufen fuer Neukunden
geschlossen. 300 Posts/Tag waeren ~45 $/Monat statt 200. Der KOSTEN-Einwand von
damals ist damit hinfaellig -- der MESSUNGS-Einwand steht unveraendert: der
vorhandene Textstrom (News-Sentiment) ist gemessen nicht robust praediktiv.

Telegram-Kanaele bleiben verworfen (transportieren Screenshots; und das
Orderbuch selbst ist am 17.08. als reaktiv gemessen).

GESAMTURTEIL: keine neue Quelle empfohlen. 25 Signal-Eingriffe gescheitert, die
HL-Quelle in allen drei Auspraegungen durchgemessen, und der einzige je
gemessene grosse Hebel war die Ausfuehrung (+0,32 R). Diese Latte muesste eine
neue Quelle schlagen.

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 00:42:35 +02:00
Axel HocksandClaude Opus 5 819b2277b8 Orderbuch fuer die Empfehlung? Nein -- es ist reaktiv, nicht praediktiv
User-Frage. Neu gerechnet auf 196.720 Buch-Schnappschuessen / 17,4 Tagen mit dem
MT5-Kurs in derselben Zeile (64 % bei lebendem Broker verwertbar). Merkmale
imb1/imb5/imb20, Horizonte 60 s und 300 s, Quintile je Haelfte, nicht
ueberlappende Fenster, 95-%-Bootstrap.

Ergebnis: alle 12 Zellen haben ein Intervall, das die Null enthaelt.

DER AUFSCHLUSSREICHE TEIL IST DIE RUECKWAERTS-KONTROLLE. Neben der kuenftigen
wird auch die VERGANGENE MT5-Bewegung je Quintil berichtet -- in 10 von 12
Zellen ist die RUECKWAERTS-Spanne groesser:

  imb1  · 60 s   vorwaerts -0,05 / +0,08 bp   rueckwaerts +0,72 / +0,50
  imb1  · 300 s  vorwaerts +0,06 / -0,91      rueckwaerts +1,31 / +1,73
  imb5  · 60 s   vorwaerts -0,09 / +0,10      rueckwaerts +0,53 / +0,78
  imb20 · 60 s   vorwaerts +0,05 / +0,06      rueckwaerts +0,63 / +0,65

Das Buch spiegelt die Bewegung, die auf Pepperstone schon passiert ist. Die zwei
Ausnahmen (imb5/imb20 300 s H1) reproduzieren in H2 nicht.

Das passt exakt zum Lead-Lag-Befund vom selben Tag: Pepperstone fuehrt HL um
~6 s. Ein Orderbuch, dessen Boerse hinterherlaeuft, kann den Broker nicht
vorhersagen -- der Befund ist damit mechanistisch erklaert, nicht nur gemessen.

Oekonomisch entscheidet es ohnehin: die groesste Vorwaerts-Spanne ueber alle
Zellen ist +1,63 bp, der Pepperstone-Spread ~2,7 bp.

URTEIL: nicht nutzbar. Bestaetigt unabhaengig die Entmachtung des Verdict-Moduls
"Orderbuch" am 06.08. -- damals aus der Verdict-Telemetrie, jetzt aus den
Rohdaten der Quelle selbst.

Grenzen: nach der Entkopplung bleiben bei 300 s nur 1.252/1.254 Faelle;
gemessen wurde die Imbalance, nicht die Waende (deren Preis-Zuordnung braeuchte
die Basis-Korrektur und waere zirkulaer); 17,4 Tage = ein Regime.

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 00:36:34 +02:00
Axel HocksandClaude Opus 5 82ccf292ff Lead-Lag HL gegen Pepperstone neu gemessen: Pepperstone fuehrt, nicht HL
User-Frage, ob der Hyperliquid-Kurs dem Broker vorauslaeuft und den Trend
vorhersagen koennte. Im Projekt stand dazu ein Befund aus n=545; neu gerechnet
auf 245.073 Ticks / 20,4 Tagen -- er reproduziert, deutlich schaerfer.

KREUZKORRELATION der Renditen (k>0 = HL fuehrt, k<0 = Pepperstone fuehrt):

  Lag                                  GESAMT      H1      H2
  k=-1 (~6 s, Pepperstone voraus)      +0,455  +0,460  +0,447
  k=0  (gleichzeitig)                  +0,505  +0,507  +0,503
  k=+1 (~6 s, HL voraus)               +0,020  +0,029  +0,005

Die Asymmetrie ist die Antwort: +0,455 gegen +0,020, Faktor 23. Beidhaelftig
identisch. Kontrolle bestanden (k=0 bei +0,505 -- beide handeln erkennbar WTI).

RICHTUNGSTEST, entkoppelt (nicht ueberlappende Fenster): ueber 12 Zellen
(Vorlauf 6-30 s x Horizont 6-30 s x Schwelle 0,5-2,0 bp) liegt die Trefferquote
zwischen 47,6 und 49,8 % -- durchweg am oder unter dem Muenzwurf; fuenf Zellen
haben ein Intervall komplett unter 50 %.

Oekonomisch entscheidet es ohnehin: die Oe-Bewegung in HL-Richtung betraegt
+0,00 bis +0,14 bp (bei 30 s sogar -0,09), der Pepperstone-Spread ist ~2,7 bp --
20- bis 270-mal so gross.

URTEIL: HL taugt nicht als Vorlaufindikator. Deckt sich mit dem uebrigen Befund
zu dieser Quelle (Orderbuch-Druck 0,2-1,0 bp, Modul am 06.08. entmachtet,
Funding/Premium tragen nicht). Was HL bleibt: der 24/7-Kurs am Wochenende --
eine Verfuegbarkeits-, keine Vorhersage-Eigenschaft.

Drei methodische Punkte, ohne die es anders ausgefallen waere:
 (1) 32 % der Zeit steht Pepperstone still (Wochenende) -- ein stehender Kurs
     erzeugt zwangslaeufig den Eindruck, HL laufe voraus. Nur die 65 %
     verwertbaren Ticks bei lebendem Broker gehen ein.
 (2) Gerechnet auf ROHEN Kursen: hl_mid + basis ist bei stehendem Broker
     zirkulaer (dokumentiert 02.08.).
 (3) Nur Renditen, nie Niveaus -- kointegrierte Preisreihen korrelieren immer
     nahe 1 und sagen nichts ueber Vorlauf.

Grenze: Abtastung ~6 s, ein Vorlauf darunter waere unsichtbar -- praktisch aber
nicht ausbeutbar (1-s-Poll, WireGuard, Market-Order).

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 00:31:41 +02:00
Axel HocksandClaude Opus 5 276c8c7f07 trail_start gemessen: keine Aenderung -- und der gepaarte Test kippt das Ergebnis
User-Frage "warum wurden meine Trades automatisch geschlossen". Am Log und an
der DB beantwortet: 9 von 11 sl-Closes seit dem 13.08. waren der NACHGEZOGENE
Stop (-75,90 EUR), einer der echte Initial-SL (-113,94), und der groesste
Verlust (-215,60) war eine MANUELLE SL-Aenderung, nach der sich das Trailing
per Konstruktion abschaltet.

Der Mechanismus ist Arithmetik: der Trail sitzt 1,0xATR hinter dem Bestkurs und
erreicht den Einstieg damit erst bei 1,0xATR Gewinn -- aktiviert wird er aber
schon bei 0,3xATR. Dazwischen liegt der Stop zwangslaeufig im Verlust.

GEMESSEN (backtest_trail_start.py, 80k M5, Squeeze-Entries, nur trail_start):

  trail_start   "war im Plus, schloss im Minus"   H1 / H2
  0,3 (live)                                      47,6 % / 38,2 %
  0,8                                             27,7 % / 19,4 %
  1,0                                             12,0 % /  6,9 %
  1,3                                              0,0 % /  0,5 %

Das beobachtete Verhalten ist damit bestaetigt und quantifiziert.

ABER DER ERTRAG TRAEGT NICHT. Sequentiell sahen vier Werte in beiden Haelften
besser aus (0,5/0,8/1,3/1,5, Delta bis +0,101). Der GEPAARTE Test dreht das:
alle 12 Intervalle enthalten die Null, und in H2 kippt das Vorzeichen
(0,8: -0,006 · 1,3: -0,023 · 1,5: -0,023).

Grund: ein spaeterer Trail-Start haelt Trades laenger, also passen ANDERE Trades
in den EINEN Slot. Der scheinbare Gewinn war ein SELEKTIONSEFFEKT, kein
Exit-Effekt -- exakt die Falle aus backtest_exit_combo.py (31.07.). Der gepaarte
Vergleich ist hier der einzig gueltige Test und zugleich trennschaerfer als die
Einzel-Intervalle.

KEINE AENDERUNG. trail_start bleibt 0,3. Nichts am Live-System angefasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 09:10:39 +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 c251652d33 Enger Stop fuer die ersten N Bars: keine Aenderung (backtest_sl_staged.py)
User-Idee: SL beim Eroeffnen sehr eng, damit falsch laufende Trades frueh
geschlossen werden; laeuft er richtig, etappenweise nachziehen. Der zweite Teil
ist laengst gebaut (Phasen-Ratsche); neu war allein der zeitlich befristete
enge Stop.

Ohne Exit-Nachbau gerechnet: Lauf A (sl_atr=eng) und B (sl_atr=weit) laufen auf
DEMSELBEN Pfad; innerhalb der ersten N Bars ist der einzige Unterschied der
SL-Abstand, jeder Nicht-SL-Ausstieg faellt identisch aus. Also exakt
R = R_A wenn A vor/bei Bar N aussteigt, sonst R_B. Keine fuenfte Exit-Kopie.

80k M5, Squeeze-Entries, ruhende Order am Level, kanonischer Exit, Echtkosten,
ein Slot. Basis = durchgehend 3,4xATR_M5 (der Live-Stop, aus 121 echten Trades
als Median gegengerechnet):

  Basis          H1 -0,248 / WR 37,0 % / worst -3,73   H2 -0,107 / 44,4 % / -3,74
  N=3,  eng 0,5  H1 -0,263 / WR 23,3 %                 H2 -0,043 / 30,4 %
  N=6,  eng 0,5  H1 -0,242 / WR 22,9 % / worst -0,89   H2 -0,045 / 30,1 % / -0,96
  N=12, eng 0,5  H1 -0,240                             H2 -0,044

DER ENTSCHEIDENDE BEFUND IST STRUKTURELL: die Staffelung hat keinen Raum. Bei
N=12 steigen 269 von 279 Trades schon in Phase 1 aus (96 %) -- die mittlere
Haltedauer ist 12-18 min, "die ersten 30-60 Minuten" sind der ganze Trade. Wo
die Staffelung ueberhaupt etwas anderes tut als ein dauerhaft enger Stop (N=3),
ist sie in H1 bei allen vier eng-Werten schlechter. Wo sie gewinnt (N=6/12), ist
sie kein gestaffelter Stop mehr, sondern ein permanent enger.

Regel verfehlt: die zwei nominell besseren Kombinationen liegen in H1 bei
+0,007/+0,008, also weit unter einem Standardfehler (~0,055 bei n=279), die
Nachbarn kippen, und alle Werte sind negativ (Verlustgrade, kein Edge).

WAS ECHT IST: der Tail. Worst-Case -3,73 -> -0,83/-0,96 = Faktor 4. Bezahlt mit
der Trefferquote (37,0 -> 22,9 %). Aber die Bar-Sim ueberschaetzt enge Stops
systematisch (Kipp ~0,3xATR) -- die Verzerrung geht zugunsten der Idee, das
Nein ist damit umso belastbarer.

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 21:53:10 +02:00
Axel HocksandClaude Opus 5 02bec8fbb2 Sizing auf der echten Historie gerechnet (analyze_sizing_live.py)
Folge der S/R-Widerlegung: der Hebel zeigt auf die GROESSE. Pfad-Simulation ueber
1.278 geschlossene Trades (08.05.-13.08.), pnl/lots als groessenunabhaengiges
Ergebnis, Lots aus der simulierten Equity abgeleitet.

Zwei dokumentierte Zahlen stimmten nicht mehr und wurden aus den Daten neu
geschaetzt: EUR je $ und Lot = 86,90 (notiert 87,6), Margin je Lot ~405 EUR
(notiert 670).

DER IST-PFAD IST DIE BOTSCHAFT:
  Start 1.115,70 · Hoch 2.724,16 (05.08.) · Tief 261,36 (30.07.) · Ende 1.279,04
  Max-Drawdown 82,8 % · schlechtester Einzeltrade -381,16 EUR
  42 von 71 Tagen negativ; getragen von wenigen Tagen (04.08. +1.297).
Das Konto hat zweimal den Grossteil seines Werts verloren. Fuer unbeaufsichtigten
Betrieb ist das die entscheidende Zahl, nicht der Endstand.

VARIANTEN (Ende / MaxDD / schlechtester Trade):
  IST                    1.279 / 82,8 % / -381
  Lot-Deckel 1,5         1.362 / 82,8 % / -345   -> bringt fast nichts
  Risiko 1,5 %/Trade       680 / 54,4 % /  -77
  Risiko 0,5 %/Trade       960 / 22,2 % /  -27
  IST + Breaker 8 %/Tag  2.018 / 59,2 % / -381   -> verbessert BEIDES

ABER: ein Tag traegt 70 % des Breaker-Vorteils (07.08. +556,82 von +800,19), und
an drei Tagen kostet er (-106,85 / -96,00 / -50,77). Ohne den 07.08. bleiben
+243 EUR ueber 10 Tage. Das ist kein Makel der Messung, sondern das Wesen einer
Versicherung -- ihr Wert sitzt im Tail. Die +739 sind eine Realisierung, keine
Erwartung.

GRENZEN: die Sim sperrt nach dem Ausloesen ALLE Trades des Tages; live sperrt der
Breaker nur die autonomen. Bei einem zu 94 % manuell gehandelten Konto misst sie
damit eher eine Disziplin-Regel -- fuer das Ziel Autotrading ist sie dagegen das
richtige Modell. Confounder bei Risiko-Sizing: laeuft auf 1.118 von 1.278 Trades
(nur die mit sl_at_entry).

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 16:38:57 +02:00
Axel HocksandClaude Opus 5 1e8d700f46 "S/R-Close kappt die Squeeze-Laeufer" = widerlegt (backtest_squeeze_srclose2.py)
Meine eigene Hypothese vom selben Tag -- gemessen falsch, und zwar doppelt.

(1) BACKTEST (80k M5, 2 Halbjahre, Einstiege ueber den geteilten
squeeze_scan.scan(on_entry=...), ruhende Order am Level mit Fill bei Beruehrung,
kanonischer Exit, Echtkosten, ein Slot; identische Entry-Liste ueber alle
Varianten, variiert wird NUR der Exit):

  A) ohne S/R-Close      H1 -0,151 / PF 0,72   H2 -0,079 / PF 0,86
  B) mit p<0,35 (LIVE)   H1 -0,119 / PF 0,76   H2 -0,049 / PF 0,91   D +0,032/+0,030
  B) mit p<0,45          H1 -0,088             H2 -0,046             D +0,063/+0,033

Der S/R-Close ist in BEIDEN Haelften besser als ohne -- die vorab fixierte Regel
sagt: anlassen. Und die von mir vorgeschlagene "Abhilfe" (Close erst ab
Mindestgewinn) macht H1 schlechter (D -0,006 / -0,011).

(2) LIVE, 11 Squeeze-Trades ab 01.08.:
  sl        5 Trades  -198,17 EUR
  sr_close  4 Trades   +15,98 EUR   <- der verdaechtigte Exit hat BEIGETRAGEN
  manual    2 Trades    +8,73 EUR
Der groesste Gewinner (+77,34) kam ebenfalls ueber sl, also ueber das Trailing.
Die Groesse steckt allein auf der Verlustseite: -175,21 EUR bei 2,91 Lots =
0,695 $ = der planmaessige 2xATR-Stop. Der Hebel zeigt auf SIZING, nicht Exit.

GRENZE, nicht ueberspielt: die ABSOLUTEN Werte reproduzieren den dokumentierten
Kontrollwert NICHT (backtest_squeeze_touchfill.py: +0,124/+0,292 bei 1.092/1.807
Trades gegen -0,151/-0,079 bei 273/422). Belastbar ist allein der RELATIVE
Vergleich; "der Squeeze ist negativ" ist hier NICHT belegt.

Zwei eigene Fehler dokumentiert, weil es Fehlerklassen sind:
- erster Lauf nahm den Modul-Default ATRMIN_STD=0,12 statt des Live-Werts 0,06
  -> H1 127 gegen H2 483 Einstiege, voellig andere Population. Dieselbe Klasse
  wie das fehlende set_entry_room(0.6): ein aufgerufenes Gate ist nicht dasselbe
  wie ein aktives Gate.
- erster Entwurf haengte den Close an stop_when (prueft den BAR-CLOSE gegen ein
  0,018-$-Fenster) -> feuerte fast nie. Live prueft den laufenden Kurs im
  Sekundentakt; das Analogon ist die Bar-SPANNE.

Nichts am Live-System geaendert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 16:33:11 +02:00
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 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