"""Traegt Trail 1,0 ueber die ZEITACHSE - oder nur ueber zwei Haelften? (2026-08-19)

Der Walk-Forward-Lauf vom selben Tag hat gezeigt, dass "beidhaelftig positiv"
Instabilitaet verdecken kann: der Squeeze war in nur 4 von 8 Bloecken positiv,
und die einzigen zwei Bloecke mit Intervall ohne Null waren BEIDE negativ.

Diese Sicht fehlt fuer den LIVE-Exit. `LIVE.mult` steht seit dem 31.07. auf 1,0,
validiert ueber zwei Halbjahre (`backtest_trailmult.py`: enger ist monoton
besser). Der Multiplikator betrifft JEDEN Trade - ist er ueber die Zeitachse
instabil, ist das wichtiger als jede Signal-Idee.

⚠ GEPAART gerechnet: alle Multiplikatoren laufen auf DENSELBEN Einstiegen, und
verglichen wird die Differenz je Trade. Der sequentielle Vergleich waere hier
ungueltig - ein anderer Exit laesst ANDERE Trades in den einen Slot, das ist ein
Selektions- und kein Exit-Effekt (die Falle vom 14.08. beim trail_start-Sweep).

⚠ GRENZE: kuerzere Bloecke -> breitere KI. Ausgewertet wird das VORZEICHENMUSTER
der Differenz, nicht der Einzelblock.

Aufruf:  python backtest_trail_wf.py [bars] [bloecke]
"""
import sys

import MetaTrader5 as mt5

from core.exit_model import LIVE, simulate
from core.squeeze_scan import atr_series, scan
from core.stichprobe import paarweise

BOX_N, K, MULT_BOX, ATRMIN = 10, 0.1, 2.5, 0.06
KANDIDATEN = [0.8, 1.0, 1.5]


def einstiege(H, L, C, A, SP, lo, hi):
    out = []
    scan(H, L, C, A, SP, 1.0, lo, hi, MULT_BOX, box_n=BOX_N, k=K, atr_min=ATRMIN,
         exit_fn=lambda *a: 0.0,
         on_entry=lambda j, d, lvl, atr, komp: (
             out.append((j, d, lvl, atr)) if komp else None))
    return out


def r_werte(ein, H, L, C, SP, ende, mult):
    par = LIVE.with_(mult=mult)
    out = []
    for j, d, lvl, atr in ein:
        f = None
        for x in range(j, min(j + 13, ende)):
            if (H[x] >= lvl) if d > 0 else (L[x] <= lvl):
                f = x; break
        if f is None or f + 1 >= ende:
            out.append(None); continue
        r = simulate(lvl, d, atr, H, L, C, f + 1, par, timestop=True, use_tp=True)
        out.append(r - ((SP[f] if SP[f] > 0 else 0.0225) / atr))
    return out


def main():
    n = int(sys.argv[1]) if len(sys.argv) > 1 else 80000
    nb = int(sys.argv[2]) if len(sys.argv) > 2 else 8
    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]
    SP = [float(b["spread"]) * point for b in bars]
    A = atr_series(H, L, C)
    N = len(C); ende = N - LIVE.max_hold - 1

    print("=" * 88)
    print("  TRAIL 1,0 im WALK-FORWARD - {} M5 ({} Bars, {} Bloecke)".format(sym, N, nb))
    print("  gepaart: gleiche Einstiege, nur der Trail variiert")
    print("=" * 88)
    for m in KANDIDATEN:
        if m == LIVE.mult:
            continue
        print("\n  {} gegen LIVE {}  (Differenz je Trade, + = Kandidat besser)"
              .format(m, LIVE.mult))
        print("  " + "-" * 84)
        vz = []
        for b in range(nb):
            lo, hi = int(b * ende / nb), int((b + 1) * ende / nb)
            ein = einstiege(H, L, C, A, SP, lo, hi)
            a = r_werte(ein, H, L, C, SP, ende, LIVE.mult)
            k = r_werte(ein, H, L, C, SP, ende, m)
            paare = [(y, x) for x, y in zip(k, a) if x is not None and y is not None]
            if len(paare) < 10:
                print("    Block {}/{}  n={:<4} zu duenn".format(b+1, nb, len(paare)))
                continue
            basis = [p0 for p0, _ in paare]; kand = [p1 for _, p1 in paare]
            d = [p1 - p0 for p0, p1 in paare]
            mw = sum(d) / len(d)
            try:
                st = paarweise(basis, kand)
                ci = st.get("ci") if isinstance(st, dict) else None
            except Exception:
                ci = None
            m2 = ""
            if ci:
                m2 = " [{:+.3f} .. {:+.3f}]{}".format(
                    ci[0], ci[1], "" if ci[0]*ci[1] > 0 else " ~0")
            print("    Block {}/{}  n={:<4} Δ={:+.3f}{}".format(b+1, nb, len(d), mw, m2))
            vz.append(mw)
        if vz:
            print("    Vorzeichen: " + " ".join("+" if x > 0 else "-" for x in vz)
                  + "   ({} von {} fuer den Kandidaten)".format(
                      sum(1 for x in vz if x > 0), len(vz)))
    print("\n  " + "=" * 84)
    print("  LESART: kippt das Vorzeichen ueber die Bloecke, ist 'enger ist besser'")
    print("  eine Aussage ueber ZWEI Regime - keine ueber Stabilitaet.")


if __name__ == "__main__":
    main()
