Sieben Verbesserungen umgesetzt: Breaker scharf, B5 entschieden, 5 Werkzeuge
1) CIRCUIT-BREAKER SCHARF -- daily_loss_limit_pct 0 -> 8. Live verifiziert:
enabled=True, limit_eur 89,44. Steht nicht in runtime_state.json, die ini
greift direkt. Begruendung: MaxDD 82,8 % auf dem gemessenen IST-Pfad,
schlechtester Einzeltrade -381 EUR.
2) B5-DEADLOCK RECHNERISCH AUFGELOEST -- die Regel ist ENTSCHIEDEN, nicht
vertagt. Stand 11/20: Verhaeltnis 0,14 (Latte 1,0), PF 0,39 (Latte 1,0).
Was die 9 Rest-Trades leisten muessten:
9/0 Gewinner -> 165,72 EUR je Trade = 12,2x der bisherige Schnitt
7/2 -> 186,17 EUR
5/4 -> 222,99 EUR
Der groesste Squeeze-Gewinn des Zeitraums war 77,34 EUR -- selbst der beste
Fall verlangt 2,1x den Rekord, neunmal in Folge. Latte nicht mehr erreichbar.
auto_squeeze bleibt FALSE. Wiederaufnahme waere eine NEUE Entscheidung mit
NEUER, vorab fixierter Latte.
3) core/kontrolle.py -- Kontroll-Fixture mit den Referenzwerten. Bricht bewusst
NICHT ab: ein Backtest darf abweichen, er muss es nur wissen und sagen.
4) core/live_config.py -- EINE Quelle der Live-Parameter (ini + runtime_state in
der Vorrangfolge des Engine-Starts). Dritte Instanz derselben Fehlerklasse:
ATRMIN_STD 0,12 statt 0,06, fehlendes set_entry_room, nachgebauter Cluster.
5) stichprobe.paarweise()/zeig_paarweise() -- gepaarter Vergleich. Anlass:
trail_start sah sequentiell besser aus, gepaart kippte das Vorzeichen
(Selektions- statt Exit-Effekt). Selbsttest in drei Richtungen bestanden.
6) tools/check_konstanten.py -- Waechter fuer veraltete Zahlen.
Erster Lauf: zwei Befunde, BEIDE Fehler in meiner eigenen Ableitung (Margin
aus Balance geschaetzt statt vom Broker gelesen; Elliott ohne
Gueltigkeitsfenster gezaehlt). Beide korrigiert.
Danach ein ECHTER Fund: meine am 13.08. notierten "~405 EUR/Lot" sind falsch,
der exakte Broker-Wert ist 712,84 -- die urspruenglich notierten 670 lagen
naeher als meine Korrektur. Lehre: eine abgeleitete Zahl ist keine gemessene.
Stand jetzt 0 Befunde.
7) Puls-Waechter bedingungs-bewusst: PULS traegt je Zeile die Vorbedingung,
bedingte Tabellen erscheinen als Hinweis statt als Ausfall. 0 Zeilen bleibt
IMMER ein Befund (der rec_outcomes-Fall). Grund: ein Waechter mit
Fehlalarmen wird ignoriert -- so ist der Divergenz-Waechter verstummt.
Pipeline gruen (85 Tests), Deployment ueber deploy.py --feld circuit_breaker
verifiziert, genau eine Instanz je Port.
Nicht angefasst: Sizing (User-Entscheidung) und die 44 Backtests mit eigener
Exit-Kopie (Migrations-Regel).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9dbc5d0452
commit
792355e8f9
+31
-10
@@ -436,15 +436,27 @@ class HistoryLogger:
|
||||
# BEIDE Nutzer (Reminder-Popup + Tagesreport) brauchen ihn. Zwei Kopien
|
||||
# waeren genau die Divergenz, die im Projekt dreimal zugeschlagen hat.
|
||||
# Richtungsregel: Skripte duerfen `core` importieren, nicht umgekehrt.
|
||||
# ⚠⚠ BEDINGUNGS-KENNTNIS (2026-08-17). Der Puls hat `pbreak_predictions` als
|
||||
# „63,5 h still" gemeldet — dabei schreibt die Tabelle NUR bei frischem
|
||||
# Level-Touch auf der ZIEL-Seite einer OFFENEN Position. Ohne offene
|
||||
# Position kann sie legitim tagelang schweigen. Ein Waechter, der
|
||||
# Fehlalarme produziert, wird ignoriert — und mit ihm die eine echte
|
||||
# Meldung; genau das ist dem Divergenz-Waechter passiert (6 Tage
|
||||
# Dauerwarnung, 02.08.). Deshalb traegt jede Zeile jetzt ihre VORBEDINGUNG.
|
||||
# `bedingung=None` heisst „schreibt unbedingt, Stille ist immer ein Fehler".
|
||||
PULS = (
|
||||
# (Tabelle, Zeitspalte, erwartete Kadenz in Minuten, wozu)
|
||||
("recommendations", "timestamp", 1, "Empfehlungs-Log"),
|
||||
("candles_m1", "time", 1, "M1-Kerzen-Sammlung"),
|
||||
("verdict_votes", "ts", 1, "Modul-Stimmen"),
|
||||
("m15_states", "ts", 60, "M15-Karte Selbstmessung"),
|
||||
("cone_checks", "ts", 60, "Kegel-Kalibrierung (ACI)"),
|
||||
("pbreak_predictions", "ts", 60, "P(break)-Prognose-Tracking"),
|
||||
("rec_outcomes", "ts", 180, "Selbst-Kalibrierung Empfehlung"),
|
||||
# (Tabelle, Zeitspalte, Kadenz in Minuten, wozu, Vorbedingung)
|
||||
("recommendations", "timestamp", 1, "Empfehlungs-Log", None),
|
||||
("candles_m1", "time", 1, "M1-Kerzen-Sammlung", None),
|
||||
("verdict_votes", "ts", 1, "Modul-Stimmen", None),
|
||||
("m15_states", "ts", 60, "M15-Karte Selbstmessung", None),
|
||||
("cone_checks", "ts", 60, "Kegel-Kalibrierung (ACI)", None),
|
||||
("pbreak_predictions", "ts", 60, "P(break)-Prognose-Tracking",
|
||||
"braucht eine OFFENE Position und einen frischen Level-Touch auf der "
|
||||
"Ziel-Seite — ohne offene Position ist Stille normal"),
|
||||
("rec_outcomes", "ts", 180, "Selbst-Kalibrierung Empfehlung",
|
||||
"braucht einen Richtungs-WECHSEL der Empfehlung — bei ~93 % WARTEN "
|
||||
"kann das lange dauern"),
|
||||
)
|
||||
|
||||
def telemetrie_puls(self) -> list[str]:
|
||||
@@ -458,20 +470,29 @@ class HistoryLogger:
|
||||
try:
|
||||
jetzt = time.time()
|
||||
with self._lock, self._connect() as conn:
|
||||
for tab, sp, kadenz, wozu in self.PULS:
|
||||
for tab, sp, kadenz, wozu, bedingung in self.PULS:
|
||||
try:
|
||||
n = conn.execute(f"SELECT COUNT(*) FROM {tab}").fetchone()[0]
|
||||
letzt = conn.execute(f"SELECT MAX({sp}) FROM {tab}").fetchone()[0]
|
||||
except Exception:
|
||||
continue # Tabelle gibt es (noch) nicht
|
||||
if not n:
|
||||
# ⚠ 0 Zeilen ist IMMER ein Befund — auch mit Vorbedingung:
|
||||
# „hat nie geschrieben" laesst sich nicht wegerklaeren.
|
||||
out.append(f"{tab}: 0 Zeilen — Logger hat NIE geschrieben ({wozu})")
|
||||
continue
|
||||
# ⚠ `candles_m1.time` ist ROHE Brokerzeit (UTC+3) — ohne den
|
||||
# Abzug meldet der Puls dort dauerhaft 3 h Rueckstand.
|
||||
ts = letzt - 10800 if tab == "candles_m1" else letzt
|
||||
alter_min = (jetzt - ts) / 60.0
|
||||
if alter_min > kadenz * 20:
|
||||
if alter_min <= kadenz * 20:
|
||||
continue
|
||||
if bedingung:
|
||||
# Bedingte Tabellen: als HINWEIS melden, nicht als Ausfall —
|
||||
# sonst wird der Waechter zum Rauschen (s. Kommentar an PULS).
|
||||
out.append(f"ⓘ {tab}: still seit {alter_min/60:.1f} h — "
|
||||
f"{bedingung} ({wozu})")
|
||||
else:
|
||||
out.append(f"{tab}: letzte Zeile vor {alter_min/60:.1f} h "
|
||||
f"(erwartet ~alle {kadenz} min) — {wozu}")
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user