#!/usr/bin/env python3
"""Misst den Effekt eines Higher-TF-Trendfilters auf die Empfehlung.

Vergleicht den Richtungs-Edge der echten _build-Logik OHNE Filter gegen
MIT Filter: Signal wird verworfen, wenn der uebergeordnete Trend (H1 bzw. M30,
EMA12 vs EMA50) klar dagegen steht (Totband in xATR der HTF).
"""
from __future__ import annotations
import sys
import MetaTrader5 as mt5
from core.wave_rec import (WaveRecommender, _atr, _ema_last,
                           _EMA_FAST, _EMA_SLOW, _N_BARS)

_TF = {"M1": mt5.TIMEFRAME_M1, "M5": mt5.TIMEFRAME_M5, "M15": mt5.TIMEFRAME_M15,
       "M30": mt5.TIMEFRAME_M30, "H1": mt5.TIMEFRAME_H1}


class _NeutralTU:
    def snapshot(self):
        return {"intervals": {}}


def _ema_series(vals, period):
    """Komplette EMA-Reihe (gleiche Laenge wie vals)."""
    k = 2.0 / (period + 1)
    out = []
    e = vals[0]
    for i, v in enumerate(vals):
        e = v if i == 0 else v * k + e * (1.0 - k)
        out.append(e)
    return out


def _rep(name, rets):
    if not rets:
        print(f"  {name:<16} keine Signale"); return
    n = len(rets); win = sum(1 for x in rets if x > 0)
    print(f"  {name:<16} n={n:>4}  Treffer={100*win/n:>3.0f}%  "
          f"Oe-Edge={sum(rets)/n:+.4f}  Summe={sum(rets):+.2f}")


def main():
    base_lbl = (sys.argv[1].upper() if len(sys.argv) > 1 else "M5")
    htf_lbl  = (sys.argv[2].upper() if len(sys.argv) > 2 else "H1")
    n_bars   = int(sys.argv[3]) if len(sys.argv) > 3 else 4000
    dead     = float(sys.argv[4]) if len(sys.argv) > 4 else 0.10  # HTF-Totband xATR
    K        = 10
    tf, htf = _TF[base_lbl], _TF[htf_lbl]

    if not mt5.initialize():
        print("MT5-Init fehlgeschlagen:", mt5.last_error()); sys.exit(1)
    sym = None
    for cand in ("SpotCrude", "USOIL", "WTI", "XTIUSD"):
        if mt5.symbol_info(cand):
            sym = cand; break
    sym = sym or "SpotCrude"
    bars = mt5.copy_rates_from_pos(sym, tf, 0, n_bars + _N_BARS + K + 5)
    hbars = mt5.copy_rates_from_pos(sym, htf, 0, n_bars // 2 + 300)
    mt5.shutdown()
    if bars is None or hbars is None:
        print("Zu wenige Bars."); sys.exit(1)

    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]

    hT = [int(b["time"]) for b in hbars]
    hC = [float(b["close"]) for b in hbars]
    hH = [float(b["high"]) for b in hbars]
    hL = [float(b["low"]) for b in hbars]
    hEf = _ema_series(hC, _EMA_FAST)
    hEs = _ema_series(hC, _EMA_SLOW)

    def htf_trend(ts):
        """Vorzeichen des HTF-Trends zum Zeitpunkt ts: +1 auf, -1 ab, 0 flach."""
        # letzte HTF-Bar mit time <= ts
        lo, hi = 0, len(hT) - 1
        idx = -1
        while lo <= hi:
            mid = (lo + hi) // 2
            if hT[mid] <= ts:
                idx = mid; lo = mid + 1
            else:
                hi = mid - 1
        if idx < _EMA_SLOW:
            return 0
        atr = _atr(hH[:idx+1], hL[:idx+1], hC[:idx+1])
        if not atr:
            return 0
        d = hEf[idx] - hEs[idx]
        if abs(d) < dead * atr:
            return 0
        return 1 if d > 0 else -1

    w = WaveRecommender(_NeutralTU(), tf)
    raw = {"LONG": [], "SHORT": []}
    flt = {"LONG": [], "SHORT": []}
    dropped = 0
    for i in range(_N_BARS, len(C) - K):
        win_c = C[i-_N_BARS:i]; win_h = H[i-_N_BARS:i]; win_l = L[i-_N_BARS:i]
        atr = _atr(win_h, win_l, win_c)
        if not atr or atr <= 0:
            continue
        ef = _ema_last(win_c, _EMA_FAST); es = _ema_last(win_c, _EMA_SLOW)
        rec, _ = w._build(ef, es, C[i-1], atr, base_lbl, 5)
        sig = rec["signal"]
        if sig == "WARTEN":
            continue
        fwd = C[i+K] - C[i]
        r = fwd if sig == "LONG" else -fwd
        raw[sig].append(r)
        ht = htf_trend(T[i])
        d = 1 if sig == "LONG" else -1
        if ht != 0 and ht != d:      # HTF steht klar dagegen → verwerfen
            dropped += 1
            continue
        flt[sig].append(r)

    print("=" * 66)
    print(f"  HTF-Filter — {sym}  Basis={base_lbl}  Filter={htf_lbl}  "
          f"Totband={dead}xATR  Vorlauf={K}")
    print("=" * 66)
    print("OHNE Filter:")
    _rep("LONG", raw["LONG"]); _rep("SHORT", raw["SHORT"])
    _rep("ALLE", raw["LONG"] + raw["SHORT"])
    print(f"MIT Filter (verworfen: {dropped}):")
    _rep("LONG", flt["LONG"]); _rep("SHORT", flt["SHORT"])
    _rep("ALLE", flt["LONG"] + flt["SHORT"])


if __name__ == "__main__":
    main()
