"""EXIT-22 — DIAGNOSTICA DEL VALORE DELLO SL sulle fade (MR01/MR02/MR07).

Le fade live escono con TP/SL FISSI decisi all'entrata (al close[i]) + max_bars.
Lo SL e' sl0 = entry -/+ k*ATR (per costruzione della strategia). Questa policy
NON cambia TP ne' horizon: tocca SOLO lo SL per misurare quanto lo SL ATTUALE
aggiunge/toglie a ret/DD/Sharpe per sleeve. Tre regimi:

  mode = "none"     -> sl = None  (SL RIMOSSO: restano TP + max_bars). Il trade
                       puo' chiudere solo al TP o a scadenza horizon. Esposizione
                       al rischio di coda massima (nessun taglio della perdita).
  mode = "wide2x"   -> sl spostato a 2x la distanza entry->sl0 (stop piu' lasco):
                       sl = entry + 2*(sl0 - entry). Stoppa meno spesso.
  mode = "tight05x" -> sl spostato a 0.5x la distanza (stop piu' stretto):
                       sl = entry + 0.5*(sl0 - entry). Stoppa piu' spesso, ma
                       perde di meno per stop.

La geometria col segno e' automatica: per long sl0<entry, per short sl0>entry;
scalare (sl0-entry) preserva il lato corretto in entrambi i casi.

ANTI-LOOK-AHEAD: il livello sl(j) dipende SOLO da {entry, sl0, mode}, tutti noti
all'ENTRATA (close[i]). Costante per tutto il trade, identico al baseline tranne
il fattore di scala. Nessun dato del bar j o futuro entra. TP = tp0 invariato.
-> contratto rispettato per costruzione (livello statico, come il baseline).

INTERPRETAZIONE (diagnostica, non per forza deployabile):
  - se "none" >= base su ret E DD -> lo SL toglie valore (taglia winner che
    sarebbero rientrati: la fade e' mean-reversion, il movimento avverso e'
    spesso transitorio).
  - se "tight05x" peggiora molto -> lo SL e' gia' sul filo: stringerlo morde i
    rientri. se "wide2x" ~ "none" -> lo SL attuale e' quasi inerte (raramente
    toccato) e il rischio di coda e' contenuto da max_bars/TP.
  - DD e' la metrica chiave: lo SL serve a contenere la coda. Se "none" ha DD
    simile o piu' basso, lo SL non sta proteggendo nulla di utile.

GRID: mode in {none, wide2x, tight05x} (3 celle).
"""
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from exit_lab import ExitPolicy, evaluate  # noqa: E402


_SCALE = {"none": None, "wide2x": 2.0, "tight05x": 0.5}


class NoSl(ExitPolicy):
    name = "no_sl"

    def __init__(self, ctx, i, d, entry, tp0, sl0, mb, **params):
        super().__init__(ctx, i, d, entry, tp0, sl0, mb, **params)
        self.mode = str(params.get("mode", "none"))
        if self.mode not in _SCALE:
            raise ValueError(f"mode sconosciuto: {self.mode}")
        scale = _SCALE[self.mode]
        if scale is None:
            self.sl = None
        else:
            # sl = entry + scale*(sl0 - entry): preserva il lato per long/short.
            self.sl = entry + scale * (sl0 - entry)

    def levels(self, j: int):
        return self.tp0, self.sl, 1.0


GRID = [
    {"mode": "none"},
    {"mode": "wide2x"},
    {"mode": "tight05x"},
]


if __name__ == "__main__":
    evaluate(NoSl, GRID)
