Trading-Buch ausgewertet: 17/20 schon gemessen, die 3 Luecken fallen durch

User reichte 'Praktisches Trading 2.0' (Risueno Gomez) ein. Triage statt alles
nachmessen: 17 der ~20 Konzepte sind im Projekt bereits gemessen und ueberwiegend
verworfen. Ungemessen waren genau drei -- Bollinger, RSI-Divergenz, Drei
Soldaten/Kraehen. Alle drei mit Kontrollgruppe gemessen, keines besteht.

1 Bollinger-Squeeze ist SCHLECHTER als die live laufende ATR-Box (H2 -0,133 gegen
  -0,031, bei halb so vielen Trades). Der wertvollste Test, weil es kein neues
  Signal ist, sondern eine Variante des einzigen validierten Setups.
2 RSI-Divergenz kippt; die Gegenrichtung schlaegt sie in H1 mit KI ohne Null.
3 Drei Soldaten/Kraehen beidhaelftig negativ, Gegenrichtung besser.

In ALLEN DREI ist die Kontrollgruppe besser als die Buch-Lesart -- fuenfte
Bestaetigung derselben Inversion (Kerzen 4x, Winkel, Reversal).

Die Erfolgsraten-Tabelle S. 203 (Kopf-Schulter 83 %) ist unbelegt und
widerspricht der eigenen Messung (Ziel-Trefferquote 13-38 %).

Was das Buch BESTAETIGT ist sein Risikomanagement-Kapitel: nicht die
Trefferquote entscheidet, sondern OeGewinn/OeVerlust und 1-2 % Risiko je Trade.
Genau das misst dieses Projekt unabhaengig (Squeeze 73 % Treffer, PF 0,39,
Verhaeltnis 0,14; MaxDD 82,8 % gegen 22,2 % bei 0,5 % Risiko) -- und es ist der
einzige Punkt, an dem noch nichts umgesetzt ist.

26., 27. und 28. verworfener Signal-Eingriff. 40k Bars = Ausschluss-Urteil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-19 08:04:00 +02:00
co-authored by Claude Opus 5
parent 71bd836f56
commit adda5b0ccc
2 changed files with 366 additions and 0 deletions
+74
View File
@@ -7434,6 +7434,80 @@ vollständig.
**Verifikation der Zustellung steht aus** — sie erfolgt mit dem Report am
nächsten Morgen um 07:30. Die Bausteine sind einzeln live gegengeprüft.
## ⚠⚠ TRADING-BUCH (Risueño Gómez) AUSGEWERTET — 17 von 20 Konzepten waren
## schon gemessen, die übrigen DREI fallen durch (`backtest_buch_luis.py`, 2026-08-19)
User reichte „Praktisches Trading & Analyse 2.0“ ein (35 Chart-Übungen, SMC +
Wyckoff + klassische Muster). **Triage zuerst, nicht alles nachmessen.**
| Buch-Konzept | Stand im Projekt |
|---|---|
| Doppeltop/-boden · Kopf-Schulter · Dreieck · Rechteck · Flagge | `backtest_doubletop` / `_patterns` — Ziel-Trefferquote **1338 %** |
| Kanal · Marktstruktur HH/HL · V-Muster | `backtest_structure_tf`**24/24 Zellen negativ** |
| Kerzen (Hammer · Engulfing · Abend-/Morgenstern · Pin Bar · Doji) | **4× gemessen, Lehrbuch-Lesart beidhälftig INVERTIERT** |
| Fibonacci | 04.08. — hält **schlechter als eine Zufallslinie** gleicher Distanz |
| Order Blocks · FVG · Liquidity Sweeps | SMC = Pivot-Zonen, 6× verworfen |
| Wyckoff Akkumulation/Distribution | `backtest_consolidation` — Basisrate **48/52 %** |
| RSI-**Richtung** | bestätigender RSI kontraproduktiv (Pullback-Effekt) |
| Pullback-Einstieg | ✅ **positiv belegt** — läuft als „⭐ tiefer Pullback“ (+15) |
| S/R als **Zone** | ✅ seit 17.08. im Chart (`RZ`/`SZ`) |
| **R:R ≥ 1:2 / 12 % Risiko** (Kap. 39) | ✅ **stärkste Übereinstimmung** — s. unten |
⚠⚠ **Die Erfolgsraten-Tabelle auf S. 203 ist unbelegt und widerspricht der
Messung.** Sie behauptet Kopf-Schulter **83 %**, Engulfing 7075 %, Doppelboden
7075 % — ohne Quelle, ohne n, ohne Zeitraum. Gemessen sind hier 1338 %
Ziel-Trefferquote und eine invertierte Kerzen-Lesart. **Nicht als Erwartung
verwendet**; gemessen wurde gegen null.
**DIE DREI ECHTEN LÜCKEN — 40k M5, 2 Hälften, kanonischer Exit, Echtkosten,
Fill bei BERÜHRUNG, 95-%-KI. Alle drei mit KONTROLLGRUPPE:**
| | H1 ØR / PF | H2 ØR / PF |
|---|---|---|
| **(1) Bollinger-Squeeze** p15 | +0,128 / 1,23 | **0,133 / 0,80** |
| *KONTROLLE ATR-Box (live)* | *+0,101 / 1,18* | ***0,031 / 0,95*** |
| **(2) RSI-Divergenz** k=5 | **0,150 / 0,75** | +0,085 / 1,17 |
| *KONTROLLE Gegenrichtung* | ***+0,251 / 1,59*** [+0,030 … +0,471] | 0,052 / 0,91 |
| **(3) Drei Soldaten/Krähen** | 0,088 / 0,85 | 0,125 / 0,81 |
| *KONTROLLE Gegenrichtung* | *+0,031* | *+0,140 / 1,27* |
**Keines besteht.** Alle 30 Zellen haben ein KI, das die Null enthält — mit
**einer** Ausnahme, und die ist die **Gegenrichtung** der RSI-Divergenz.
⚠⚠ **BEFUND 1 — die Bollinger-Definition ist SCHLECHTER als die ATR-Box, die
live läuft.** Das war der wertvollste Test, weil es kein neues Signal ist,
sondern eine Variante des **einzigen validierten Setups**: der Squeeze misst
Kompression über die Box-Spanne (≤ 2,5×ATR), das Buch über die Bandbreite
(SMA20 ± 2σ). In H2 liegt Bollinger bei 0,133 gegen 0,031 der Box — und
handelt dabei nur halb so oft (324 gegen 657). **Kein Grund zu wechseln.**
✅ Nebenbefund: die ATR-Box-Kontrolle kippt hier ebenfalls (H1 +0,101 / H2
0,031) — erwartbar, weil dieser Lauf **ohne** Nacht-Gate, Cooldown und
Dedup rechnet. Belastbar ist der **interne** Vergleich, nicht der Absolutwert.
⚠⚠⚠ **BEFUND 2 — DIE FÜNFTE BESTÄTIGUNG DERSELBEN INVERSION.** In **allen
drei** Konzepten ist die Kontrollgruppe (Gegenrichtung) besser als die
Buch-Lesart; bei der RSI-Divergenz schliesst sie in H1 sogar die Null aus
(+0,251, KI [+0,030 … +0,471]). Dasselbe Muster wie bei Kerzen (4×), beim
Winkel-Bonus und beim Reversal: **die Lehrbuch-Deutung von Umkehr- und
Fortsetzungssignalen zeigt in diesem Markt systematisch in die falsche
Richtung.** ⚠ Daraus folgt NICHT „einfach umdrehen“ — die Kontrollen kippen
zwischen den Hälften genauso.
✅✅ **WAS DAS BUCH BESTÄTIGT, IST SEIN KAPITEL 39 — und das ist die eigentliche
Ausbeute.** „Der Erfolg hängt nicht von der Trefferquote ab, sondern vom
Verhältnis ØGewinn/ØVerlust“ und „nie mehr als 12 % je Trade“. Genau das
misst dieses Projekt seit Monaten unabhängig: der Squeeze hat **73 %
Trefferquote und trotzdem PF 0,39**, weil das Verhältnis bei **0,14** liegt;
`analyze_sizing_live.py` misst **MaxDD 82,8 %** und einen schlechtesten
Einzeltrade von **381 €** bei 95-%-Margin-Sizing, gegen **22,2 % MaxDD** bei
0,5 % Risiko je Trade. **Das Buch und die eigenen Zahlen sagen dasselbe — und
es ist der einzige Punkt, an dem noch nichts umgesetzt ist.**
**26., 27. und 28. verworfener Signal-Eingriff.**
**Grenzen:** 40k Bars (nicht die üblichen 80k) — für ein **Ausschluss**-Urteil
ausreichend, für eine Bestätigung wäre es zu wenig. Je eine Definition pro
Konzept. Exit-Slippage nicht modelliert.
## ⚠⚠ DIE KLEIN-CLOSE-FALLE REPRODUZIERT AUF DEN EIGENEN TRADES (2026-08-19)
Suche nach weiteren Optimierungen. Erstmals die `ctx_*`-Telemetrie (seit 04.08.)
+292
View File
@@ -0,0 +1,292 @@
"""Die DREI ungemessenen Konzepte aus Risueno Gomez, "Praktisches Trading 2.0"
(User-Auftrag 2026-08-19: "nutze das PDF fuer neue Ideen").
TRIAGE ZUERST. Von den ~20 Konzepten des Buches sind 17 in diesem Projekt
bereits gemessen und ueberwiegend verworfen (Doppeltop/-boden, Kopf-Schulter,
Dreieck, Rechteck, Kanal, Marktstruktur HH/HL, Kerzenmuster inkl. Hammer/
Engulfing/Stern, Fibonacci, Order Blocks, FVG, Wyckoff, Pullback, RSI-Richtung,
Liquidity Sweeps). Ungemessen sind genau drei:
(1) BOLLINGER-SQUEEZE -- das Wort "Bollinger" kommt in CLAUDE.md NICHT vor.
⚠⚠ Das ist die interessanteste Luecke, weil es KEIN neues Signal ist:
der live laufende Squeeze benutzt eine ATR-Box (Spanne der letzten 10
M5-Bars <= 2,5x ATR). Das Buch definiert Kompression ueber die
BANDBREITE (SMA20 +- 2 Sigma). Gleiche Idee, andere Messgroesse --
also eine Variante des EINZIGEN validierten Setups statt eines 26.
Signal-Eingriffs. Genau dort sagt die Projekt-Logik, man solle suchen.
(2) RSI-DIVERGENZ -- gemessen wurde bisher die RSI-RICHTUNG
(`backtest_confluence.py`: bestaetigender RSI kontraproduktiv, RSI GEGEN
die Richtung = der Pullback-Effekt). Die DIVERGENZ (Preis neues Extrem,
RSI nicht) ist eine dritte, andere Aussage und nie geprueft. Das Buch
nennt sie "eines der wenigen Tools, das den Preis vorwegnehmen kann".
(3) DREI WEISSE SOLDATEN / SCHWARZE KRAEHEN -- als eigene Klasse ungemessen.
⚠ Hohe Beweislast: die Kerzen-Klasse ist 4x gemessen und in der
Lehrbuch-Lesart INVERTIERT. Wird deshalb in BEIDEN Lesarten getestet.
⚠⚠ EINORDNUNG DER BUCH-ZAHLEN (S. 203). Die Tabelle behauptet Kopf-Schulter
83 %, Engulfing 70-75 %, Doppelboden 70-75 %. In diesem Projekt gemessen:
Muster-Ziel-Trefferquote 13-38 % (`backtest_patterns.py`), Doppeltop in allen
Toleranzen durchgefallen, Kerzen-Lesart beidhaelftig invertiert. Die Tabelle
nennt keine Quelle, kein n und keinen Zeitraum. Sie wird hier NICHT als
Erwartung verwendet -- gemessen wird gegen null.
AUFBAU: 80k M5-Bars, 2 Halbjahre, kanonischer Exit (`exit_model.LIVE`),
Echtkosten aus dem Bar-Spread, Fill bei BERUEHRUNG (die am 06.08. als
entscheidend gemessene Achse), 95-%-Bootstrap je Zelle.
REGEL VORAB FIXIERT -- ein Konzept gilt nur dann als tragfaehig, wenn:
(a) OeR > 0 UND PF > 1 in BEIDEN Haelften
(b) das 95-%-KI schliesst in BEIDEN Haelften die Null aus
(c) die Nachbar-Parameter kippen nicht
(d) n >= 100 je Haelfte
Fuer (1) zusaetzlich: die Bollinger-Variante muss die ATR-Box-KONTROLLE auf
DERSELBEN Population schlagen -- sonst ist sie nur eine andere Schreibweise.
Aufruf: python backtest_buch_luis.py [bars]
"""
import sys
import MetaTrader5 as mt5
from backtest_breakout_gated import _atr_series
from backtest_cost_gate import kennzahlen
from core.exit_model import LIVE, simulate
_ATRMIN = 0.06
_COOL = 3
def sma(C, n):
out = [None] * len(C)
s = 0.0
for i, c in enumerate(C):
s += c
if i >= n:
s -= C[i - n]
if i >= n - 1:
out[i] = s / n
return out
def bb_width(C, n=20, k=2.0):
"""Bandbreite (oben-unten)/Mitte -- die Buch-Definition von Kompression."""
m = sma(C, n)
out = [None] * len(C)
for i in range(n - 1, len(C)):
mu = m[i]
var = sum((C[j] - mu) ** 2 for j in range(i - n + 1, i + 1)) / n
sd = var ** 0.5
out[i] = (2 * k * sd / mu) if mu else None
return out, m
def rsi_series(C, p=14):
out = [None] * len(C)
if len(C) < p + 1:
return out
g = l = 0.0
for i in range(1, p + 1):
d = C[i] - C[i - 1]
g += max(d, 0.0); l += max(-d, 0.0)
g /= p; l /= p
out[p] = 100.0 - 100.0 / (1 + g / l) if l else 100.0
for i in range(p + 1, len(C)):
d = C[i] - C[i - 1]
g = (g * (p - 1) + max(d, 0.0)) / p
l = (l * (p - 1) + max(-d, 0.0)) / p
out[i] = 100.0 - 100.0 / (1 + g / l) if l else 100.0
return out
def pivots(V, k):
"""Indizes lokaler Hochs/Tiefs. Kausal nutzbar erst ab j+k."""
ph, pl = [], []
for j in range(k, len(V) - k):
if V[j] is None:
continue
w = [V[x] for x in range(j - k, j + k + 1) if V[x] is not None]
if len(w) < 2 * k + 1:
continue
if V[j] == max(w):
ph.append(j)
if V[j] == min(w):
pl.append(j)
return ph, pl
def trade(i, d, H, L, C, A, SP, ende, puffer):
"""Ruhende Stop-Order am Extrem der Signalbar, Fill bei BERUEHRUNG."""
atr = A[i]
if not atr or atr < _ATRMIN or i + 1 >= ende:
return None
entry = (H[i] if d > 0 else L[i]) + d * puffer * atr
j = None
for x in range(i + 1, min(i + 13, ende)):
if (H[x] >= entry) if d > 0 else (L[x] <= entry):
j = x
break
if j is None or j + 1 >= ende:
return None
r = simulate(entry, d, atr, H, L, C, j + 1, LIVE, timestop=True, use_tp=True)
return r - ((SP[j] if SP[j] > 0 else 0.0225) / atr)
def zeig(lbl, k1, k2):
def f(k):
if not k:
return " --"
ci = k.get("ci")
m = ""
if ci:
m = (" [{:+.3f} .. {:+.3f}]".format(ci[0], ci[1])
+ ("" if ci[0] * ci[1] > 0 else " ~0"))
return ("n={:>4} WR={:>3.0f}% OeR={:+.3f} PF={:.2f}{}"
.format(k["n"], k["wr"], k["oer"], k["pf"], m))
print(" {:<30} H1 {}".format(lbl, f(k1)))
print(" {:<30} H2 {}".format("", f(k2)))
def main():
n = int(sys.argv[1]) if len(sys.argv) > 1 else 80000
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_M5, 0, n)
point = mt5.symbol_info(sym).point
mt5.shutdown()
H = [float(b["high"]) for b in bars]; L = [float(b["low"]) for b in bars]
C = [float(b["close"]) for b in bars]; O = [float(b["open"]) for b in bars]
SP = [float(b["spread"]) * point for b in bars]
A = _atr_series(H, L, C)
N = len(C); mid = N // 2; ende = N - LIVE.max_hold - 1
print("=" * 96)
print(" BUCH-KONZEPTE (Risueno Gomez) -- {} M5 ({} Bars, 2 Halbjahre)".format(sym, N))
print(" Exit kanonisch - Echtkosten - Fill bei BERUEHRUNG - 95-%-KI")
print("=" * 96)
# ---------------------------------------------------------------- (1)
print("\n (1) BOLLINGER-SQUEEZE gegen die ATR-BOX des laufenden Systems")
print(" " + "-" * 92)
BW, M20 = bb_width(C)
for lo_, hi_, tag in ((0, mid, "H1"), (mid, ende, "H2")):
pass
for pct, gu in ((0.15, 50), (0.25, 50), (0.15, 100)):
res = {"bb": [[], []], "atr": [[], []]}
for h, (lo_, hi_) in enumerate(((0, mid), (mid, ende))):
i = max(lo_, 120)
while i < hi_:
atr = A[i]
if not atr or atr < _ATRMIN or BW[i] is None:
i += 1; continue
fenster = [x for x in BW[i - gu:i] if x is not None]
if len(fenster) < gu // 2:
i += 1; continue
schwelle = sorted(fenster)[int(pct * len(fenster))]
# Buch: Kontraktion = Bandbreite im unteren Perzentil
bb_komp = BW[i] <= schwelle
# Projekt: Box-Spanne der letzten 10 Bars <= 2,5x ATR
box_hi = max(H[i - 10:i]); box_lo = min(L[i - 10:i])
atr_komp = (box_hi - box_lo) <= 2.5 * atr
d = 0
if C[i] > box_hi:
d = 1
elif C[i] < box_lo:
d = -1
if d:
if bb_komp:
r = trade(i, d, H, L, C, A, SP, ende, 0.0)
if r is not None:
res["bb"][h].append(r)
if atr_komp:
r = trade(i, d, H, L, C, A, SP, ende, 0.0)
if r is not None:
res["atr"][h].append(r)
i += _COOL
else:
i += 1
zeig("BOLLINGER p{:.0f} f{}".format(pct * 100, gu),
kennzahlen(res["bb"][0]), kennzahlen(res["bb"][1]))
zeig(" KONTROLLE ATR-Box (live)",
kennzahlen(res["atr"][0]), kennzahlen(res["atr"][1]))
print("")
# ---------------------------------------------------------------- (2)
print(" (2) RSI-DIVERGENZ (Preis neues Extrem, RSI nicht)")
print(" " + "-" * 92)
R = rsi_series(C)
for k in (3, 5):
ph, pl = pivots(C, k)
res = [[], []]
gegen = [[], []]
for name, piv, d in (("bull", pl, 1), ("bear", ph, -1)):
for a, b in zip(piv, piv[1:]):
if b - a > 60 or b - a < 5 or R[a] is None or R[b] is None:
continue
# bullisch: tieferes Tief im Preis, hoeheres Tief im RSI
if d > 0:
ok = C[b] < C[a] and R[b] > R[a]
else:
ok = C[b] > C[a] and R[b] < R[a]
if not ok:
continue
i = b + k # kausal: Pivot erst k Bars spaeter bekannt
if i >= ende:
continue
h = 0 if i < mid else 1
r = trade(i, d, H, L, C, A, SP, ende, 0.0)
if r is not None:
res[h].append(r)
rg = trade(i, -d, H, L, C, A, SP, ende, 0.0)
if rg is not None:
gegen[h].append(rg)
zeig("Divergenz k={} (Buch-Lesart)".format(k),
kennzahlen(res[0]), kennzahlen(res[1]))
zeig(" KONTROLLE Gegenrichtung", kennzahlen(gegen[0]), kennzahlen(gegen[1]))
print("")
# ---------------------------------------------------------------- (3)
print(" (3) DREI WEISSE SOLDATEN / DREI SCHWARZE KRAEHEN")
print(" " + "-" * 92)
res = [[], []]; geg = [[], []]
i = 5
while i < ende:
atr = A[i]
if not atr or atr < _ATRMIN:
i += 1; continue
d = 0
for dd in (1, -1):
ok = True
for x in (i - 2, i - 1, i):
koerper = (C[x] - O[x]) * dd
spanne = H[x] - L[x]
if koerper <= 0 or spanne <= 0 or koerper < 0.5 * spanne:
ok = False; break
if x > i - 2:
# oeffnet im Koerper der Vorkerze, schliesst nahe Extrem
if not (min(O[x - 1], C[x - 1]) <= O[x] <= max(O[x - 1], C[x - 1])):
ok = False; break
if (C[x] - C[x - 1]) * dd <= 0:
ok = False; break
if ok:
d = dd; break
if d:
h = 0 if i < mid else 1
r = trade(i, d, H, L, C, A, SP, ende, 0.0)
if r is not None:
res[h].append(r)
rg = trade(i, -d, H, L, C, A, SP, ende, 0.0)
if rg is not None:
geg[h].append(rg)
i += _COOL
else:
i += 1
zeig("Fortsetzung (Buch-Lesart)", kennzahlen(res[0]), kennzahlen(res[1]))
zeig(" KONTROLLE Gegenrichtung", kennzahlen(geg[0]), kennzahlen(geg[1]))
print("=" * 96)
if __name__ == "__main__":
main()