#!/usr/bin/env python3
"""Verlässlichkeit der Bounce-Anzeige ('aktiv'): Wenn _bounce_one(TF)=active feuert
(überdehnt + Winkel gedreht), wie oft bewegt sich der Kurs in Bounce-Richtung?
Aufgeschlüsselt nach TF (M1/M5/M15/M30) und nach H1-Regime (mit/gegen/flach zur
Bounce-Richtung). Nur ONSET (Übergang nicht-aktiv→aktiv) = unabhängige Ereignisse.
"""
import sys, bisect
import MetaTrader5 as mt5
from core.wave_rec import WaveRecommender, _atr, _ema_last, _EMA_FAST, _EMA_SLOW, _HTF_DEADBAND
K = 10   # Vorlauf in Bars der jeweiligen TF

def _ema_series(v,p):
    k=2.0/(p+1); o=[]; e=v[0]
    for i,x in enumerate(v): e=x if i==0 else x*k+e*(1-k); o.append(e)
    return o
def _atr_series(H,L,C,p=14):
    t=[0.0]
    for i in range(1,len(C)): t.append(max(H[i]-L[i],abs(H[i]-C[i-1]),abs(L[i]-C[i-1])))
    return [(sum(t[max(1,i-p+1):i+1])/max(1,len(t[max(1,i-p+1):i+1]))) if i else None for i in range(len(C))]

def main():
    n=int(sys.argv[1]) if len(sys.argv)>1 else 40000
    mt5.initialize()
    sym=None
    for c in ("SpotCrude","USOIL","WTI","XTIUSD"):
        if mt5.symbol_info(c): sym=c; break
    # H1-Regime vorbereiten
    h1=mt5.copy_rates_from_pos(sym,mt5.TIMEFRAME_H1,0,20000)
    hT=[int(b["time"]) for b in h1]; hc=[float(b["close"]) for b in h1]
    hh=[float(b["high"]) for b in h1]; hl=[float(b["low"]) for b in h1]
    hEf=_ema_series(hc,_EMA_FAST); hEs=_ema_series(hc,_EMA_SLOW); hA=_atr_series(hh,hl,hc)
    def h1_sign(ts):
        idx=bisect.bisect_right(hT,ts)-1
        if idx<_EMA_SLOW or hA[idx] is None or hA[idx]<=0: return 0
        d=hEf[idx]-hEs[idx]
        return 0 if abs(d)<_HTF_DEADBAND*hA[idx] else (1 if d>0 else -1)

    tfs=[("M1",mt5.TIMEFRAME_M1),("M5",mt5.TIMEFRAME_M5),
         ("M15",mt5.TIMEFRAME_M15),("M30",mt5.TIMEFRAME_M30)]
    print("="*86)
    print(f"  Bounce-Anzeige 'aktiv' — Verlässlichkeit je TF & H1-Regime  ({sym}, Vorlauf {K} Bars)")
    print("  Treffer = Kurs bewegt sich in Bounce-Richtung · Ø = Ø-Bewegung in ATR")
    print("="*86)
    for lbl,tf in tfs:
        r=mt5.copy_rates_from_pos(sym,tf,0,n)
        if r is None or len(r)<200: print(f"{lbl}: zu wenig Bars"); continue
        T=[int(b["time"]) for b in r]; H=[float(b["high"]) for b in r]
        L=[float(b["low"]) for b in r]; C=[float(b["close"]) for b in r]
        buckets={"mit":[], "gegen":[], "flach":[], "alle":[]}
        prev=False
        for i in range(120, len(C)-K):
            wc=C[i-119:i+1]; wh=H[i-119:i+1]; wl=L[i-119:i+1]
            atr=_atr(wh,wl,wc)
            if not atr or atr<=0: prev=False; continue
            b=WaveRecommender._bounce_one(wc,atr)
            active = bool(b and b["state"]=="active")
            if active and not prev:
                d=1 if b["dir"]=="LONG" else -1
                fwd=(C[i+K]-C[i])*d/atr        # in ATR, Bounce-Richtung
                reg=h1_sign(T[i])
                cls = "mit" if reg==d else "gegen" if reg==-d else "flach"
                buckets[cls].append(fwd); buckets["alle"].append(fwd)
            prev=active
        print(f"\n{lbl}  ({len(buckets['alle'])} aktive Bounce-Signale)")
        for cls in ("alle","mit","gegen","flach"):
            v=buckets[cls]
            if not v: print(f"   {cls:<6} -"); continue
            hit=100*sum(1 for x in v if x>0)/len(v)
            print(f"   {cls:<6} n={len(v):>4}  Treffer={hit:>3.0f}%  Ø={sum(v)/len(v):+.2f}×ATR")
    mt5.shutdown()
    print("\n  'mit'   = H1-Trend in Bounce-Richtung (Trend-Fortsetzung)")
    print("  'gegen' = H1-Trend GEGEN den Bounce (Gegen-Trend-Fade)")
    print("  'flach' = H1 neutral (reine Range/Mean-Reversion)")

if __name__=="__main__":
    main()
