0dd2e524b77298ce68ad0d82a1e7b9adf0a0308d
98
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0dd2e524b7 |
S/R-Auto-Close komplett entfernt + Circuit-Breaker als runder CB-Knopf (v=210)
(1) S/R-AUTO-CLOSE RAUS (User-Vorgabe: "die brauche ich nicht mehr").
Der Schalter stand seit dem 19.08. ohnehin auf AUS - abgeschaltet, nachdem
analyze_pbreak_live.py das P(break)-Modell live als INVERTIERT gemessen hatte
(AUC 0,452, Klassen monoton rueckwaerts). Ohne funktionierendes Gate ist der
S/R-Close faktisch der PAUSCHALE, und der ist 2x gemessen und verworfen
(Gewinner-Kappen). Die Entfernung vollzieht den gemessenen Stand nach.
WEG: _check_sr_close, set_sr_autoclose, set_sr_close_min_gain, die
Konstruktor-Felder, die %-Armierung des Gewinn-Close, drei Snapshot-Felder,
beide runtime_state-Schluessel, die Reichweiten- und Systemstatus-Zeilen,
/api/srclose und /api/srclose_min, der Knopf S/R, das Gewinn-Close-Feld, der
Toast "Bot hat am Level geschlossen".
BLEIBT: `_sr_close_hint` (App-Hinweis, P(break)-Chartlinien, Copilot-Kontext,
pbreak_predictions-Tracking), `stop_approach`, das Modell selbst und die
closed_by=sr_close-Historie in der DB. Live gegengeprueft: die drei Felder sind
aus dem Snapshot verschwunden, sr_close_hint und stop_approach sind da, beide
Endpunkte antworten 405.
Sicherung: .removed_backup/sr_auto_close_2026-08-21.py
⚠ Der Close-Alarm gilt jetzt schlicht ab jedem Gewinn (`minGain = 0`) - die
Schwelle gab es nur fuer den Auto-Close. Das ist der Zustand von vor 2026-07.
⚠ Der Test test_automatik_zeile_nennt_alle_schalter war MITGEZAEHLT und faellt
korrekt - er ist angepasst, nicht entfernt: jetzt zwei Schalter statt drei, und
die Negativ-Pruefungen ("SIG"/"S/R-Close" duerfen NICHT auftauchen) sind der
eigentliche Wert, denn ein wieder auftauchender Pfad waere ein stiller Rueckbau.
(2) CIRCUIT BREAKER als runder Knopf "CB" rechts neben BALANCE.
⚠ Farb-Logik wie vorgegeben: GRUEN = inaktiv (aus), ROT = aktiv (scharf).
Bewusst NICHT die uebliche "gruen = geschuetzt"-Lesart - hier signalisiert Rot,
dass eine Automatik eingreifen kann. Im Code und im Markup steht das dran, damit
es niemand spaeter "korrigiert".
⚠ VERSCHOBEN, nicht kopiert: zwei Elemente mit derselben ID waeren ein stiller
Fehler, weil getElementById nur das erste findet.
⚠ Beim Entfernen zwei eigene Fehler: (a) ein Slice ueber `rindex("try:")`
schnitt durch fremde Konstruktor-Bloecke und riss Kommentar-Fragmente heraus -
zurueckgesetzt und zeilenbasiert von hinten neu gemacht; (b) beim Toast-Block
eine Klammer zu viel entfernt, von `node --check` sofort gefangen.
Pipeline A-G gruen, 97 Tests, 14 render*-Funktionen, deployt und am
ausgelieferten HTML/Snapshot verifiziert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
21f2dda983 |
Anzeigefelder im aktuellen Trade noch einmal 2 px kleiner (v=208)
User-Vorgabe. Zweite Stufe, gezielt auf die ANZEIGEFELDER. `.tb-val` 0,8333rem -> 0,7222rem (15 px -> 13 px bei der 18-px-Referenz, in der die rem-Werte entstanden sind). Betrifft Richtung, Lots, Einsatz, Laufzeit, SL/TP und TP1/TP3. ⚠ BEWUSST NUR `.tb-val`: die EINGABEfelder (`.tb-field input`) bleiben bei 0,8333rem. Dort wird getippt, und unter rund 16 px zoomt iOS beim Fokus selbsttaetig ins Feld - das reisst am Handy das Layout auseinander. Die Anzeigeboxen haben dieses Problem nicht. ⚠ Umgesetzt als eigene, SPAETERE Regel statt einer Aenderung an der Sammelregel `.tb-field input, .tb-field .tb-val` - so bleiben Eingaben und Anzeigen getrennt einstellbar. Reihenfolge geprueft: die spezifische Regel steht spaeter und gewinnt. Am ausgelieferten CSS verifiziert (input 0,8333rem / tb-val 0,7222rem). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
71abb49cf7 |
Meldungen entschlackt, Bild-Modalbox, neues Muster, kleinere Trade-Schrift, M15 eingeklappt (v=207)
Fuenf User-Vorgaben in einem Durchgang.
(1) HYPERLIQUID + MUSTER + TRAILING AUS DER MELDUNGEN-KARTE. Die drei Divs sind
ENTFERNT, nicht nur versteckt; die Render-Bloecke bleiben stehen (null-sicher),
damit ein Zurueckholen eine reine HTML-Aenderung ist. Backend rechnet
unveraendert weiter (hl_ctx, patterns_tf, trail_info stehen im Snapshot).
Stufe F bekam eine dokumentierte Ausnahmeliste - sonst haette sie drei
Dauer-Treffer gemeldet, und eine Pruefung mit Dauer-Treffern wird ignoriert.
⚠⚠ DABEI ZWEI ECHTE ABSTUERZE GEFUNDEN - und der Weg dahin ist der Punkt.
`hl-note` wurde ueber das Auffang-`$` geholt; nach dem Entfernen des Elements
griffen ZWEI Zweige ungeschuetzt auf `hlEl.classList` zu. Im Browser ein
TypeError mitten im Render = das GESAMTE Dashboard friert auf Altwerten ein.
Die Render-Probe blieb zunaechst GRUEN - ihr eigener blinder Fleck: die
DOM-Attrappe lieferte fuer JEDE ID ein Element, `$streng` konnte darin also NIE
`null` zurueckgeben. Genau der Fall, fuer den es `$streng` gibt, war ungeprueft.
Behoben: die Attrappe kennt jetzt die echten IDs aus index.html
(`getElementById: id => HTML_IDS.has(id) ? el() : null`) - und meldete die
beiden Zweige im selben Lauf. Danach beide Waechter ergaenzt.
(2) BILD-MODALBOX. Klick auf ein Chartmuster oeffnet es gross.
⚠⚠ BEWUSST OHNE BIBLIOTHEK: ein Lightbox-Paket waere 15-40 KB plus ein zweites
Bedienkonzept fuer ~30 Zeilen Code. Das Dashboard laeuft nur ueber WireGuard,
ein CDN ist gar nicht erreichbar; das Projekt hat aus demselben Grund Tailwind
abgelehnt und am 05.08. die vendorte lightweight-charts (164 KB) entfernt.
Delegierter Klick auf `document`, weil die Kacheln bei JEDEM Render neu erzeugt
werden - ein Handler am <img> waere nach dem naechsten Snapshot weg.
Grosse Fassung (1408 px, ~133 KB) liegt getrennt unter muster/gross/ und wird
ERST beim Klick geladen; die Kachel bleibt bei 25 KB. Esc und Klick auf den
Hintergrund schliessen.
(3) NEUES BILD gescannt: "Inverse Tasse+Henkel.jpg". `inv_cup` hatte bis dahin
ausdruecklich KEIN Bild ("lieber keins als ein falsches") - jetzt zugeordnet.
Damit 16 Muster, keins ohne Datei, keine Datei ohne Zuordnung.
(4) SCHRIFT IN DER TRADE-LEISTE um 2 px (bezogen auf die 18-px-Referenz)
verkleinert - 4 Regeln: Ueberschrift, Feldbeschriftungen, Werte/Eingaben,
Knoepfe.
⚠ Erster Versuch nahm alles zwischen `.tb-title{` und `.mg-row` und traf 80
Regeln statt 4 - die halbe Oberflaeche. Zurueckgesetzt und namentlich
aufgezaehlt. Ein Zeilenbereich ist kein Selektor.
(5) M15-KARTE PER DEFAULT EINGEKLAPPT. Das `open` am ersten <details> ist weg.
⚠ Zusaetzlich der localStorage-Schluessel gebumpt (oil_m15_akk -> oil_m15_akk2):
bei jedem, der die Karte je aufgeklappt hatte, stand dort `true`, und das
gewinnt gegen den neuen Default. Ein neuer Schluessel setzt genau EINMAL
zurueck; danach merkt sich die Karte die eigene Wahl wie bisher.
Pipeline A-G gruen, 97 Tests, 14 render*-Funktionen (Fixture UND leerer
Snapshot), deployt und am ausgelieferten HTML/JS verifiziert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
06024dd0c1 |
Muster-Bilder ins Dashboard hinter die Meldungen + M15-Karte sagt jetzt, WARUM kein Setup (v=205)
(1) BILDER INS DASHBOARD (User-Vorgabe). Das Raster `#pt-tfgrid` sitzt jetzt in
einer eigenen Karte `#card-muster` direkt hinter der Meldungen-Karte, vor der
Breakout-Karte. VERSCHOBEN, nicht kopiert: eine zweite Kopie haette eine
doppelte Element-ID erzeugt, und getElementById liefert dann immer nur die
erste - die zweite Karte waere still leer geblieben. Im Tab "SIG Live" bleibt
die M30-Detailliste mit Trigger und Kursziel (sie traegt das Verdict-Gewicht
0,25; die Bilder tragen keins).
Geprueft am ausgelieferten HTML: 0 doppelte IDs, pt-tfgrid genau 1x, Reihenfolge
Meldungen -> Muster -> BRK, Tag-Balance 20/20.
(2) "DIE TP IN DER M15 KARTE SIND NICHT MEHR SICHTBAR" - kein Fehler, aber die
Anzeige war schuld. Der Setup-Block verlangt `sb && erl && nah && atr>0`, und
`erl` (die erlaubte Richtung) kommt aus dem VETO. Live steht bias.verboten auf
None, weil M30 flach ist (m30=0) - also gibt es keine erlaubte Richtung, und
ohne Richtung sind Entry Zone, Stop und TP1-3 nicht bestimmbar. Genau so ist es
am 10.08. entschieden worden ("kein Veto - Richtung offen, kein Ziel
bestimmbar").
Der Block verschwand dabei aber KOMMENTARLOS. Ein leeres und ein blockiertes
Feld sahen identisch aus - dieselbe Klasse wie "Slot frei" beim Breakout und wie
das schweigende Trailing, beide heute aus demselben Grund repariert. Jetzt steht
dort: "Kein Setup: kein Trend-Veto (M30 flach) - ohne erlaubte Richtung sind
Entry Zone, Stop und TP nicht bestimmbar." Die beiden anderen Abbruchgruende
(kein Level in Reichweite / ATR fehlt) werden ebenfalls benannt.
Pipeline A-G gruen, 97 Tests, 14 render*-Funktionen laufen durch (Fixture und
leerer Snapshot), deployt und am ausgelieferten HTML verifiziert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
02bede7ef9 |
Chartmuster je Zeitebene als Bild + M1/M5 in der Meldungskarte (v=204)
User-Vorgabe: die hinterlegten Muster-Bilder sollen je Minuten-Chart das gerade entstehende Muster zeigen, M1 und M5 zusaetzlich in der Meldungskarte. BILDER: 15 Vorlagen aus /Chartmuster, 436-611 KB je Stueck (7,5 MB gesamt). Das Dashboard uebertraegt ~14 KB je Snapshot ueber WireGuard - ein Originalbild waere das 40-fache. Verkleinert auf 520 px / JPEG q80 nach web/muster/: 7,5 MB -> 379 KB (Faktor 20), im Frontend zusaetzlich loading="lazy". Die Originale sind gitignored, nur die Web-Fassungen kommen ins Repo. DETEKTOR: core/patterns.py bekommt die Zeitebene als PARAMETER. Der Default bleibt M30 und damit bitgleich - `PatternDetector()` speist das Verdict-Gewicht 0,25, eine stille Verschiebung dort waere eine Strategie-Aenderung durch die Hintertuer. Daneben laufen vier weitere Instanzen (M1/M5/M15/H1) mit gestaffelten Refresh-Zeiten (20/25/35/60 s), damit sie den mt5_lock nicht im Pulk belegen. Sie haben KEINE Stimme. Neu Snapshot `patterns_tf`: je Zeitebene das STAERKSTE Muster (bestaetigte vor sich bildenden, dann Symmetrie-Guete; ungueltige fallen raus) samt Bildnamen ueber die Karte `patterns.BILD`. Doppeltop/-boden, Dreifach-Top/-Boden und Flagge bull/baer teilen sich je ein Bild (die Vorlagen zeigen beide Richtungen); `inv_cup` bekommt KEINS - lieber kein Bild als ein falsches. ⚠⚠ REINE ANZEIGE, und das steht auch dran. Die Muster-Klasse ist als SIGNAL gemessen und verworfen (Ziel-Trefferquote nur 13-38 %, backtest_patterns.py), und auf M1 ist sie am schwaechsten: dort liegt der Spread bei 0,319xATR, ein Muster ueber wenige Bars ist weitgehend Rauschen. Kein Verdict-Gewicht, kein Trade-Trigger; die Tooltips nennen die Messung. ⚠ Beim Bau zwei eigene Fehler gefangen: (1) ich hatte die Feldnamen GERATEN - es heisst `type`, nicht `typ`, und der Status ist "confirmed"/"forming"/ "invalidated". Ein falscher Schluessel haette still None geliefert, die Karte waere leer geblieben ohne jede Fehlermeldung. (2) Der Emoji-Surrogat-Abbruch zum sechsten Mal - die .tmp-Regel hat app.js erneut gerettet (0 Bytes verhindert), danach mit literalen Zeichen statt \u-Escapes geschrieben. Live verifiziert: M1 Doppelboden, M5 Tasse+Henkel, M15 aufsteigendes Dreieck, M30 Doppeltop; alle Bilder HTTP 200 (22-28 KB). Pipeline A-G gruen, 97 Tests, 14 render*-Funktionen laufen durch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
437ab56598 |
Trailing tat nichts - beide Gruende waren richtig, nur unsichtbar (v=203)
User: "trailing scheint nicht zu funktionieren wenn man es einmal manuell
aktiviert hat und dann wieder einschaltet."
AM LOG UND AM ZUSTAND NACHGEPRUEFT - es lief die ganze Zeit:
19:30:52 Manuelle SL/TP-Aenderung erkannt (SL 87.297) -> Trailing abgeschaltet
19:31:01 AKTIVIERT ATR=0.5689 (M30) mult=1.0x
danach phase=Init, HW 87.39, enabled=true, trail_mult=1.0
`toggle()` setzt alles sauber zurueck (High-Water, Phase, _last_sl/_last_tp,
TF und Mult werden neu eingefroren). Es war KEIN Defekt.
WARUM ES TROTZDEM NICHTS TAT - zwei Gruende, beide korrekt:
(a) Phase "Init": der Trail springt erst ab `trail_start` an, und der steht
seit HEUTE auf 1,3xATR (war 0,3). Der Gewinn lag bei 0,13xATR - also
Faktor 10 zu frueh. Wer die alte Einstellung gewohnt ist, erwartet den
Trail zehnmal frueher als er kommt.
(b) Er lockert einen Stop NIE. Nach der Handeingabe lag der SL bei 87.300,
der Trail haette HW-1,0xATR = 86.821 gewollt - deutlich schlechter. Also
zu Recht keine Aenderung. Um 87.300 zu schlagen, braeuchte es HW >= 87.869.
DER EIGENTLICHE MANGEL WAR DIE SICHTBARKEIT: die Trailing-KARTE ist seit dem
22.07. ausgeblendet (User-Vorgabe). Damit gab es KEINE Stelle mehr, an der man
Phase, High-Water oder den gewollten Stop sehen konnte - "es tut nichts" und
"es wartet zu Recht" sahen identisch aus.
GEBAUT: `engine._trail_info()` -> Snapshot `trail_info` -> Zeile `#trail-note`
in der Meldungen-Karte. Live:
"Trailing wartet - springt ab 1.3xATR Gewinn an (jetzt 0.38x, also ab Kurs
88.054)."
Drei weitere Zustaende: "Trailing AUS - nur der Broker-SL schuetzt", "laeuft,
zieht aber NICHT nach: sein Stop waere X, der gesetzte Y ist enger", und
"laeuft - zieht den Stop auf X nach".
⚠ Nur ZUSAMMENGESETZT aus dem, was der Snapshot ohnehin enthaelt - kein
zweiter Rechenweg (der Konsens-Pfeil-Fehler).
⚠⚠ BEINAHE-FEHLER beim Bau, gefangen: der Block landete in `renderKontext(snap)`,
mein Code las aber `d.trail_info`. Ein ReferenceError haette den GESAMTEN Render
abgebrochen (Dashboard friert auf Altwerten ein) - genau die Klasse, die am
01.08. schon einmal zugeschlagen hat. `node --check` sieht das NICHT. Gefunden,
weil ich die umgebende Funktion nachgelesen habe, und danach mit einem
Minimal-DOM gegengeprueft (snap / leer / null - alle drei laufen durch).
NEBENBEI: der Kommentar an `_TRAIL_START_ATR` sagte weiterhin "0,3", der Wert
ist 1,3. Genau diese Zahl macht den Unterschied, um den es hier geht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
fe01596020 | BRK-Blockade sichtbar machen + runtime_state-Ueberstimmung melden | ||
|
|
0966caf1b8 |
G/V-Trennung geprueft: Adoptions-Sperre riss bei JEDEM Neustart auf
User: "ueberpruefe ob wirklich die G/V und G/V BRK Anzeigen stimmen, besonders bei gleichzeitig laufenden Trades. Die Anzeige darf jeweils nur den eigenen Slot anzeigen." FRONTEND SAUBER: #hdr-pnl liest nur d.position, #hdr-pnl-brk nur d.position_brk - keine Summe, kein Fallback. Aber das ist die falsche Stelle zum Suchen: stehen im Backend beide Felder auf derselben Position, kann keine Anzeige das mehr richten. Geprueft wurde deshalb die AUSWAHL in TradeManager._refresh_locked. ⚠⚠ FUND 1 - die Sperrliste kannte nur zwei von DREI Quellen eines BRK-Tickets: trader_brk.ticket ✅ nur im Speicher _pending_tickets ✅ nur im Speicher _brk_restore ❌ FEHLTE - und nur das ueberlebt den Neustart Nach einem Neustart sind die ersten beiden leer, und die Reihenfolge im _pos_loop besiegelt es: trader.refresh() laeuft DREI Zeilen vor _rebind_brk(). Slot 1 greift die BRK-Position also, bevor sie zurueckgebunden werden kann. _rebind_brk erkennt das zwar und bricht ab - damit ist der Schaden aber nur festgestellt, nicht behoben: die BRK-Position haengt am falschen Slot, ihr G/V steht links statt rechts, und "G/V BRK" zeigt "—". Danach sieht alles normal aus, was es besonders schwer sichtbar macht. Behoben ueber getattr(..., None), also unabhaengig davon, WANN das Attribut gesetzt wird - genau die Reihenfolge-Falle, die in zwei Tagen zweimal zugeschlagen hat. ✅✅ FUND 2 - zwei verschiedene Rechnungen nebeneinander. Bei geschlossenem Markt zeigt Slot 1 seit dem 01.08. eine HL-Schaetzung (pnl_hl), der BRK-Slot bekam die nie und zeigte den EINGEFRORENEN Broker-Wert, ohne dass man es der Anzeige ansieht. Neu pnl_hl_brk, mit ≈ markiert. Geprueft statt angenommen, dass _tick_size/_tick_value am BRK-Slot gesetzt sind. ✅ day_pl.open summiert korrekt BEIDE Slots - die Summe gehoert dorthin, die Trennung in die beiden G/V-Felder. BELEG - tests/test_slot_gv.py, 6 Tests auf dem ECHTEN TradeManager (Broker gestubbt): zwei Positionen gleichzeitig je im eigenen Slot · Slot 1 adoptiert die BRK-Position nicht · Pending-Fill wird nicht weggeschnappt · der BRK-Slot adoptiert nie · plus die Regressionsprobe, die den alten Zustand festhaelt. NEUE PIPELINE-STUFE E (tools/check_slots.py): die Sperrliste muss alle drei Namen erwaehnen. Mutationsprobe: Merker entfernt -> Exit 1. ⚠⚠ Ehrlich zur Arbeitsteilung: der pytest belegt den MECHANISMUS, baut die Lambda aber selbst nach und bleibt bei der Mutation gruen. Erst die statische Stufe belegt, dass die ENGINE sie richtig verdrahtet. Keine der beiden allein haette gereicht. ⚠⚠ NEBENBEFUND, korrigiert: mein Schreib-Helfer hat SECHS Dateien still von LF auf CRLF gedreht (io.open(...,"w") uebersetzt auf Windows). Mein erster Check mit `grep -c $'\r$'` meldete faelschlich 0 - erst die BYTE-Zaehlung zeigte 8959 CR in CLAUDE.md. Alle sechs auf LF zurueckgesetzt. core.autocrlf=true haette es im Repo normalisiert, im Arbeitsbaum aber nicht. Live verifiziert: Slot 1 T=50396824 (+10,34), BRK flat, day_pl.open 10,34 - kein gemeinsames Ticket. Deploy mit --feld pnl_hl_brk, alle 5 Schritte gruen. ⚠ Noch nicht beobachtet: ein Neustart MIT offener BRK-Position - der Fall, den der Fix adressiert. v=201. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3e275e7515 |
Slot-Close-Knoepfe groesser und in CLOSE-Farbe; grosser CLOSE-Knopf entfernt
User-Wunsch, drei Teile.
(1) GROESSER: font-size 0.72 -> 1rem, Polster 0.17/0.33 -> 0.39/0.61rem, fett.
(2) FARBE wie der bisherige CLOSE-Knopf: background #2d2000, color var(--accent),
Rahmen #4a3600 - derselbe Bernstein-Ton, damit "schliessen" ueberall gleich
aussieht.
(3) Grosser CLOSE-Knopf aus der Aktionsleiste ENTFERNT.
⚠⚠ DER HAKEN AN (3), geprueft bevor entfernt: der Knopf hatte ZWEI Aufgaben im
Render, nicht nur das Klicken - `disabled`, wenn keine Position offen ist, und
BLINKEN beim Close-Alarm (`closeBtn.classList.toggle("blink", closeAlert)`).
Haette ich ihn nur aus der HTML geloescht, waere der Alarm still geworden: nur
noch Ton, keine Sichtbarkeit. Beides ist mitgezogen:
- `close-main` ist disabled, wenn Slot 1 leer ist; `close-brk`, wenn BRK leer
ist (vorher gab es diese Unterscheidung gar nicht)
- `.px-close.blink` nutzt dieselbe `blkClose`-Keyframe wie vorher, und weil
die Farben identisch sind, sieht das Blinken exakt aus wie zuvor
⚠ Es blinkt NUR der Slot-1-Knopf: dort entstehen `sr_close_hint` und der
Flip-Alarm. Ein blinkender BRK-Knopf ohne Anlass waere ein Fehlsignal.
FUNKTIONAL GEPRUEFT (drei Zustaende gegen ein Minimal-DOM):
hasPos=1 hasBrk=0 alarm=0 -> main aktiv, brk gesperrt, kein Blinken
hasPos=0 hasBrk=1 alarm=1 -> main gesperrt, brk aktiv, Blinken
hasPos=1 hasBrk=1 alarm=1 -> beide aktiv, Blinken
0 verbliebene `data-side="close"`-Referenzen in JS und HTML.
⚠ `.btn.close` und `.btn.close.blink` bleiben in der CSS stehen - ungenutzt,
aber harmlos, und sie machen ein Zurueckholen des grossen Knopfs zu einer
Ein-Zeilen-Sache.
v=200 (HTML, JS, style.css und der Cache-Waechter `data-html-v` alle
gleichgezogen und am ausgelieferten Stand verifiziert).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
54bcc9f81d |
Cache-Waechter: die Seite meldet selbst, wenn HTML und JS nicht zusammenpassen
User: "die buttons werden nicht angezeigt" (Close-Knoepfe an den G/V-Anzeigen).
DIAGNOSE: serverseitig war alles korrekt - HTML, CSS und JS werden mit v=199
ausgeliefert, der Knopf steht im gelieferten Markup, die CSS-Regel ist da, und
KEINE andere Regel versteckt ihn (globale button-Regeln gibt es nicht, .px setzt
nur Schrift). Der Server sendet no-store, und last-modified stimmt mit der
Platte ueberein. Es bleibt der Browser-Cache.
⚠⚠ URSACHE IST STRUKTURELL, nicht einmalig: `index.html` wird vom `?v=`-Bump
NICHT gebustet - nur app.js und style.css. Trifft neues JS auf eine alte,
gecachte HTML, fehlen die neuen Elemente. Das Auffang-`$` verhindert den
Absturz, aber die Anzeige ist STILL unvollstaendig. Real jetzt zum zweiten Mal:
19.08. (M5-/RSI-Zeile) und 20.08. (diese Knoepfe) - beide Male sah der Server
korrekt aus und der Browser zeigte Altes, und beide Male habe ich es von Hand
diagnostizieren muessen.
GEBAUT: `<body data-html-v="199">` plus eine Konstante `_JS_V` in app.js. Weichen
sie ab, blendet die Seite unten ein rotes Band ein ("Alte Seite im Cache, HTML
v198, JS v199 - hier tippen zum Neuladen"); ein Tipp darauf laedt mit frischem
Query-String neu.
⚠ Bewusst SICHTBAR statt nur Konsole - die sieht am Handy niemand.
⚠ Die Version wird beim `?v=`-Bump aus der HTML gelesen, muss also nicht getrennt
gepflegt werden.
BEIDE RICHTUNGEN VERIFIZIERT: HTML v198 gegen JS v199 -> Banner erscheint;
gleiche Version -> kein Banner.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
d881636e1b |
Close-Knopf je Slot, direkt vor der jeweiligen G/V-Anzeige
User-Wunsch. Zwei Slots heissen zwei Close-Moeglichkeiten - bisher gab es nur
den grossen CLOSE-Knopf, und der schliesst seit heute BEIDE. Neu je ein kleines
✕ vor "G/V" (Slot 1) und vor "G/V · BRK", rechtsbuendig gespiegelt.
BACKEND: `engine.close(slot=None)` - None/"" = beide (Verhalten des grossen
Knopfs, unveraendert), "main" = nur Slot 1, "brk" = nur der Breakout-Autotrader.
`POST /api/order {"side":"close","slot":"brk"}` reicht ihn durch; ohne `slot`
ist das Verhalten bitgleich zu vorher.
⚠ Sicherheitsabfrage NUR im Minus - dieselbe Regel wie beim grossen Knopf: im
Plus direkt schliessen, im Minus nachfragen. Hartes Blockieren ist im Projekt
verworfen, aber ein versehentlicher Klick soll kein Geld kosten.
⚠⚠ EIGENER FEHLER auf dem Weg, gefunden bevor er live ging: mein erster Entwurf
las den P&L aus `_letzterSnap` - eine Variable, die es NICHT gab. Das ist exakt
der ReferenceError, der am 19.08. den halben Render abgeschossen hat, nur
diesmal im Klick-Pfad (er waere erst beim Druecken geknallt, also genau dann,
wenn man schliessen will). Behoben durch `letzterSnap`, das `_applySnapshot`
jetzt fuehrt - die Variable fehlte im Projekt tatsaechlich, Klick-Handler hatten
bisher keinen Zugriff auf den aktuellen Zustand.
Verifiziert: 2 Knoepfe im ausgelieferten HTML, span/div/button ausgeglichen,
keine doppelten IDs, node --check, Render-Probe, 91 Tests und die volle Pipeline
gruen. Deploy verifiziert (v=199).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
bf7e382818 |
Auto-Signal-Entry (SIG) komplett entfernt inkl. Button (v=166)
User-Entscheidung. Der Pfad war seit 01.08. aus und auf BEIDEN Ausfuehrungs-Achsen gemessen negativ: Markt-Einstieg in allen 8 Feldern, ruhende Order mit Touch-Fill -0,392/-0,338 in allen 6 und damit sogar schlechter als Markt. Die +0,35/+0,32 aus backtest_auto_signal_v3.py galten in Variante B (Fill beim Close-Bruch) und waren Look-ahead - Aufschlag 0,77-0,85 R. Ursache strukturell: das Bestaetigungs-Level _pend WANDERT. Nebenbei entfaellt der offene Churn-Defekt (4x setzen/stornieren in 76 s bei identischem Level, gefunden 06.08., nie behoben). Entfernt: _check_auto_signal, set_auto_signal, der Signal-Zweig in _pending_ziel, /api/autosignal, Button + Handler, vier Snapshot-Felder, die auto_signal*/signal_pending_entry-Leser. Geblieben: AUTOSIG_*-Trades in der DB, die Backtests, wave_rec.breakout (speist block_reason) und _confirm_breakout selbst. Sicherung: .removed_backup/auto_signal_2026-08-12.py + Git. Das Risiko war nicht SIG, sondern der GETEILTE Pending-Manager (zwei getrennte Manager wuerden sich gegenseitig stornieren). Deshalb wurde das Squeeze-Verhalten VOR dem Eingriff in tests/test_pending_ziel.py festgenagelt - 7 Tests, vorher gruen, laufen unveraendert weiter. Zwei Folgefehler fing die Pruefkette sofort: ruff F821 ein verwaistes _t, py_compile ein dangling if. Zwei Tests wurden mitgezogen statt geloescht - test_signal_fill_long ist jetzt umgedreht (unbekannte Quelle darf NICHT als Squeeze durchgehen). Live verifiziert: alle vier Snapshot-Felder weg, Endpunkt tot, auto_squeeze/squeeze_pending unveraendert, 67 Tests gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5fb1d7e268 |
M15-Karte: Flacker-Ursache gemessen, Hysterese + EINE Quelle (v=165)
Die Karte wechselte den Zustand alle 12 Sekunden (~1.030/Tag) - der Grund, warum ihre Selbstmessung so stark geclustert war. Mein erster Verdacht (das Level im Wechsel-Schluessel) war falsch. Ausgezaehlt ueber 3.525 Zeilen: status 32,9 %, lesart 32,7 %, level allein nur 7,6 %. Das Level zu entfernen braechte 3.525 -> 3.248, also nichts. Der Zustand selbst zappelt: gap <= 0,5 und das 45/55-Band von P(break) sind stetige Groessen um ihre Schwelle. Das Projekt hatte die Loesung schon (analyze_pbreak_flicker.py, 14.07.: Hysterese +-5 Pp) - die Karte umging sie, weil sie P(break) selbst neu rechnet. Jetzt dieselbe Hysterese auf beide Schwellen: Status gruen ab 0,50 / zurueck erst ueber 0,60; Lesart gerichtet ab 40/60 / zurueck erst innerhalb 45/55. Simuliert: 64 % weniger Wechsel. Zweiter, groesserer Befund: Status und Lesart wurden an DREI Stellen unabhaengig gebildet und wichen bereits ab - der Logger kannte den "kein Veto"-Fall des Frontends nicht, protokollierte also einen anderen Zustand als angezeigt wurde. Jetzt eine Quelle: _m15_setup liefert status/lesart/nah im Snapshot, Logger und Frontend lesen sie. Die alten 3.525 Zeilen sind mit den neuen nicht vergleichbar; die Selbstmessung beginnt faktisch neu (Stichtag 12.08.). Kein Verlust - sie liess vorher ohnehin kein Urteil zu. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e882d795a6 |
M15-Karte: Selbstmessung entkoppelt - 60 % waren 53 %
User fragte nach einer zweiten Karte auf M5. Die Antwort haengt daran, ob die bestehende traegt - und sie misst sich seit 08.08. selbst. Befund: die Karte zeigte 60 % Trefferquote. Zwei Gruende, warum das nichts belegt. (1) Geclustert: m15_accuracy nahm die letzten 200 Zeilen ohne Entkopplung, bei ~990 Zustandswechseln/Tag sind das fuenf Stunden derselben Marktlage. Aus 2.302 rohen bleiben 114 unabhaengige. (2) Regime: das Fenster lief +4,93 $, und roh liest die Karte "auf" zu 62 % richtig und "ab" zu 46 % - das ist der Trend. Entkoppelt: 53-54 %, KI [46 ... 63] - enthaelt die 50. Der handlungsrelevante Zustand (gruen + gerichtet) liegt bei 45,5 %. Behoben: m15_accuracy entkoppelt (Schluessel Level+Stunde) und meldet beide Zahlen. Anzeige jetzt 53 % statt 60 %. Antwort auf die M5-Frage: nein, jetzt nicht - die erste Karte hat kein Urteil, M5 waere teurer (0,193 gegen 0,104), die M5-Information ist grossenteils schon da (Gate 3b rechnet bereits auf M5), und eine zweite Karte verdoppelt die Drift-Flaeche. Offen benannt: die Karte flackert (~990 Wechsel/Tag). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8584b2b776 |
Entry-Dialog beim Eroeffnen entfernt (v=163)
User-Vorgabe: "entferne auch die Warnung beim Eroeffnen von Trades". LONG/SHORT feuern jetzt sofort. Was wegfaellt: die 7-Punkte-Checkliste und der Ausrichtungs-Split im Moment der Entscheidung - letzterer zeigte die einzige beidhaelftig robuste Zahl des Projekts (gegen das Signal -6,60 EUR je Lot ueber 1.216 Trades). Bewusste User-Entscheidung, kein Messergebnis; liegt aber auf der Linie "sichtbar machen, nicht bevormunden" (harte Blocks waren nie eingebaut, Uebersteuerungen liefen 68 % Trefferquote). Backend unberuehrt: _entry_checklist rechnet weiter und steht im Snapshot, die Zahlen bleiben auswertbar. Die Verlust-Close-Abfrage bleibt - sie schuetzt vor einem Fehlklick, nicht vor einer Entscheidung. Zurueck: const ENTRY_DIALOG = true. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e8de83143c |
M15-Karte: Klartext-Kopfzeile (v=162)
User: "kannst du die M15-Empfehlung vereinfachen, wie: jetzt long/short
zu xxx Prozent". Der Wunsch ist berechtigt - die Karte war sieben
Zeilen Technik. Die Form nicht: eine Richtungs-Prognose ist ueber 1.071
Live-Episoden mit 48-51 % Trefferquote gemessen (frei AUC 0,52
IN-sample), und die Prozentzahl war als conf_pct nicht kalibriert, in
H2 invertiert. Genau daran ist die Gesamtempfehlung gescheitert und
wurde entfernt - es waere der vierte Rueckfall dieser Karte in die
Veto->Richtung-Falle gewesen.
Gebaut ist stattdessen eine Zeile, die sagt WAS ZU TUN IST, mit der
einen kalibrierten Prozentzahl: P(break) des Einstiegs-Levels (AUC
0,65 oos) - eine Aussage ueber die Struktur, nicht ueber den Trade.
gruen JETZT: LONG-Order bei 78,768 (Abpraller) - haelt zu 75 %
- Ziel 79,033 - SHORT meiden
gelb JETZT: warten auf das Level - erlaubt waere LONG
gelb JETZT: kein Trend-Veto - die Karte gibt hier keine Richtung
rot JETZT: nicht handeln - Spread frisst den Edge
"Erlaubt" heisst nicht "empfohlen"; belegt ist nur, dass die
Gegenrichtung kostet (-6,60 EUR/Lot). 45-55 % bleibt ohne Richtung.
Reine Formulierung, keine Aenderung der Gate-Semantik. Frontend-only,
kein Neustart noetig.
Beim Bau in die Anfuehrungszeichen-Falle gelaufen (ASCII-Quote als
deutsches Schlusszitat -> Unexpected token). node --check hat es
gefangen - genau dafuer wurde es eingebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
4eb92bf192 |
Telegram: Close-Benachrichtigung ab Schwelle + Auto-Squeeze wieder an
Diagnose zu "ich bekomme keine Telegram-Nachrichten mehr": der Kanal war intakt (getMe/getChat ok, Testnachricht zugestellt, keine einzige Fehlermeldung im Log, Tagesreport kam taeglich). Ursache war, dass ALLE NEUN sendenden Ausloeser aus waren - Auto-Squeeze (ueber runtime_state.json, unbemerkt), Auto-Signal, S/R-Close, Flip-Close, 15-Minuten-Regel, Circuit-Breaker und die drei Notfall-Stop-Modi. Jede Abschaltung war fuer sich begruendet; zusammen ergaben sie eine Stille, die niemand beschlossen hatte. Gebaut: engine._check_close_notify - Telegram bei JEDEM geschlossenen Trade ab close_notify_min_eur (50, 0 = aus). Haengt an keiner Automatik, feuert also auch bei manuellem Close und Broker-SL. Der -87-EUR-SL vom 10.08. kam bisher wortlos. Schwelle aus den Daten: bei ~17 Trades/Tag rund 2,4-6,1 Meldungen/Tag, erfasst 54-80 % des bewegten Geldes. Absolute Euro-Schwelle altert mit der Positionsgroesse - bewusst so, ein Mensch denkt in Euro. Der Unterschied zum frueher entfernten Push ist die Schwelle, und sie liegt in der Engine statt in der DB-Schicht. Vorgemerkt statt sofort gesendet, weil der Flat-Zustand dem DB-Schreiber einen Tick voraus sein kann (exit_time IS NULL heisst "noch nicht fertig"). - tests/test_close_notify.py: 7 Tests, Netz abgefangen - Mutationsprobe in beide kritischen Zweige, beide gefangen - Snapshot-Feld close_notify_min (belegt die Schwelle im Prozess) - Auto-Squeeze wieder AN ueber /api/autosqueeze (ini + runtime_state) - v=161 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
47c596ed70 |
M15-Karte: Gate 3b zeigt Motor-Block + RAUM je Richtung
Anlass Trade #49671601 (-87,03 EUR). Die Praemisse "SL trotz LONG- Empfehlung" stimmte nicht: 138 Zeilen zwischen Ein- und Ausstieg, 100 % WARTEN (entry_room 76 %, breakout_pending 19 %, min_conf 5 %). Gesehen wurde "verboten: SHORT" - ein Veto. Dritter Fall derselben Veto->Richtung-Umwandlung in dieser Karte (Code 08.08., Geometrie 10.08. frueh, jetzt die Lesart). Der eigentliche Befund: entry_room und Gate 3 lesen DIESELBE Tatsache ("ein Level ist nah") mit umgekehrtem Vorzeichen. Beide gemessen, beide richtig - ueber verschiedene Trades (Markt-Einstieg mit dem Level als Hindernis vs. ruhende Order AM Level). Die Karte zeigte nur die gruene Haelfte; die Block-Grund-Zeile war mit der Gesamtempfehlung verschwunden. Gebaut: Zeile 3b (#m15-motor) mit block_reason im Klartext + Raum je Richtung. Reine Anzeige. Das Status-Banner bleibt bewusst unveraendert - es auf gelb zu ziehen waere eine Strategie-Aenderung, und die einzige Live-Zahl dafuer (-9,91 vs +3,24 EUR/Lot, n=76) hat ein KI, das die Null enthaelt. - wave_rec.room_info(): EINE Implementierung fuer Gate und Anzeige, _room_gate rechnet jetzt darueber (kein Nachbau) - tests/test_room_info.py: Bitgleichheit ueber 2.000 Zufallslagen x 3 Signale, Gate feuerte >300x; Grenzfall-Test fuer die Rundung - v=160 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5474c2be61 |
Gate 4 der M15-Karte: Ziel nur noch in der ERLAUBTEN Richtung
User-Fund: Karte zeigte "verboten SHORT" (= LONG erlaubt) UND ein Ziel 0,15 $ UNTER dem Kurs. Die Arithmetik war korrekt - aber fuer die verbotene Richtung. Ursache: das Ziel war schlicht das entferntere der beiden Level (max nach gap), ohne Richtungspruefung. Strukturell steckte dahinter ein Fade-Trade (Gegenlevel als Ziel = Mean Reversion) in einer Kette, deren Gate 2 ein Trendfilter ist - zwei unvereinbare Konzepte. Damit derselbe Fehler, wegen dem die Gesamtempfehlung entfernt wurde: aus einem VERBOT wird ueber die Hintertuer wieder eine RICHTUNG. Fix nach der gemessenen Population (backtest_m15_gates.py): Einstieg am naechstgelegenen Level, Richtung = die vom HTF erlaubte. Ein Ziel nur, wenn es jenseits dieses Einstiegs in der erlaubten Richtung liegt; sonst "kein Ziel" mit Grund statt einer erfundenen Zahl. Richtung steht jetzt im Anzeigetext. - tests/test_m15_ziel.py (6 Tests, Invariante ueber 32 Konstellationen) - Mutationsprobe: alte Zeile zurueck -> 4 von 6 Tests fallen - deploy.py --feld unterstuetzt jetzt Punktpfade (m15_setup.ziel_grund) - v=159 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |