M15-Karte "Setup-Bereitschaft" gebaut - Ersatz der Gesamtempfehlung (v=153)
Nach drei negativen M15-Messungen (Squeeze-Einstieg, VWAP-Baender, Exit-ATR) steht fest: auf M15 traegt keine Richtungsquelle. Gebaut ist deshalb bewusst KEINE Empfehlung, sondern eine sequenzielle Gate-Kette: [1 HTF-BIAS M30/H1] -> [2 KOSTEN Spread/ATR_M15] -> [3 LEVEL & KEGEL] -> Order AM LEVEL Der Unterschied zur alten Karte ist grundsaetzlich: dort wurden Stimmen zu einem Bias VERRECHNET (gemessen 48-51 % Treffer), hier muss jedes Gate EINZELN passieren. Ein gefallenes Gate laesst sich nicht durch ein anderes ausgleichen. Nur belegte Bausteine: HTF-Trend (einziger robuster Filter, Edge x2), Kosten (M15 gemessen 0,104 gegen M5 0,193), naechstes stehendes Level + P(break), Kegel (out-of-sample kalibriert, 80-%-Band trifft 77 %), Veto (-6,60 EUR/Lot). Status-Banner: SETUP BEREIT / WARTEN AUF LEVEL / KEIN TRADE. Es bestaetigt ausdruecklich auch das NICHT-Handeln - die gemessene Kern-Leckage sind diskretionaere Abweichungen. Die Order-Buttons werden BEWUSST NICHT gesperrt (gegen den Vorschlag "ausgrauen"): hartes Blockieren wurde im Projekt verworfen, und User-Uebersteuerungen liefen gemessen 68 % WR. Umsetzung: engine._m15_setup() setzt nur zusammen, was der Snapshot ohnehin erzeugt. Neu gerechnet wird allein das M15-Kosten-Verhaeltnis und P(break) fuer das naechste Level. Dafuer veroeffentlicht wave_rec jetzt tf_atr (ADDITIV) - der ATR je Zeitebene wurde im Turn-Fetch laengst berechnet, war aber nirgends abrufbar. P(break)-Merkmale bleiben auf M5 (Modell ist darauf trainiert, Fix 2026-07-13). Mit 5 Szenarien getestet (alles passt, Bias uneinig, Kosten teuer, Level zu weit, Kaltstart ohne ATR_M15 -> kein Absturz), live verifiziert ueber deploy.py --feld m15_setup. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
010007f7a3
commit
44955bf70a
@@ -3795,6 +3795,12 @@ class TradingEngine:
|
||||
if (b and a and atr) else None)(
|
||||
(market or {}).get("bid"), (market or {}).get("ask"),
|
||||
((wave_snap or {}).get("pb_feats") or {}).get("atr")),
|
||||
# M15-SETUP-BEREITSCHAFT (2026-08-08) — Ersatz fuer die entfernte
|
||||
# Gesamtempfehlung. ⚠ KEINE Richtungsaussage: auf M15 traegt gemessen
|
||||
# keine (Squeeze n=33/Nachbarn kippen, VWAP-Baender ohne Edge).
|
||||
# Zeigt Bedingungen, nicht Prognosen.
|
||||
"m15_setup": self._m15_setup(market, wave_snap, _cone,
|
||||
self._alignment_cached()),
|
||||
"sr_close_hint": sr_close_hint,
|
||||
"stop_approach": stop_approach,
|
||||
"auto_sr_close": self._auto_sr_close,
|
||||
@@ -3968,6 +3974,84 @@ class TradingEngine:
|
||||
log.debug(f"sr_close_hint: {e}")
|
||||
return None
|
||||
|
||||
def _m15_setup(self, market, wave_snap, cone, alignment) -> dict | None:
|
||||
"""SETUP-BEREITSCHAFT auf M15 — der Ersatz für die entfernte Gesamtempfehlung.
|
||||
|
||||
⚠⚠ BEWUSST KEINE RICHTUNGS-EMPFEHLUNG. Gemessen (2026-08-08) trägt auf
|
||||
M15 KEINE Richtungsquelle: der Squeeze fällt dort durch (n=33 in H1,
|
||||
Nachbarn kippen), VWAP-Bänder ebenso (Zufallslinie hält gleich gut, alle
|
||||
Konfidenzintervalle enthalten die Null), und 24 Signal-Eingriffe sind
|
||||
insgesamt gescheitert. Was BELEGT ist, sind Bedingungen — nicht Prognosen.
|
||||
Die Karte zeigt deshalb das Schema des Users (Bias → Zone → Reichweite →
|
||||
Veto) und überlässt den Auslöser dem Menschen, dessen Auswahl-Vorteil
|
||||
unabhängig belegt ist.
|
||||
|
||||
Zusammengesetzt aus bereits berechneten Teilen — NEU gerechnet wird nur
|
||||
das Kosten-Verhältnis auf M15 und P(break) für das nächste Level. Der
|
||||
Konsens-Pfeil hat einmal ein zweites `_verdict()` gezogen; das ist die
|
||||
Lehre daraus.
|
||||
"""
|
||||
try:
|
||||
bid = (market or {}).get("bid"); ask = (market or {}).get("ask")
|
||||
ws = wave_snap or {}
|
||||
atr15 = (ws.get("tf_atr") or {}).get("M15")
|
||||
out: dict = {"atr_m15": round(atr15, 4) if atr15 else None}
|
||||
|
||||
# ── 1) BIAS — der einzige belegte Filter (M30-Gegen-Trend: Edge ×2)
|
||||
h30 = ws.get("htf_trend"); h1 = ws.get("h1_trend")
|
||||
einig = (h30 and h1 and h30 == h1)
|
||||
out["bias"] = {"m30": h30, "h1": h1,
|
||||
"richtung": h30 if einig else None,
|
||||
"einig": bool(einig)}
|
||||
|
||||
# ── 2) KOSTEN auf M15 — hier gewinnt M15 wirklich (gemessen 0,104
|
||||
# gegen M5 0,193). Schwellen wie beim M5-Chip (0,20 / 0,32).
|
||||
kr = None
|
||||
if bid and ask and atr15 and atr15 > 0:
|
||||
kr = round((ask - bid) / atr15, 3)
|
||||
out["kosten"] = {"ratio": kr,
|
||||
"stufe": (None if kr is None else
|
||||
"guenstig" if kr < 0.20 else
|
||||
"normal" if kr < 0.32 else "teuer")}
|
||||
|
||||
# ── 3) ZONE — nächstes STEHENDES Level (M30-Pivots, dieselbe Quelle
|
||||
# wie Chart und S/R-Close) + P(break). ⚠ Die P(break)-Merkmale
|
||||
# kommen aus M5, weil das Modell darauf trainiert ist (Fix
|
||||
# 2026-07-13) — NICHT auf M15 umstellen.
|
||||
dl = self._draw_levels() or {}
|
||||
res = (dl.get("res") or [None])[0]
|
||||
sup = (dl.get("sup") or [None])[0]
|
||||
pf = ws.get("pb_feats") or {}
|
||||
a5 = pf.get("atr") or 0.2
|
||||
zonen = []
|
||||
for lvl, seite in ((res, "res"), (sup, "sup")):
|
||||
if not lvl or not bid or not atr15:
|
||||
continue
|
||||
d = 1 if seite == "res" else -1
|
||||
gap = abs(lvl - bid)
|
||||
wt = 1.0 if (pf.get("ema_diff", 0.0) or 0.0) * d > 0 else 0.0
|
||||
p = _p_break(pf.get("mom6", 0.0) * d, pf.get("mom3", 0.0) * d,
|
||||
wt, gap / max(a5, 0.06))
|
||||
zonen.append({"seite": seite, "level": round(lvl, 3),
|
||||
"gap_atr15": round(gap / atr15, 2),
|
||||
"p_break": round(100 * p)})
|
||||
out["zonen"] = zonen
|
||||
|
||||
# ── 4) REICHWEITE — der Kegel (kalibriert: 80 %-Band trifft 77 %)
|
||||
lv = (cone or {}).get("levels") or []
|
||||
b80 = [x for x in lv if x.get("band") == 80]
|
||||
out["reichweite"] = [{"minutes": x.get("minutes"),
|
||||
"lo": x.get("lo"), "hi": x.get("hi")}
|
||||
for x in b80] or None
|
||||
|
||||
# ── 5) VETO — die eigene Bilanz, je Lot (absolute Euro sind bei
|
||||
# wechselnder Positionsgröße ungültig, Lehre vom 04.08.)
|
||||
out["veto"] = alignment or None
|
||||
return out
|
||||
except Exception as e:
|
||||
log.debug(f"m15_setup: {e}")
|
||||
return None
|
||||
|
||||
def _stop_approach_hint(self, market, position, wave_snap) -> dict | None:
|
||||
"""REINE ANZEIGE: P(Durchbruch) für das Level, dem sich der Kurs auf der
|
||||
**Gegen-/Stop-Seite** der offenen Position nähert (LONG → Support darunter,
|
||||
|
||||
Reference in New Issue
Block a user