Auto-Signal abgeschaltet + B5-Abbruchregel fuer Auto-Squeeze fixiert
Auto-Signal AUS (auto_signal=false via Toggle -> runtime_state.json). Gruende sind NICHT die Live-Bilanz (n=4 sagt nichts): - gemessen in H1 durchgehend negativ (backtest_auto_signal.py, alle 8 Varianten) - beide Auto-Pfade konkurrieren um den EINEN Positions-Slot -> solange beide laufen, ist die B5-Pruefung des Auto-Squeeze nicht sauber messbar B4-Befund Auto-Squeeze (Anlass: negative Auto-Trades vom 31.07.): Mechanik (isolierter Einstieg): WR 46 %, OR +0,102, PF 1,15 Live (n=31, 17.-31.07.) : WR 45 %, OR -0,242, PF 0,49 Die Trefferquote stimmt ueberein - der Einstieg ist intakt. Die Luecke von 0,34 R/Trade entsteht im EXIT (O-Gewinn +11,02 vs O-Verlust -19,83). Alle drei Ursachen wurden am 31.07. behoben (P(break) nachtrainiert, 15-Min-Regel aus, Trail einheitlich 1,0), der Live-Zeitraum liegt also VOR den Reparaturen. Deshalb kein Rueckbau, sondern vorab fixierte Latte: >=20 Squeeze-Trades ab 01.08., dann Verhaeltnis < 1,0 ODER PF < 1 -> aus. measurement_reminder.py: - neue Messung squeeze_b5 (loest autosig_b4 ab) - CONFIG_DEPS um auto_signal (soll false) und auto_squeeze (soll true) ergaenzt - ⚠ _cfg_now() liest jetzt AUCH runtime_state.json und bildet dessen Vorrang ab. Vorher verglich der Waechter nur die ini -> er meldete "alles auf dem gemessenen Stand", waehrend auto_signal per persistiertem UI-Toggle lief. Mit Szenario verifiziert (runtime true gegen validiert false -> gemeldet). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d0f3b78796
commit
d18d8712db
@@ -1005,8 +1005,17 @@ dort bereits nachvalidiert, ØR +0,305.) **Eine** Oberfläche:
|
|||||||
→ B4-Monitor). Snapshot `auto_signal`/`auto_signal_min_conf`/`signal_entry_count`,
|
→ B4-Monitor). Snapshot `auto_signal`/`auto_signal_min_conf`/`signal_entry_count`,
|
||||||
Toggle `POST /api/autosignal` = Dashboard-Button **🎯 SIG** (bernstein statt blau,
|
Toggle `POST /api/autosignal` = Dashboard-Button **🎯 SIG** (bernstein statt blau,
|
||||||
weil gemessen nicht tragfähig; zeigt die Schwelle an), neustart-fest via
|
weil gemessen nicht tragfähig; zeigt die Schwelle an), neustart-fest via
|
||||||
`runtime_state.json`. **B5-Pflicht:** Live-ØR/PF gegen die Backtest-Erwartung halten
|
`runtime_state.json`.
|
||||||
(H2-Regime +0,14 vs H1-Regime −0,05) — driftet es weg, **zurückbauen** (`=false`).
|
⚠⚠ **ABGESCHALTET am 2026-08-01 (`auto_signal=false`, via Toggle → `runtime_state.json`).**
|
||||||
|
Zwei Gründe, KEINER davon die Live-Bilanz (n=4 = +21,79 € sagt nichts): (1) gemessen in
|
||||||
|
H1 durchgehend negativ, gebaut gegen die Messung; (2) **beide Auto-Pfade konkurrieren um
|
||||||
|
den EINEN Positions-Slot** — ein AUTOSIG-Trade blockiert einen Squeeze-Einstieg und
|
||||||
|
umgekehrt. Solange beide laufen, ist die B5-Abbruchprüfung des Auto-Squeeze (s. u.)
|
||||||
|
nicht sauber messbar. ⚠ Er lief bis dahin **unbemerkt**, obwohl die ini `false` sagte:
|
||||||
|
ein Dashboard-Toggle hatte `true` in `runtime_state.json` persistiert, und das
|
||||||
|
überschreibt die ini beim Start. Der Config-Wächter prüft das jetzt mit.
|
||||||
|
Reaktivieren = Button 🎯 SIG; dann gilt wieder: ≥20 AUTOSIG-Trades, Live-ØR/PF gegen
|
||||||
|
die Erwartung halten (H2-Regime +0,14 vs H1-Regime −0,05).
|
||||||
- **⚠⚠ 15-MINUTEN-REGEL GANZ ABGESCHALTET (`adverse_15min_atr = 0`, 2026-07-31,
|
- **⚠⚠ 15-MINUTEN-REGEL GANZ ABGESCHALTET (`adverse_15min_atr = 0`, 2026-07-31,
|
||||||
User-Entscheidung nach der Messung).** Auf die User-Frage „vielleicht die Auto-Close
|
User-Entscheidung nach der Messung).** Auf die User-Frage „vielleicht die Auto-Close
|
||||||
auf 30 min setzen?" wurde die **ZEIT-Achse** mitgemessen
|
auf 30 min setzen?" wurde die **ZEIT-Achse** mitgemessen
|
||||||
@@ -1085,6 +1094,34 @@ dort bereits nachvalidiert, ØR +0,305.) **Eine** Oberfläche:
|
|||||||
Konf-Gate, Dedup, WARTEN-Re-Arm, Nachkauf, Gegen-Position, Cooldown, Toggle,
|
Konf-Gate, Dedup, WARTEN-Re-Arm, Nachkauf, Gegen-Position, Cooldown, Toggle,
|
||||||
Nacht-Sperre · 9 Adverse: über/unter Schwelle, zu früh, im Plus, SHORT-Richtung,
|
Nacht-Sperre · 9 Adverse: über/unter Schwelle, zu früh, im Plus, SHORT-Richtung,
|
||||||
manueller Trade, aus, 1×-je-Ticket, Startup-Grace) — alle korrekt.
|
manueller Trade, aus, 1×-je-Ticket, Startup-Grace) — alle korrekt.
|
||||||
|
- **⚠⚠ AUTO-SQUEEZE B4-BEFUND 2026-08-01: der EINSTIEG ist intakt, der EXIT hat den
|
||||||
|
Edge gefressen — deshalb NICHT zurückgebaut, aber mit vorab fixierter Abbruchregel.**
|
||||||
|
Anlass war die User-Frage zu den negativen Auto-Trades vom 31.07. Der B4-Monitor
|
||||||
|
trennt beides sauber:
|
||||||
|
| | Trefferquote | ØR | PF |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **Mechanik** (Regel neu gerechnet, Backtest-Exit = isolierter Einstieg) | 46 % | **+0,102** | 1,15 |
|
||||||
|
| **Live** (n=31, 17.–31.07., Gesamtsystem mit echten Exits) | 45 % | **−0,242** | 0,49 |
|
||||||
|
Die **Trefferquote stimmt praktisch überein (46 vs 45 %)** — das Setup findet also
|
||||||
|
weiterhin, was es finden soll. Die Lücke von **0,34 R/Trade** entsteht komplett im
|
||||||
|
Exit: Ø-Gewinn **+11,02 €** gegen Ø-Verlust **−19,83 €** (Verhältnis 0,56, ΣEUR
|
||||||
|
**−162,99**). Der Squeeze ist runner-abhängig (43 % Treffer tragen nur, wenn die
|
||||||
|
Gewinner deutlich größer sind) — genau die Läufer wurden gekappt.
|
||||||
|
**Alle drei Ursachen sind am 31.07. behoben worden**, der Live-Zeitraum liegt also
|
||||||
|
fast vollständig VOR den Reparaturen: (a) das **P(break)-Modell** schloss 91 % aller
|
||||||
|
Level-Berührungen = faktisch pauschaler S/R-Close, und der ist 2× als Gewinner-Kappen
|
||||||
|
gemessen → nachtrainiert; (b) die **15-Min-Regel** schnitt Squeeze-Trades, auf dieser
|
||||||
|
Population in beiden Hälften schädlich → aus; (c) **Trailing 1,5–3,0 je nach TF**
|
||||||
|
statt der gemessenen 1,5 (Deployment-Drift Fall 3) → einheitlich 1,0.
|
||||||
|
⚠ **Ehrlich:** die Mechanik liegt mit ØR +0,102 **unter** dem validierten Band
|
||||||
|
+0,14…+0,23 — der Einstieg ist also auch selbst schwächer geworden (Regime). Das ist
|
||||||
|
kein Freibrief, sondern der Grund für eine harte Latte statt unbegrenztem Zuwarten.
|
||||||
|
✅ **B5-ABBRUCHREGEL, VORAB FESTGELEGT (User-Zustimmung 2026-08-01):** nach **≥20
|
||||||
|
Squeeze-Trades ab dem 01.08.** — **Verhältnis (ØGewinn/ØVerlust) < 1,0 ODER PF < 1
|
||||||
|
→ `auto_squeeze=false`.** Bewusst VOR der Beobachtung fixiert, damit die Latte
|
||||||
|
hinterher nicht verschoben wird; überwacht als Messung `squeeze_b5` im
|
||||||
|
`measurement_reminder.py`. Nacht-Anteil der Altdaten: 12 der 31 Trades / −78,92 € —
|
||||||
|
die stammen aus der Zeit vor dem Nacht-Guard (seit 24.07. wieder an).
|
||||||
- **Auto-Squeeze-Entry = LIVE AUTONOM (User-Vorgabe 2026-07-16, `[trading]
|
- **Auto-Squeeze-Entry = LIVE AUTONOM (User-Vorgabe 2026-07-16, `[trading]
|
||||||
auto_squeeze=true`, Default FALSE):** der Bot eröffnet **selbständig eine echte
|
auto_squeeze=true`, Default FALSE):** der Bot eröffnet **selbständig eine echte
|
||||||
Order**, sobald der **gemessen-validierte** Squeeze-Ausbruch feuert (`wave.squeeze.
|
Order**, sobald der **gemessen-validierte** Squeeze-Ausbruch feuert (`wave.squeeze.
|
||||||
@@ -2456,15 +2493,25 @@ Status jederzeit: `python measurement_reminder.py --status`.
|
|||||||
blieb liegen. Die P(break)-Prognose-Genauigkeit war seit 2026-07-23 auswertbar und
|
blieb liegen. Die P(break)-Prognose-Genauigkeit war seit 2026-07-23 auswertbar und
|
||||||
hatte am 2026-07-30 bereits **2213 ausgewertete Zeilen**, ohne dass jemand hinsah.
|
hatte am 2026-07-30 bereits **2213 ausgewertete Zeilen**, ohne dass jemand hinsah.
|
||||||
|
|
||||||
| Messung | Bedingung | Stand 2026-07-31 |
|
| Messung | Bedingung | Stand 2026-08-01 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| P(break) erneut auswerten (nach Nachtraining) | ≥800 Vorhersagen ab 01.08. | 0 |
|
| P(break) erneut auswerten (nach Nachtraining) | ≥800 Vorhersagen ab 01.08. | 0 |
|
||||||
| **Modul-Audit: zweiter Durchgang** | ≥28 Tage seit dem 1. Audit | 1 (2 %) |
|
| **Modul-Audit: zweiter Durchgang** | ≥28 Tage seit dem 1. Audit | 2 (6 %) |
|
||||||
| Verdict-Module auf Prädiktivität (`verdict_votes`) | ≥25 000 Verdicts | 7184 (29 %) |
|
| Verdict-Module auf Prädiktivität (`verdict_votes`) | ≥25 000 Verdicts | 8142 (33 %) |
|
||||||
| Auto-Signal-Entry B4/B5 | ≥20 AUTOSIG-Trades | 3 (15 %) |
|
| **Auto-Squeeze: B5-Abbruchprüfung** (Latte vorab fixiert) | ≥20 Squeeze-Trades ab 01.08. | 0 |
|
||||||
| M30-Level-Umstellung live gegenprüfen | ≥30 S/R-Closes seit 30.07. | 13 (43 %) |
|
| M30-Level-Umstellung live gegenprüfen | ≥30 S/R-Closes seit 30.07. | 17 (57 %) |
|
||||||
| M1-Squeeze Variante B | ≥180 Tage `candles_m1` | 14 (8 %) |
|
| M1-Squeeze Variante B | ≥180 Tage `candles_m1` | 14 (8 %) |
|
||||||
| News-Score-Prädiktivität | ≥90 Tage Sammlung | 8 (8 %) |
|
| News-Score-Prädiktivität | ≥90 Tage Sammlung | 9 (10 %) |
|
||||||
|
|
||||||
|
⚠ **Der Config-Wächter liest jetzt auch `runtime_state.json` (Fix 2026-08-01).** Er
|
||||||
|
verglich vorher nur die **ini** gegen die validierten Werte — die UI-Schalter leben aber
|
||||||
|
in `runtime_state.json` und werden beim Start **über** die ini gelegt. Dadurch meldete er
|
||||||
|
„alles auf dem gemessenen Stand", während live etwas anderes lief. Real: `auto_signal`
|
||||||
|
stand in der ini auf `false`, war aber durch einen Dashboard-Toggle dauerhaft `true` —
|
||||||
|
4 der 7 Bot-Trades vom 31.07. kamen aus diesem gemessen-negativen Pfad. `_cfg_now()`
|
||||||
|
bildet den Vorrang jetzt genauso ab wie der Engine-Start; mit einem Szenario verifiziert
|
||||||
|
(runtime `true` gegen validiert `false` → wird gemeldet). Neu überwacht: `auto_signal`
|
||||||
|
(soll `false`) und `auto_squeeze` (soll `true`).
|
||||||
|
|
||||||
*(erledigt und ausgetragen: P(break)-Genauigkeit → `analyze_pbreak_live.py` 31.07.,
|
*(erledigt und ausgetragen: P(break)-Genauigkeit → `analyze_pbreak_live.py` 31.07.,
|
||||||
Modell daraufhin nachtrainiert · Chartmuster-Kontrolltest → 30.07., Muster schlagen
|
Modell daraufhin nachtrainiert · Chartmuster-Kontrolltest → 30.07., Muster schlagen
|
||||||
|
|||||||
+63
-11
@@ -94,17 +94,32 @@ CHECKS = [
|
|||||||
"need": 25000, "unit": "geloggte Verdicts (~3 Wochen)",
|
"need": 25000, "unit": "geloggte Verdicts (~3 Wochen)",
|
||||||
"cmd": "analog analyze_verdict_calibration.py, aber auf verdict_votes",
|
"cmd": "analog analyze_verdict_calibration.py, aber auf verdict_votes",
|
||||||
},
|
},
|
||||||
|
# (ausgetragen 2026-08-01: „Auto-Signal-Entry B4" — der Pfad wurde ABGESCHALTET
|
||||||
|
# (`auto_signal=false`, Toggle + runtime_state). Gründe: gemessen H1 durchgehend
|
||||||
|
# negativ, und er konkurriert mit dem Auto-Squeeze um den EINEN Positions-Slot →
|
||||||
|
# solange beide laufen, ist die Squeeze-Erholung unten nicht sauber messbar.
|
||||||
|
# Wird er je reaktiviert, gilt wieder: ≥20 AUTOSIG-Trades, ØR gegen +0,14 halten.
|
||||||
|
# Der Zustand wird jetzt über CONFIG_DEPS['auto_signal'] überwacht.)
|
||||||
{
|
{
|
||||||
"key": "autosig_b4",
|
# ⚠ VORAB festgelegte Abbruchregel (User-Zustimmung 2026-08-01) — bewusst VOR
|
||||||
"title": "Auto-Signal-Entry: B4-Monitor (trägt er live?)",
|
# der Beobachtung fixiert, damit die Latte hinterher nicht verschoben wird.
|
||||||
"why": "Gemessen NICHT tragfähig (H1 −0,05…−0,18, H2 positiv = Regime-Kippen), "
|
"key": "squeeze_b5",
|
||||||
"auf ausdrücklichen Wunsch trotzdem gebaut. Erwartung: im aktuellen "
|
"title": "Auto-Squeeze: B5-Abbruchprüfung (Latte vorab fixiert)",
|
||||||
"Regime ~+0,14 R/Trade, im ungünstigen −0,05. Driftet es negativ weg → "
|
"why": "Live-Bilanz 17.–31.07.: n=31, ΣEUR −162,99, PF 0,49, Verhältnis 0,56 — "
|
||||||
"`auto_signal=false` (B5-Rückbau).",
|
"während der B4-Monitor den EINSTIEG als intakt ausweist (Trefferquote "
|
||||||
"have": lambda: _q("SELECT COUNT(*) FROM trades WHERE setup LIKE 'AUTOSIG%' "
|
"live 45 % vs. Mechanik 46 %, ØR Mechanik +0,102). Die Lücke von ~0,34 R "
|
||||||
"AND pnl IS NOT NULL"),
|
"entstand also im EXIT, und alle drei Ursachen wurden am 31.07. behoben: "
|
||||||
"need": 20, "unit": "AUTOSIG-Trades",
|
"P(break)-Modell nachtrainiert (schloss vorher 91 % aller Level-"
|
||||||
"cmd": "Statistik-Tab · setup LIKE 'AUTOSIG%' gegen ØR +0,14 halten",
|
"Berührungen = faktisch pauschaler S/R-Close), 15-Min-Regel aus, Trailing "
|
||||||
|
"einheitlich 1,0 statt 1,5–3,0 je TF. Deshalb NICHT sofort zurückgebaut, "
|
||||||
|
"sondern ein sauberes Fenster mit harter Latte.",
|
||||||
|
"have": lambda: _q("SELECT COUNT(*) FROM trades WHERE setup LIKE 'SQUEEZE%' "
|
||||||
|
"AND pnl IS NOT NULL AND entry_time >= "
|
||||||
|
"strftime('%s','2026-08-01')"),
|
||||||
|
"need": 20, "unit": "Squeeze-Trades seit 01.08.",
|
||||||
|
"cmd": "ABBRUCHREGEL: Verhältnis (ØGewinn/ØVerlust) < 1,0 ODER PF < 1 "
|
||||||
|
"→ `auto_squeeze=false` (B5-Rückbau, kein Ego). Sonst weiterlaufen "
|
||||||
|
"lassen. Zahlen: /api/squeeze_monitor bzw. Statistik-Tab.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "m30_levels",
|
"key": "m30_levels",
|
||||||
@@ -209,6 +224,24 @@ CONFIG_DEPS = [
|
|||||||
"why": "Empirisch bester Punkt (NICHT weil höhere Konfidenz besser wäre — "
|
"why": "Empirisch bester Punkt (NICHT weil höhere Konfidenz besser wäre — "
|
||||||
"conf_pct ist unkalibriert). Nachbarwerte sind nicht besser.",
|
"conf_pct ist unkalibriert). Nachbarwerte sind nicht besser.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "auto_signal", "test": "backtest_auto_signal.py",
|
||||||
|
"validated": "false",
|
||||||
|
"why": "ABGESCHALTET 2026-08-01. Gemessen in H1 durchgehend negativ (alle 8 "
|
||||||
|
"Varianten, n=718–1167/Hälfte), H2 positiv = Regime-Kippen. Zusätzlich: "
|
||||||
|
"beide Auto-Pfade konkurrieren um den EINEN Positions-Slot — läuft er "
|
||||||
|
"mit, ist die B5-Abbruchprüfung des Auto-Squeeze nicht sauber messbar. "
|
||||||
|
"⚠ Dieser Schlüssel lebt AUCH in runtime_state.json (UI-Toggle) und wird "
|
||||||
|
"von dort überschrieben — genau so lief er am 31.07. unbemerkt weiter, "
|
||||||
|
"obwohl die ini 'false' sagte.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "auto_squeeze", "test": "backtest_breakout_squeeze.py",
|
||||||
|
"validated": "true",
|
||||||
|
"why": "Der EINZIGE 2-Stichproben-validierte Auto-Einstieg (ØR +0,14…+0,23). "
|
||||||
|
"Bleibt an, aber unter der vorab fixierten B5-Abbruchregel (s. Messung "
|
||||||
|
"'squeeze_b5'). Ebenfalls über runtime_state.json überschreibbar.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "dead_hours", "test": "backtest_hourly_split.py / backtest_realcosts.py",
|
"key": "dead_hours", "test": "backtest_hourly_split.py / backtest_realcosts.py",
|
||||||
"validated": "",
|
"validated": "",
|
||||||
@@ -220,8 +253,18 @@ CONFIG_DEPS = [
|
|||||||
|
|
||||||
def _cfg_now() -> dict:
|
def _cfg_now() -> dict:
|
||||||
"""Liest NUR die überwachten [trading]-Keys. ⚠ Die ini enthält Live-Secrets —
|
"""Liest NUR die überwachten [trading]-Keys. ⚠ Die ini enthält Live-Secrets —
|
||||||
hier wird bewusst nichts anderes gelesen oder ausgegeben."""
|
hier wird bewusst nichts anderes gelesen oder ausgegeben.
|
||||||
|
|
||||||
|
⚠⚠ WICHTIG (Fix 2026-08-01): Die ini ist NICHT die Quelle der Wahrheit für die
|
||||||
|
UI-Schalter. `runtime_state.json` wird beim Start über die ini gelegt (engine
|
||||||
|
`_load_runtime_state`) — der Wächter muss denselben Vorrang abbilden, sonst meldet
|
||||||
|
er „alles auf dem gemessenen Stand", während live etwas anderes läuft.
|
||||||
|
Real passiert: `auto_signal` stand in der ini auf `false`, lief aber wochenlang,
|
||||||
|
weil ein Dashboard-Toggle `true` persistiert hatte — 4 der 7 Bot-Trades vom 31.07.
|
||||||
|
stammten aus diesem Pfad, der gemessen in H1 negativ ist.
|
||||||
|
"""
|
||||||
import configparser
|
import configparser
|
||||||
|
import json
|
||||||
out: dict = {}
|
out: dict = {}
|
||||||
try:
|
try:
|
||||||
c = configparser.ConfigParser(inline_comment_prefixes=("#", ";"))
|
c = configparser.ConfigParser(inline_comment_prefixes=("#", ";"))
|
||||||
@@ -231,6 +274,15 @@ def _cfg_now() -> dict:
|
|||||||
out[d["key"]] = (t.get(d["key"], "") or "").strip()
|
out[d["key"]] = (t.get(d["key"], "") or "").strip()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
# runtime_state.json überschreibt — exakt wie im Engine-Start.
|
||||||
|
try:
|
||||||
|
with open(os.path.join(HERE, "runtime_state.json"), encoding="utf-8") as f:
|
||||||
|
rt = json.load(f) or {}
|
||||||
|
for k, v in rt.items():
|
||||||
|
if k in out:
|
||||||
|
out[k] = ("true" if v else "false") if isinstance(v, bool) else str(v)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user