06024dd0c1d69cec1879d6e6d9c23e571770c096
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fd2ca46dc0 |
Ruhende Orders: aufraeumen statt liegenlassen (User-Vorgabe)
User: "was sind ruhende orders. Loesche die wenn der trade nicht eroeffnet werden kann." Anlass: MT5 zeichnete SL/TP-Linien, obwohl keine Position lief. Das waren die liegenden Stop-Orders des Breakout-Traders - MT5 stellt jede Pending-Order samt mitgeschicktem SL selbst dar. Der Bot exportiert NIE SL/TP ins Chart (0 Treffer im .mq5, keine SL-Zeile in der CSV). Kein Anzeigefehler. ZWEI ECHTE VERWAISUNGS-PFADE GEFUNDEN. _manage_squeeze_pending stieg VOR dem Aufraeum-Block aus, wenn squeeze_pending_entry=false oder kein Symbol da war. Die Orders sind ORDER_TIME_GTC - sie verfallen NICHT. Eine so verwaiste Order haengt beim Broker, wird von niemandem mehr bewertet und kann Stunden spaeter fuellen: ohne Dedup, ohne Guard-Pruefung und (bis heute) ohne Trailing. Neu engine._pendings_abraeumen(sym, grund) - beide Pfade raeumen jetzt ab. DIE EIGENTLICHE VORGABE: ein halbes Setup wird aufgeloest. Scheitert eine Seite mit Lot-Fehler (freie Margin reicht nicht fuers Mindestlot), wird auch die Gegenseite storniert - der gemessene Squeeze ist ein Ausbruch in BEIDE Richtungen; laege nur eine Seite, handelte der Bot ihn nur noch in eine. Ausdruecklich NICHT bei "Kurs hat das Level bereits passiert": das ist voruebergehend und betrifft nur die eine Seite. Der Lot-Fehler betrifft das KONTO und damit beide. Erkannt ueber die Konstante mt5_utils.LOT_ZU_KLEIN, nicht ueber ein deutsches Wort im Fliesstext - eine Erkennung, die an einer Formulierung haengt, hoert still auf zu funktionieren und faellt dabei auf die stille Seite. ⚠⚠ DIE LOG-DROSSEL WAR AM SELBEN TAG ZUM ZWEITEN MAL AUSGEHEBELT - durch meine eigene Verbesserung. Vormittags lag der Merker in EINER Variable fuer beide Seiten (behoben). Dann bekam die Meldung ueber lot_grund ihre Zahlen, und die freie Margin aendert sich mit jedem Tick: der Text war jedes Mal neu, der Vergleich traf immer zu, wieder 2 Zeilen pro Sekunde. Gedrosselt wird jetzt auf die URSACHE, nicht auf ihre Formulierung (_err_key: alle Zahlen -> #). Gemessen: 7 Zeilen in 90 s statt ~180, und die verbliebenen sind echte Wechsel zwischen den beiden Ursachen. Lehre: eine Drossel, die einen TEXT vergleicht, ist so stabil wie der Text. Live verifiziert: 0 liegende Orders, keine verwaisten Reste, Startup-Schonfrist raeumt korrekt ab, Orders kommen danach zurueck sobald die Margin reicht. Pipeline gruen (A-G), 97 Tests, deployt mit --feld squeeze_block. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
b448a7ade8 |
Warum BRK heute nicht ausgeloest hat: drei Ursachen, zwei behoben
User: "warum wurde beim letzten anstieg kein Break Out trade ausgeloest?"
Der Squeeze HAT gefeuert - mit der echten `_squeeze_one` nachgerechnet: 8 Bars
`active` heute, davon 6 LONG (00:55 / 03:00 / 07:40 / 08:35 / 11:50 / 13:00).
`squeeze_entry_count` steht trotzdem auf 0. Im Log stehen 8
`AUTO-SQUEEZE-ENTRY`-Zeilen - die Order scheiterte JEDES MAL.
URSACHE 1 - "Position bereits offen!" (1x, 08:30:34). Der Market-Fallback lief
noch ueber Slot 1, der vom manuellen Trade belegt war. Genau die Zwei-Slot-
Luecke; der `_slot()`-Fix kam um 08:32 und hat sie geschlossen.
URSACHE 2 - "Lot-Fehler" (140x, ab 13:02 JEDER Versuch). Das ist der Hauptgrund
und er ist eine Einstellung, kein Defekt: `margin_brk = 10 %`, und `calc_lots`
nimmt einen Prozentsatz der FREIEN Margin, nicht des Kontos. Die manuelle
Position bindet 707 von 776 EUR -> 10 % von ~100 EUR frei = ~10 EUR, ein
Mindestlot braucht 7,47 EUR, und die freie Margin schwankt mit dem P&L. Damit
lag BRK den ganzen Tag auf der Kippe. NICHT eigenmaechtig geaendert - das Feld
ist eine User-Entscheidung.
URSACHE 3 - "Kurs hat das Level bereits passiert" (129x). Die BUY_STOP-Seite
war nicht platzierbar, weil das Box-Dach dem Kurs ENTGEGENKAM (rollierendes
Fenster) - die wandernde Marke aus backtest_squeeze_frozen.py, hier live.
BEHOBEN (1): LOG-DROSSEL GRIFF NIE. Der Merker lag in EINER Variable, die
beiden Seiten scheitern aber im selben Tick mit VERSCHIEDENEN Fehlern
("Level passiert" oben, "Lot-Fehler" unten) - der Wert wechselte bei jedem
Aufruf. Real: 269 Zeilen an einem Tag, 2 je Sekunde. Jetzt je Order-Seite
gemerkt. Eine Drossel, die nie drosselt, ist schlimmer als keine: sie verdeckt
im Log genau die Meldung, die zaehlt.
BEHOBEN (2): "Lot-Fehler" erklaert sich jetzt selbst (`mt5_utils.lot_grund`).
Statt zwei Woertern steht dort
"Einsatz 2 % von 101.90 EUR freier Margin = 2.04 EUR, Mindestlot 0.01
braucht aber 7.47 EUR"
Beide Aufrufer (Market `_send` und Pending `place_stop`) nutzen ihn. Live
gegengeprueft an drei Einsatz-Werten.
Pipeline gruen (check_nfalle, Stufe E, 97 Tests), deployt und verifiziert:
seit dem Neustart 0 Zeilen "nicht platzierbar".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
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>
|
||
|
|
6af4c868bc |
Feste Einsatz-Margin (UI-Feld) + lokale Sprachausgabe via Piper
EINSATZ-FELD (User-Wunsch): Laufzeitwert MANUAL_MARGIN in core/config.py (set/get_manual_margin, Muster wie set_margin_buffer). 0 = automatisch wie bisher (margin_buffer_pct % der freien Margin), > 0 = Position wird auf genau diesen Margin-Einsatz gerechnet. - calc_lots setzt es um und DECKELT auf freie Margin x Buffer; ein zu hoher Wunschwert wird begrenzt und geloggt statt an den Broker durchgereicht. Reicht der Betrag nicht fuers Mindestlot -> 0.0 + Warnung, Trade sauber abgelehnt. - Vorrang vor dem Risiko-Modus in trader._send_locked: eine ausdrueckliche Groessenvorgabe schlaegt die Rechenregel. - Wirkt auf ALLE neuen Positionen, auch die autonomen. - UI-Feld "Einsatz" in der ORDER-Leiste (nicht in der Trade-Leiste: die ist nur bei offener Position sichtbar, der Einsatz muss vorher einstellbar sein), bernstein umrandet solange gesetzt. Enter blurrt nur, change sendet einmal. - POST /api/manualmargin, Snapshot manual_margin, neustart-fest ueber runtime_state.json. Ende-zu-Ende getestet (250 -> Snapshot -> 0 -> persistiert). - Lot-Logik isoliert geprueft: 200 EUR -> 0,58 Lots; 5000 EUR -> gedeckelt. SPRACHAUSGABE: Piper lokal (tools/speak.py). Windows-TTS funktioniert zwar, aber es ist KEINE deutsche Stimme installiert - weder SAPI5 noch OneCore (nur David/Zira/Mark, en-US); deutscher Text kaeme mit englischer Aussprache. Add-WindowsCapability scheitert ohne Adminrechte. Piper gewaehlt: laeuft lokal (passt zum Rest - WireGuard-only, Secrets in der ini, keine Cloud), kostet nichts, aus PowerShell/Python aufrufbar. Stimme thorsten-medium (de_DE), Real-Time-Faktor 0,08 (4,3 s Audio in 0,36 s). Das ZIP entpackt eine Ebene tiefer als erwartet (tools/piper/piper/piper.exe) - speak.py SUCHT Binary und Modell statt Pfade fest zu verdrahten. Der erste Entwurf scheiterte daran; der Fail-safe meldete die Pfade sauber statt stumm zu bleiben. Drei Modi getestet (Argument, Pipe, --wav). tools/piper/ ist gitignored (Binaries + 60-MB-Modell), speak.py versioniert. v=136. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
75d28827e8 |
Initial commit: Oil Trading Bot (MT5, WTI)
Headless FastAPI-Backend (server.py + core/engine.py) mit Mobile-PWA (web/), Strategie-/Backtest-Suite und Doku. Secrets, DB, Logs und Laufzeit-State sind via .gitignore ausgeschlossen; Config-Vorlage: oil_widget_config.ini.example. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |