Artefakt, das einen alten Schluss entwertet
Anlass: Frage zur Trail-Kalibrierung "jetzt bei 3 Lot". Zur Praemisse: die
Positionsgroesse aendert das Optimum NICHT (R ist ATR-normiert). Gemessen wurde
die echte offene Frage - be=1,3 stammt aus der Zeit mit Trail 1,5, mult wurde am
31.07. auf 1,0 gesenkt ohne das Breakeven neu zu pruefen.
(1) Breakeven ist praktisch wirkungslos: bei mult <= 0,6 sind alle be-Zeilen
identisch (der enge Trail erreicht den Einstand frueher als der BE-Boden). Bei
mult 1,0 ist be=0,6 um +0,019 besser - unter einem Standardfehler. Keine
Aenderung.
(2) Der Trail ist monoton besser bis hinunter zu 0,05 xATR (~3 Cent) - das waere
vom Spread allein ausgeloest. Ein Optimum, das bis an die physikalische
Unmoeglichkeit monoton bleibt, misst die Methode, nicht den Markt.
Aufloesungs-Artefakt nachgewiesen (analyze_trail_resolution.py): mit in DOLLAR
fixiertem Trail auf M5 gegen M1, 597 gemeinsame Einstiege, kippt das Vorzeichen
der Differenz bei ~0,3 xATR - die groebere Aufloesung ueberschaetzt enge Trails
(-0,027 bei 0,10) und unterschaetzt weite (+0,036 bei 1,0, +0,066 bei 1,5).
Damit ist der Befund vom 31.07. ("enger ist monoton besser") teilweise entwertet.
Erster Testentwurf war falsch konstruiert: der Trail wurde mit dem ATR der
jeweiligen Zeitebene skaliert, damit bleibt das Verhaeltnis Trail/Bar-Spanne
konstant und die Aufloesung wird gar nicht variiert.
Nebenbefund gegen die eigene Slippage-Vermutung: die Trade-Zahl ist ueber alle
Multiplikatoren fast konstant (2108 bei 0,3 gegen 2083 bei 1,0), Worst-Case
ueberall -2,44. Das Slippage-Argument traegt kaum, das Aufloesungs-Argument
traegt.
Ergebnis: Trail 1,0 / Breakeven 1,3 bleiben.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
53 lines
2.2 KiB
Python
53 lines
2.2 KiB
Python
"""Korrigierter Aufloesungs-Test.
|
|
|
|
FEHLER im ersten Versuch: der Trail wurde mit dem ATR der JEWEILIGEN Zeitebene
|
|
skaliert. Damit bleibt das Verhaeltnis Trail/Bar-Spanne konstant — die Aufloesung
|
|
wird gar nicht variiert. Richtig: Trail in DOLLAR fixieren, nur die Bar-Groesse
|
|
aendern. Dieselben Einstiegszeitpunkte auf beiden Zeitebenen.
|
|
"""
|
|
import sys
|
|
from datetime import datetime, timedelta, timezone
|
|
sys.path.insert(0, r"c:\Users\ah\Downloads\tradingrobot")
|
|
import MetaTrader5 as mt5
|
|
from core.exit_model import LIVE, simulate
|
|
|
|
ATR_FIX = 0.30 # $ — fuer BEIDE Zeitebenen identisch
|
|
mt5.initialize()
|
|
sym = next(c for c in ("SpotCrude","USOIL","WTI") if mt5.symbol_info(c))
|
|
d = {}
|
|
for lbl, tf, n in (("M5", mt5.TIMEFRAME_M5, 40000), ("M1", mt5.TIMEFRAME_M1, 60000)):
|
|
b = mt5.copy_rates_from_pos(sym, tf, 0, n)
|
|
d[lbl] = {"T":[int(x["time"]) for x in b],
|
|
"H":[float(x["high"]) for x in b], "L":[float(x["low"]) for x in b],
|
|
"C":[float(x["close"]) for x in b]}
|
|
mt5.shutdown()
|
|
print(f"M5 {len(d['M5']['T'])} Bars · M1 {len(d['M1']['T'])} Bars")
|
|
# gemeinsamer Zeitraum
|
|
t_von = max(d["M5"]["T"][0], d["M1"]["T"][0]); t_bis = min(d["M5"]["T"][-1], d["M1"]["T"][-1])
|
|
import bisect
|
|
m1T = d["M1"]["T"]
|
|
paare = []
|
|
for i,t in enumerate(d["M5"]["T"]):
|
|
if not (t_von <= t <= t_bis) or i % 20: continue
|
|
j = bisect.bisect_left(m1T, t)
|
|
if 0 < j < len(m1T)-300: paare.append((i,j))
|
|
print(f"gemeinsame Einstiege: {len(paare)}")
|
|
print()
|
|
print(f"{'Trail $':>9}{'= xATR':>8}{'M5 OeR':>10}{'M1 OeR':>10}{'Differenz':>11}")
|
|
print("-"*48)
|
|
for mult in (0.1,0.2,0.3,0.5,0.8,1.0,1.5):
|
|
p = LIVE.with_(mult=mult)
|
|
out = {}
|
|
for lbl, idx in (("M5",0), ("M1",1)):
|
|
X = d[lbl]; rs=[]
|
|
for pr in paare:
|
|
k = pr[idx]
|
|
rs.append(simulate(X["C"][k], 1, ATR_FIX, X["H"], X["L"], X["C"], k+1,
|
|
p, timestop=False, use_tp=True))
|
|
out[lbl] = sum(rs)/len(rs)
|
|
print(f"{mult*ATR_FIX:>9.3f}{mult:>8.2f}{out['M5']:>+10.3f}{out['M1']:>+10.3f}"
|
|
f"{out['M1']-out['M5']:>+11.3f}")
|
|
print()
|
|
print("Wird die Differenz bei engem Trail deutlich NEGATIV, ist der M5-Befund")
|
|
print("'enger ist immer besser' ein Aufloesungs-Artefakt.")
|