M15-Karte an 7 Tagen getestet: Veto haelt ueber 2 Halbjahre, Woche war Rauschen
Wochentest (test_m15_karte_woche.py, 30.07.-07.08., 93 Episoden) meldete das Veto als FALSCH herum: MIT dem HTF OeR -0,273 / PF 0,56, GEGEN den HTF +0,258 / PF 1,83 - Differenz -0,532 R gegen die erlaubte Richtung. Gegenprobe ueber 2 Halbjahre auf DERSELBEN Population (Level-Beruehrungen, M15): H1 (n=1504) MIT -0,072 / PF 0,87 GEGEN -0,116 / PF 0,80 -> +0,044 R H2 (n=1617) MIT +0,028 / PF 1,06 GEGEN -0,012 / PF 0,98 -> +0,040 R Beidhaelftig konsistent. Die Woche war Rauschen (n=93 gegen n=3121). Dieselbe Falle wie bei der 15-Minuten-Regel und dem Nacht-Guard. Der Verdacht war trotzdem berechtigt: der HTF-Filter ist auf SIGNAL-Entries validiert (backtest_htf_filter.py), nicht auf Level-Beruehrungen. Auf der Level-Population traegt er +0,04 R statt des dokumentierten "Edge x2" - richtig, aber klein. Was der Test sonst zeigt - die Karte ist zu permissiv: gruene Bars je Tag 22-56 von 92 (24-61 %) Episoden je Tag 14,7 Kosten-Gate blockte 0 von 644 Bars Das Kosten-Gate ist auf M15 dekorativ (Spread/ATR ~0,10, Schwelle 0,32). Die Level-Einstiege selbst tragen kaum (OeR -0,072 / +0,028); das Veto macht sie nur weniger schlecht. Die einzige diskriminierende Schwelle (Reichweite 0,5xATR) ist gesetzt, nicht gemessen. Fehler im Test selbst, dokumentiert: der erste Lauf zaehlte 46 fortlaufende gruene Bars als 46 Trades und meldete 7 % Trefferquote - eine Bewegung 46-mal gezaehlt. Erst die Entkopplung macht die Zahl lesbar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
30830d76b1
commit
6a9b554d54
@@ -4942,6 +4942,54 @@ Modell schliesst keine Trades.
|
||||
„die Rangfolge ist kaputt" ist **nicht** belegt; belegt ist nur die
|
||||
Basisraten-/Kalibrierungslücke.
|
||||
|
||||
## ⚠⚠ M15-KARTE AN 7 TAGEN GETESTET — zwei eigene Fehler, einer davon fast veröffentlicht (2026-08-08)
|
||||
|
||||
**(1) BIAS WAR EIN RICHTUNGSGEBER — korrigiert zum VETO (v=155).** Der Tagestest
|
||||
an 07.08. (`test_m15_karte_tag.py`) zeigte: 46 von 92 Bars grün, entkoppelt
|
||||
**13 Episoden — ALLE LONG**, an einem Tag, der von 78,399 auf 77,383 **fiel**.
|
||||
Trefferquote **0 %**, ØR −0,753.
|
||||
⚠ Ursache strukturell, nicht Pech: gemessen ist „gegen den M30-Trend halbiert
|
||||
den Edge" — eine **VERBOTS**-Aussage. Ich hatte daraus „M30+H1 einig → Bias
|
||||
LONG" gemacht, also einen Richtungsgeber. **Exakt der Fehler, wegen dem die
|
||||
Gesamtempfehlung entfernt wurde** (Richtung dort 48–51 % Treffer). Behoben:
|
||||
`bias.richtung` ist dauerhaft `None`, das Feld liefert nur noch die **verbotene**
|
||||
Richtung; das Banner nennt keine Richtung mehr.
|
||||
|
||||
**(2) FAST EINEN FEHLALARM VERÖFFENTLICHT.** Der Wochentest
|
||||
(`test_m15_karte_woche.py`, 30.07.–07.08., 93 Episoden) meldete das Veto als
|
||||
**falsch herum**: MIT dem HTF ØR −0,273 / PF 0,56, GEGEN den HTF **+0,258 /
|
||||
PF 1,83** — Differenz −0,532 R gegen die erlaubte Richtung.
|
||||
✅ **Über 2 Halbjahre auf DERSELBEN Population (Level-Berührungen, M15) hält das
|
||||
Veto aber:**
|
||||
| | MIT dem HTF | GEGEN den HTF | Differenz |
|
||||
|---|---|---|---|
|
||||
| **H1** (n=1504) | −0,072 / PF 0,87 | −0,116 / PF 0,80 | **+0,044 R** |
|
||||
| **H2** (n=1617) | +0,028 / PF 1,06 | −0,012 / PF 0,98 | **+0,040 R** |
|
||||
Beidhälftig konsistent, gleiche Größenordnung. **Die Woche war Rauschen** —
|
||||
n=93 gegen n=3121. Dieselbe Falle wie bei der 15-Minuten-Regel (31.07.) und dem
|
||||
Nacht-Guard (05.08.): ein Zeitraum, der zum Beleg erhoben wird.
|
||||
⚠ Der Verdacht, der mich zur Gegenprüfung brachte, war trotzdem berechtigt: der
|
||||
HTF-Filter ist auf **Signal**-Entries validiert (`backtest_htf_filter.py`), nicht
|
||||
auf Level-Berührungen. Auf der Level-Population trägt er **+0,04 R** statt des
|
||||
dokumentierten „Edge ×2" — richtig, aber klein.
|
||||
|
||||
**(3) WAS DER TEST SONST ZEIGT — die Karte ist zu permissiv:**
|
||||
| | |
|
||||
|---|---|
|
||||
| grüne Bars je Tag | 22–56 von 92 (**24–61 %**) |
|
||||
| Episoden je Tag | **14,7** |
|
||||
| Kosten-Gate blockte | **0 von 644 Bars** |
|
||||
Das Kosten-Gate ist auf M15 **dekorativ**: Spread/ATR liegt dort bei ~0,10, die
|
||||
Schwelle bei 0,32. Und die Level-Einstiege selbst tragen kaum (ØR −0,072 / +0,028
|
||||
über 2 Halbjahre) — das Veto macht sie nur **weniger schlecht**.
|
||||
⚠ Die einzige diskriminierende Schwelle (Reichweite 0,5×ATR) ist **gesetzt, nicht
|
||||
gemessen**.
|
||||
|
||||
⚠⚠ **Und ein Fehler im TEST selbst:** der erste Lauf zählte 46 fortlaufende
|
||||
grüne Bars als 46 Trades und meldete 7 % Trefferquote — **eine Bewegung 46-mal
|
||||
gezählt**. Erst die Entkopplung auf zusammenhängende Blöcke macht die Zahl
|
||||
lesbar. Dieselbe Klasse wie die Clusterung bei `pbreak_predictions` (07.08.).
|
||||
|
||||
## ✅ M15-KARTE „SETUP-BEREITSCHAFT" GEBAUT (2026-08-08, v=153) — Ersatz der Gesamtempfehlung
|
||||
|
||||
Nach dem Entfernen der Gesamtempfehlung und drei negativen M15-Messungen
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
"""M15-Karte über eine ganze Woche — was behauptet sie, und stimmt es?
|
||||
|
||||
⚠⚠ DIE FRAGE „WIE VIELE KORREKTE EMPFEHLUNGEN?" MUSS NEU GESTELLT WERDEN.
|
||||
Seit der Korrektur vom 08.08. gibt die Karte **keine Richtung** mehr aus
|
||||
(`bias.richtung` ist dauerhaft None). Grund: der erste Entwurf machte aus dem
|
||||
gemessenen VERBOT („gegen den M30-Trend halbiert den Edge") einen
|
||||
Richtungsgeber — und erzeugte am 07.08. dreizehn LONG-Episoden an einem Tag,
|
||||
der 1,02 $ fiel (Trefferquote 0 %).
|
||||
|
||||
Prüfbar ist deshalb nur, was die Karte NOCH behauptet:
|
||||
(A) das VETO — ist die verbotene Richtung tatsächlich schlechter als die
|
||||
erlaubte? Das ist die einzige Richtungsaussage, die überhaupt bleibt.
|
||||
(B) das LEVEL — trägt eine Order AM stehenden Level (statt zum Markt)?
|
||||
(C) die MECHANIK — wie oft grün/gelb/rot, welches Gate blockt?
|
||||
|
||||
⚠ Beide Richtungen werden auf DENSELBEN Episoden gerechnet — nur so misst der
|
||||
Vergleich das Veto und nicht zwei verschiedene Trade-Folgen.
|
||||
⚠ EINE WOCHE = EIN REGIME. Das ist ausdrücklich KEIN Edge-Nachweis (die
|
||||
2-Stichproben-Regel bleibt), sondern eine Mechanik- und Plausibilitätsprüfung.
|
||||
|
||||
Aufruf: python test_m15_karte_woche.py [tage] (Default 7)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
import MetaTrader5 as mt5
|
||||
|
||||
from core.exit_model import LIVE, simulate
|
||||
from core.sr_levels import halten, linien, naechste
|
||||
from test_m15_karte_tag import _berlin, atr_series, htf_sign, m30_levels
|
||||
|
||||
_KOST_MAX = 0.32
|
||||
_REICH = 0.5 # ⚠ GESETZT, nicht gemessen — der einzige diskriminierende Gate
|
||||
|
||||
|
||||
def main():
|
||||
tage = int(sys.argv[1]) if len(sys.argv) > 1 else 7
|
||||
mt5.initialize()
|
||||
sym = next((c for c in ("SpotCrude", "USOIL", "WTI", "XTIUSD")
|
||||
if mt5.symbol_info(c)), None)
|
||||
bars = mt5.copy_rates_from_pos(sym, mt5.TIMEFRAME_M15, 0, 6000)
|
||||
point = mt5.symbol_info(sym).point
|
||||
mt5.shutdown()
|
||||
T = [int(b["time"]) for b in bars]
|
||||
H = [float(b["high"]) for b in bars]; L = [float(b["low"]) for b in bars]
|
||||
C = [float(b["close"]) for b in bars]
|
||||
SP = [float(b["spread"]) * point for b in bars]
|
||||
A = atr_series(H, L, C)
|
||||
S30, S1H = htf_sign(H, L, C, 2), htf_sign(H, L, C, 4)
|
||||
LV = m30_levels(H, L, C)
|
||||
|
||||
proTag = defaultdict(list)
|
||||
for i, t in enumerate(T):
|
||||
proTag[_berlin(t).strftime("%Y-%m-%d")].append(i)
|
||||
datteln = sorted(proTag)[-tage:]
|
||||
|
||||
print("=" * 100)
|
||||
print(f" M15-KARTE — {len(datteln)} Handelstage ({datteln[0]} bis {datteln[-1]}), {sym}")
|
||||
print(" ⚠ Die Karte gibt KEINE Richtung mehr aus. Geprüft wird das VETO und das LEVEL.")
|
||||
print("=" * 100)
|
||||
print(f"\n {'Tag':<12}{'Bars':>5}{'grün':>7}{'gelb':>7}{'rot':>6}"
|
||||
f"{'Epis.':>7}{'Bewegung':>11}")
|
||||
|
||||
alle_erlaubt, alle_verboten, alle_epi = [], [], 0
|
||||
tagszeilen = []
|
||||
for d in datteln:
|
||||
idx = proTag[d]
|
||||
if len(idx) < 20:
|
||||
continue
|
||||
st_liste = []
|
||||
prev_r = prev_s = None
|
||||
for i in idx:
|
||||
a = A[i]
|
||||
if not a or not LV[i]:
|
||||
st_liste.append((i, None, None, None)); continue
|
||||
ph, pl = LV[i]
|
||||
lv = linien(ph, pl, a)
|
||||
r, s = naechste(lv, C[i])
|
||||
r = halten(r, prev_r, C[i], a, True)
|
||||
s = halten(s, prev_s, C[i], a, False)
|
||||
prev_r, prev_s = r, s
|
||||
kr = SP[i] / a
|
||||
gaps = [(abs(x - C[i]) / a, x) for x in (r, s) if x is not None]
|
||||
nah = [g for g in gaps if g[0] <= _REICH]
|
||||
zu = "rot" if kr >= _KOST_MAX else ("gruen" if nah else "gelb")
|
||||
st_liste.append((i, zu, S30[i], nah[0][1] if nah else None))
|
||||
|
||||
gr = sum(1 for _, z, _, _ in st_liste if z == "gruen")
|
||||
ge = sum(1 for _, z, _, _ in st_liste if z == "gelb")
|
||||
ro = sum(1 for _, z, _, _ in st_liste if z == "rot")
|
||||
|
||||
# Episoden = erste Bar je zusammenhaengendem Gruen-Block
|
||||
epi, vor = [], None
|
||||
for i, z, h30, lvl in st_liste:
|
||||
if z == "gruen" and vor != "gruen":
|
||||
epi.append((i, h30, lvl, A[i], SP[i] / A[i]))
|
||||
vor = z
|
||||
alle_epi += len(epi)
|
||||
|
||||
# ⚠ BEIDE Richtungen auf DENSELBEN Episoden — das misst das Veto
|
||||
for i, h30, lvl, a, kr in epi:
|
||||
if not h30:
|
||||
continue # HTF flach -> kein Veto -> nichts zu pruefen
|
||||
erlaubt = 1 if h30 == 1 else -1 # mit dem HTF
|
||||
alle_erlaubt.append(simulate(lvl, erlaubt, a, H, L, C, i + 1, LIVE) - kr)
|
||||
alle_verboten.append(simulate(lvl, -erlaubt, a, H, L, C, i + 1, LIVE) - kr)
|
||||
|
||||
bew = C[idx[-1]] - C[idx[0]]
|
||||
tagszeilen.append((d, len(idx), gr, ge, ro, len(epi), bew))
|
||||
print(f" {d:<12}{len(idx):>5}{gr:>7}{ge:>7}{ro:>6}{len(epi):>7}{bew:>+10.2f} $")
|
||||
|
||||
def kz(Rs, name):
|
||||
if not Rs:
|
||||
return f" {name:<34} —"
|
||||
n = len(Rs); w = sum(1 for x in Rs if x > 0); s = sum(Rs)
|
||||
g = sum(x for x in Rs if x > 0); v = -sum(x for x in Rs if x < 0)
|
||||
return (f" {name:<34} n={n:>3} Treffer={100*w/n:>3.0f}% ØR={s/n:+.3f} "
|
||||
f"PF={(g/v if v > 0 else 9.99):>4.2f} ΣR={s:>+6.1f}")
|
||||
|
||||
print(f"\n {'-'*96}")
|
||||
print(f" (A) DAS VETO — beide Richtungen auf denselben {len(alle_erlaubt)} Episoden")
|
||||
print(kz(alle_erlaubt, "MIT dem HTF (erlaubt)"))
|
||||
print(kz(alle_verboten, "GEGEN den HTF (verboten)"))
|
||||
if alle_erlaubt and alle_verboten:
|
||||
d = sum(alle_erlaubt) / len(alle_erlaubt) - sum(alle_verboten) / len(alle_verboten)
|
||||
print(f" → Unterschied {d:+.3f} R je Trade zugunsten der ERLAUBTEN Richtung")
|
||||
print(f" {'✅ Veto zeigt in die richtige Richtung' if d > 0 else '❌ Veto zeigt FALSCH'}")
|
||||
print(f"\n Episoden gesamt: {alle_epi} an {len(tagszeilen)} Tagen "
|
||||
f"= {alle_epi/max(1,len(tagszeilen)):.1f} je Tag")
|
||||
print("\n ⚠ EINE WOCHE = EIN REGIME. Kein Edge-Nachweis, nur Mechanik.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user