#!/usr/bin/env python3 """Misst einen Rebound/Reversal-Einstieg für ÜBERDEHNTE Lagen (jetzt = WARTEN): Kurs weit von der EMA weg (|stretch| >= _STRETCH_MAX) UND Regressions-Winkel hat in die Gegenrichtung gedreht → antizyklischer Einstieg in Winkel-Richtung. überdehnt UNTER EMA + Winkel auf → LONG überdehnt ÜBER EMA + Winkel ab → SHORT Kontrolle: gleiche Überdehnung OHNE Winkel-Bestätigung (reines Fade). """ from __future__ import annotations import sys import MetaTrader5 as mt5 from core.analysis import calc_trend_angle from core.wave_rec import (_atr, _ema_last, _EMA_FAST, _EMA_SLOW, _N_BARS, _STRETCH_MAX) _LR = 14 def _rep(name, r): if not r: print(f" {name:<28} -"); return n=len(r); w=sum(1 for x in r if x>0) print(f" {name:<28} n={n:>4} Treffer={100*w/n:>3.0f}% Oe-Edge={sum(r)/n:+.4f} Summe={sum(r):+.1f}") def main(): n=int(sys.argv[1]) if len(sys.argv)>1 else 8000 dead=2.0 if not mt5.initialize(): print("init",mt5.last_error()); sys.exit(1) sym=None for c in ("SpotCrude","USOIL","WTI","XTIUSD"): if mt5.symbol_info(c): sym=c; break sym=sym or "SpotCrude" KS=[5,10,20] bars=mt5.copy_rates_from_pos(sym,mt5.TIMEFRAME_M5,0,n+_N_BARS+max(KS)+5) mt5.shutdown() if bars is None: print("Bars fehlen"); sys.exit(1) H=[float(b["high"]) for b in bars]; L=[float(b["low"]) for b in bars]; C=[float(b["close"]) for b in bars] print("="*72) print(f" Reversal-Test (überdehnt + Winkel gedreht) — {sym} M5 _STRETCH_MAX={_STRETCH_MAX}") print("="*72) for K in KS: rev=[]; rev_long=[]; rev_short=[]; fade_noang=[] for i in range(_N_BARS,len(C)-K): wc=C[i-_N_BARS:i]; wh=H[i-_N_BARS:i]; wl=L[i-_N_BARS:i] atr=_atr(wh,wl,wc) if not atr or atr<=0: continue ef=_ema_last(wc,_EMA_FAST); es=_ema_last(wc,_EMA_SLOW) stretch=(C[i-1]-es)/atr if abs(stretch) < _STRETCH_MAX: # nur ÜBERDEHNTE Lagen (sonst normal) continue ang=calc_trend_angle(C[i-_LR-2:i], _LR) down_over = stretch <= -_STRETCH_MAX # weit unter EMA up_over = stretch >= _STRETCH_MAX # weit über EMA d=0 if down_over and ang >= 90+dead: d=1 # Rebound long elif up_over and ang <= 90-dead: d=-1 # Rebound short if d!=0: r=(C[i+K]-C[i])*d rev.append(r); (rev_long if d>0 else rev_short).append(r) else: # Überdehnt, aber Winkel NICHT gedreht → reines Fade gegen Überdehnung df = 1 if down_over else -1 fade_noang.append((C[i+K]-C[i])*df) print(f"\nVorlauf {K} Bars:") _rep("Reversal (Winkel best.)", rev) _rep(" davon LONG", rev_long); _rep(" davon SHORT", rev_short) _rep("Fade OHNE Winkel (Kontrolle)", fade_noang) print("\nHinweis: überdehnte Lagen sind selten → kleine n, mit Vorsicht lesen.") if __name__=="__main__": main()