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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
19ee379f20
commit
d8839ef7c5
@@ -6161,6 +6161,79 @@ Neumessung. Sie bleiben unverändert und reproduzierbar; wo ihre Schlussfolgerun
|
||||
relevant wird, gehört sie live-treu **neu gerechnet** (Muster:
|
||||
`backtest_auto_signal_norev.py`).
|
||||
|
||||
## ⚠⚠ TAG P/L WAR FALSCH — Fehlbuchungen beim Schliessen (2026-08-12)
|
||||
|
||||
User: „überprüfe ob Tag P/L richtig berechnet wird." **Die Formel war richtig, die
|
||||
Datenbasis nicht.**
|
||||
| | |
|
||||
|---|---|
|
||||
| Anzeige „TAG P/L" | **+14,26 €** |
|
||||
| Broker, realisiert heute | **−74,08 €** |
|
||||
| **Abweichung** | **81,71 €, mit falschem Vorzeichen** |
|
||||
✅ `realisiert + offen` stimmt bitgenau gegen die DB (0,0000). Der Fehler lag
|
||||
darunter: **die DB stimmte nicht mit dem Broker überein.**
|
||||
|
||||
⚠⚠ **URSACHE — eine Race Condition beim Eröffnen**, im Log im Sekundentakt
|
||||
sichtbar (#49926460): `20:04:10 SELL eröffnet` → `20:04:10 „extern geschlossen"`
|
||||
→ `20:04:12 „kein OUT-Deal in 1 Deals"` → Fallback bucht **0,00** →
|
||||
`20:11:42` der ECHTE Close **lief ins Leere**. Drei Defekte griffen ineinander:
|
||||
**(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 die Position 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 €** und buchte den Trade auf den
|
||||
**falschen Tag**.
|
||||
|
||||
✅ **BEHOBEN:** (1) `_log_external_close` bricht bei „kein OUT-Deal" ab (der
|
||||
Fallback bleibt nur für den wirklich blinden Fall, in dem gar keine Deals
|
||||
abrufbar sind — dort ist `reconcile_open_trades` das Netz). (2) `log_trade_close`
|
||||
darf eine **erkennbare Fehlbuchung** korrigieren — eng gefasst: nur wenn die
|
||||
Zeile `closed_by='unknown'` trägt UND die neue Buchung echte Deal-Daten hat.
|
||||
✅ **4 Tests** (`tests/test_close_buchung.py`), inkl. der Gegenprobe „eine gute
|
||||
Zeile wird NICHT überschrieben" — sonst wäre der Fix schlimmer als der Fehler.
|
||||
⚠ Zwei Testfehlschläge waren **meine**: synthetische Zeitstempel (1000/2000) vor
|
||||
der Eröffnungszeit lösten die Defensive „exit < entry → jetzt" aus.
|
||||
|
||||
✅ **ALTLAST REPARIERT** — `tools/repair_closes.py` (Trockenlauf ist Standard,
|
||||
Schreiben nur mit `--schreiben`, Backup `…bak-2026-08-12-repair`). Korrigiert
|
||||
werden **nur eindeutige Fälle**: `closed_by='unknown'` UND echter OUT-Deal beim
|
||||
Broker. **18 Zeilen** über 60 Tage. Heute: von **+7,63 auf −72,67 €**, Restfehler
|
||||
**1,41 €**. Gesamt-P&L (`all`): von **−282,78 auf +169,98 €**.
|
||||
⚠⚠ **ZEITFALLE dabei, zweimal:** `history_deals_get` filtert nach BROKER-Wallclock
|
||||
— `datetime`-Objekte verschieben das Fenster; und `fromtimestamp(d.time, BROKER)`
|
||||
rendert **3 h zu spät**. Aufgefallen, weil eine Deal-Zeit „23:11" lautete, das Log
|
||||
aber „20:11:42 CLOSE" sagte. ➜ **Epochs übergeben (lokal + Offset), beim Lesen
|
||||
`d.time − Offset`.**
|
||||
⚠ **20 weitere Trades** weichen um ±1–4 € ab (DB nutzt den Schwebe-P&L im
|
||||
Moment des Closes, der Broker den Fill). Die Summe hebt sich fast auf (+1,66 €
|
||||
über 19 Trades) → nur berichtet, **nicht** automatisch korrigiert.
|
||||
|
||||
## ✅ STATISTIK-MODUL: ARITHMETIK KORREKT, NETTO-RECHNUNG WEITER DEFEKT (2026-08-12)
|
||||
|
||||
Gegen unabhängige SQL geprüft, alle drei Zeiträume: **Abweichung 0,00 in jeder
|
||||
Zelle** (n · wins+losses+be = n · gross_win − gross_loss = total_pnl).
|
||||
| | today | week | all |
|
||||
|---|---|---|---|
|
||||
| n | 6 | 91 | 1.267 |
|
||||
| total_pnl | −72,67 | −1.259,12 | **+169,98** |
|
||||
✅ Das Modul rechnet also korrekt — es las nur eine fehlerhafte DB (jetzt repariert).
|
||||
|
||||
⚠⚠ **Der am 05.08. dokumentierte NETTO-Defekt besteht unverändert — und ist
|
||||
grösser als damals gemessen:**
|
||||
| | |
|
||||
|---|---|
|
||||
| Modell-Steuerlast (`gross_win × 26,375 %`) | **2.619,93 €** |
|
||||
| **angezeigtes `net_pnl`** | **−2.449,95 €** |
|
||||
| ECHT einbehalten / erstattet (90 Tage) | −2.625,89 / **+2.608,83** |
|
||||
| **tatsächlich verblieben** | **−17,06 €** |
|
||||
✅ Das Modell schätzt die *einbehaltene* Steuer fast perfekt (2.620 gegen 2.626).
|
||||
Der Fehler ist die Annahme, sie sei **verloren** — real werden **99 %** erstattet
|
||||
(am 05.08. waren es 79 %). Die Anzeige macht damit aus **+153 € rund −2.450 €**.
|
||||
⚠ `_add_net`/`_add_net_setup` in `server.py:154/171` sind unverändert. Die Lösung
|
||||
steht seit dem 05.08. fest: **die tatsächlichen `WHT #…`/`Tax settlement`-Deals
|
||||
verwenden statt zu schätzen** (gecacht, unter `mt5_lock`). **Noch nicht gebaut.**
|
||||
|
||||
## ✅ AUTO-SIGNAL-ENTRY (🎯 SIG) KOMPLETT ENTFERNT (User-Entscheidung 2026-08-12)
|
||||
|
||||
User: „den Signal-Autotrader brauchen wir im Moment nicht mehr — sollten wir den
|
||||
|
||||
Reference in New Issue
Block a user