16 agentes en líneaXAUUSD 4 552,4Sesión: London KillzonePróximo análisis: 04:12
Indicadores · Pine Script v5 · XAUUSD M15
● Avanzado · TradingView

Midas AI Legacy: el scoring OTE+ de la sala, en tu gráfico

Midas AI Legacy es la réplica visual de la lógica de análisis de la sala STX Desk sobre el oro (XAUUSD, M15): puntúa cada contexto con el método OTE+ (6 condiciones + bonus institucionales) y te muestra el grado, las killzones y los niveles, para que aprendas a leer una operación como lo hace el equipo.

Herramienta de estudio y alerta. Los patrones ICT (Order Block, FVG, doble techo) se aproximan en Pine; es un apoyo a la decisión, no una recomendación. No garantiza resultados.

Añadir en TradingViewVer el códigoDescargar .pine

¿Qué incluye?

  • Scoring OTE+ (6 condiciones). Bias H4+H1, killzone, barrido de liquidez, FVG con desplazamiento, zona OTE (0.618–0.79) y alineación de medias — cada uno suma al score.
  • Bonus institucionales (cap +4.0). Retest de Order Block, doble techo/suelo en H4 y triple confluencia (OTE + OB + FVG).
  • Grade A / B / C + nº de órdenes. El score se traduce en un grado y un número de órdenes sugerido, con umbral más exigente en la killzone de NY (SB2).
  • Killzones Silver Bullet. Sombreado de las 3 ventanas (London, NY AM, NY PM) en hora de París.
  • Niveles Fibonacci ABC + SL por ATR. Dibuja SL y TP1/TP2/TP3 (1.618 / 2.0 / 2.618) con buffers de broker.
  • Módulo Consolidation Breakout. Detecta cajas de consolidación planas y proyecta el measured move.
  • Guarda ATR-extrema (stand-aside). Marca «no operar» cuando la volatilidad diaria es excesiva.
  • Paneles HUD. Desglose del score condición por condición + panel de backtest histórico (ilustrativo).

Cómo se lee

El panel superior derecho muestra el score total y su desglose: cuanto más alto, más condiciones del método se alinean. El grado resume la calidad del contexto:

ScoreGradeLectura
≥ 9.5AConfluencia máxima del método.
≥ 9.0BContexto fuerte.
≥ umbralCContexto válido mínimo (8.2 general · 9.0 en NY AM).
< umbralSin contexto suficiente. Stand-aside.

El panel de backtest es un cálculo histórico ilustrativo dentro de TradingView; los resultados pasados no garantizan resultados futuros.

Cómo instalarlo en TradingView

  1. Abre el Pine Editor (parte inferior de TradingView).
  2. Pega el código de abajo (Pine Script v5) y reemplaza el contenido.
  3. «Add to chart» sobre un gráfico de XAUUSD en M15 (es su configuración nativa).
  4. Guarda con Ctrl/Cmd + S.

Código Pine Script v5

Midas AI — Legacy · Pine v5 · 495 líneas · XAUUSD M15.

Descargar .pine
//@version=5
// =============================================================================
//  ⚡ MIDAS AI — LEGACY COMPLET   ·   Machine de Guerre   ·   XAUUSD M15
// -----------------------------------------------------------------------------
//  Réplique VISUELLE complète de la stratégie LEGACY du daemon STX (config
//  machine de guerre) : scoring OTE+ 6 conditions + bonus institutionnels
//  (OB retest, double-top/bottom H4, triple confluence) cappés +4.0, garde
//  ATR-extrême (stand-aside), grade C/B/A + nb d'ordres, killzones SB1/SB2@9.0/
//  SB3-live, TP Fibonacci ABC, SL ATR-D, + module Consolidation Breakout + win-rate.
//
//  ⚠️  Aide à la décision / alertes. Les patterns ICT (OB, FVG, double-top) sont
//      APPROXIMÉS en Pine — le daemon Python reste la vérité d'exécution.
// =============================================================================
indicator("⚡ MIDAS AI — Legacy (Machine de Guerre, XAUUSD M15)", shorttitle="MIDAS LEGACY", overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count=500)

GOLD   = #E6B400
GOLDLT = #FFD23F
INK    = #0B0E11

// ───────────────────────── INPUTS — GÉNÉRAL ─────────────────────────────────
gGen     = "Général"
showSBbg = input.bool(true,  "Killzones Silver Bullet (fond)",         group=gGen)
showOTE  = input.bool(true,  "Module OTE+ Legacy",                     group=gGen)
showBO   = input.bool(true,  "Module Consolidation Breakout",          group=gGen)
showBT   = input.bool(true,  "Module backtest win-rate",               group=gGen)
showMark = input.bool(true,  "Watermark MIDAS AI",                     group=gGen)
tz       = input.string("Europe/Paris", "Fuseau des sessions",         group=gGen)

// ───────────────────────── INPUTS — OTE+ LEGACY ─────────────────────────────
gOTE   = "OTE+ Legacy (config machine de guerre)"
sb1    = input.session("1000-1100", "SB1 — London (Paris)",  group=gOTE)
sb2    = input.session("1500-1600", "SB2 — NY AM (Paris)",   group=gOTE)
sb3    = input.session("2000-2100", "SB3 — NY PM (Paris, LIVE)", group=gOTE)
htfTF  = input.timeframe("240", "TF biais HTF (H4)",          group=gOTE)
htf2TF = input.timeframe("60",  "TF confirmation (H1)",       group=gOTE)
scoreMin = input.float(8.2,  "Score min — général/SB1/SB3",   group=gOTE, step=0.1)
sb2Min   = input.float(9.0,  "Score min — SB2 (durci)",       group=gOTE, step=0.1)
atrMaxD  = input.float(100.0,"Garde ATR-extrême : stand-aside si ATR_D >", group=gOTE, step=5.0)
slPctD = input.float(0.25, "SL = % de l'ATR Daily",           group=gOTE, step=0.05)
slFloor= input.float(8.0,  "SL plancher ($)",                 group=gOTE)
slCeil = input.float(30.0, "SL plafond ($)",                  group=gOTE)
tpBuf1 = input.float(3.0,  "Buffer TP1 ($)",                  group=gOTE)
tpBuf2 = input.float(3.0,  "Buffer TP2 ($)",                  group=gOTE)
tpBuf3 = input.float(5.0,  "Buffer TP3 ($)",                  group=gOTE)

// ───────────────────────── INPUTS — BREAKOUT (= Python) ─────────────────────
gBO       = "Consolidation Breakout"
BOX_BARS  = input.int(24,   "BOX_BARS",       group=gBO)
BIAS_BARS = input.int(48,   "BIAS_BARS",      group=gBO)
FLAT_ATR  = input.float(0.35,"FLAT_DRIFT_ATR",group=gBO, step=0.01)
EQ_TOL    = input.float(0.10,"EQ_TOL_ATR",    group=gBO, step=0.01)
BOX_MIN   = input.float(0.20,"BOX_MIN_ATR",   group=gBO, step=0.01)
BOX_MAX   = input.float(0.50,"BOX_MAX_ATR",   group=gBO, step=0.01)
BIAS_ATR  = input.float(0.40,"BIAS_DRIFT_ATR",group=gBO, step=0.01)
BUF_ATR   = input.float(0.02,"BREAKOUT_BUFFER_ATR", group=gBO, step=0.01)
MM        = input.float(1.5, "MEASURED_MOVE", group=gBO, step=0.1)
FWD       = input.int(30,   "Projection lignes (barres)", group=gBO)
btFwd     = input.int(60,   "Backtest : fenêtre résolution", group=gBO, minval=5)
lot       = input.float(0.05, "Lot (pour Day P&L $)", group=gBO, step=0.01)

// ───────────────────────── DONNÉES DE BASE ──────────────────────────────────
atrD  = request.security(syminfo.tickerid, "D", ta.atr(14), lookahead=barmerge.lookahead_off)
atrM  = ta.atr(14)

inSB1 = not na(time(timeframe.period, sb1, tz))
inSB2 = not na(time(timeframe.period, sb2, tz))
inSB3 = not na(time(timeframe.period, sb3, tz))
inSB  = inSB1 or inSB2 or inSB3
bgcolor(showSBbg and inSB ? color.new(GOLD, 90) : na, title="Killzone SB")

// garde ATR-extrême (legacy : stand-aside quand ATR_D > seuil)
standAside = atrD > atrMaxD
bgcolor(standAside ? color.new(color.red, 85) : na, title="STAND ASIDE (ATR extrême)")

// État backtest
var tDir     = array.new_int()
var tEntry   = array.new_float()
var tSL      = array.new_float()
var tTP      = array.new_float()
var tMod     = array.new_int()
var tExp     = array.new_int()
var tWinAmt  = array.new_float()
var tLossAmt = array.new_float()
var int   boW  = 0
var int   boL  = 0
var int   oteW = 0
var int   oteL = 0
var float boGW  = 0.0
var float boGL  = 0.0
var float oteGW = 0.0
var float oteGL = 0.0

// Daily stats (simulated from the indicator's signals — resets each calendar day)
var int   dTrades = 0
var int   dWins   = 0
var int   dLosses = 0
var float dPnl    = 0.0
if ta.change(time("D")) != 0
    dTrades := 0
    dWins   := 0
    dLosses := 0
    dPnl    := 0.0

// =============================================================================
//  MODULE 1 — CONSOLIDATION BREAKOUT (réplique breakout_shadow.py)
// =============================================================================
f_detectBox(atrd) =>
    n = BOX_BARS
    sumY = 0.0
    for i = 0 to n - 1
        sumY += close[1 + i]
    yMean = sumY / n
    xMean = (n - 1) / 2.0
    num = 0.0
    den = 0.0
    for i = 0 to n - 1
        num += (i - xMean) * (close[1 + i] - yMean)
        den += (i - xMean) * (i - xMean)
    slope = den == 0.0 ? 0.0 : num / den
    flat  = math.abs(slope * (n - 1)) < FLAT_ATR * atrd
    valid = false
    sup = float(na)
    res = float(na)
    if flat
        tol = EQ_TOL * atrd
        hP = array.new_float()
        lP = array.new_float()
        for o = 2 to n - 1
            hc = high[o]
            hp = high[o - 1]
            hn = high[o + 1]
            if hc >= hp and hc >= hn and (hc > hp or hc > hn)
                array.push(hP, hc)
            lc = low[o]
            lp = low[o - 1]
            ln = low[o + 1]
            if lc <= lp and lc <= ln and (lc < lp or lc < ln)
                array.push(lP, lc)
        bestCntH = 0
        lvlH = float(na)
        szH = array.size(hP)
        if szH > 0
            for a = 0 to szH - 1
                base = array.get(hP, a)
                cnt = 0
                sm = 0.0
                for b = 0 to szH - 1
                    v = array.get(hP, b)
                    if math.abs(v - base) <= tol
                        cnt += 1
                        sm += v
                if cnt > bestCntH
                    bestCntH := cnt
                    lvlH := sm / cnt
        bestCntL = 0
        lvlL = float(na)
        szL = array.size(lP)
        if szL > 0
            for a = 0 to szL - 1
                base = array.get(lP, a)
                cnt = 0
                sm = 0.0
                for b = 0 to szL - 1
                    v = array.get(lP, b)
                    if math.abs(v - base) <= tol
                        cnt += 1
                        sm += v
                if cnt > bestCntL
                    bestCntL := cnt
                    lvlL := sm / cnt
        if bestCntH >= 2 and bestCntL >= 2
            h = lvlH - lvlL
            if h >= BOX_MIN * atrd and h <= BOX_MAX * atrd
                valid := true
                res := lvlH
                sup := lvlL
    [valid, sup, res]

boxOK = false
boxSup = float(na)
boxRes = float(na)
if showBO and atrD > 0
    [v, s, r] = f_detectBox(atrD)
    boxOK := v
    boxSup := s
    boxRes := r

biasDrift = close[BOX_BARS + 1] - close[BOX_BARS + BIAS_BARS]
biasBuy   = biasDrift >  BIAS_ATR * atrD
biasSell  = biasDrift < -BIAS_ATR * atrD
prevInside = boxOK and close[1] >= boxSup and close[1] <= boxRes
buf = BUF_ATR * atrD
boBuy  = boxOK and prevInside and biasBuy  and close > boxRes + buf and not standAside
boSell = boxOK and prevInside and biasSell and close < boxSup - buf and not standAside

if boBuy
    h = boxRes - boxSup
    box.new(bar_index - BOX_BARS, boxRes, bar_index - 1, boxSup, border_color=color.new(GOLD, 30), bgcolor=color.new(GOLD, 93))
    line.new(bar_index, boxSup, bar_index + FWD, boxSup, color=color.new(color.red, 0), width=2)
    line.new(bar_index, close + MM*h, bar_index + FWD, close + MM*h, color=color.new(color.green, 0), width=2)
    label.new(bar_index + FWD, boxSup, "BO SL " + str.tostring(boxSup, format.mintick), style=label.style_label_left, color=color.new(color.red, 20), textcolor=color.white, size=size.tiny)
    label.new(bar_index + FWD, close + MM*h, "BO TP " + str.tostring(close + MM*h, format.mintick), style=label.style_label_left, color=color.new(color.green, 0), textcolor=color.white, size=size.tiny)
if boSell
    h = boxRes - boxSup
    box.new(bar_index - BOX_BARS, boxRes, bar_index - 1, boxSup, border_color=color.new(GOLD, 30), bgcolor=color.new(GOLD, 93))
    line.new(bar_index, boxRes, bar_index + FWD, boxRes, color=color.new(color.red, 0), width=2)
    line.new(bar_index, close - MM*h, bar_index + FWD, close - MM*h, color=color.new(color.green, 0), width=2)
    label.new(bar_index + FWD, boxRes, "BO SL " + str.tostring(boxRes, format.mintick), style=label.style_label_left, color=color.new(color.red, 20), textcolor=color.white, size=size.tiny)
    label.new(bar_index + FWD, close - MM*h, "BO TP " + str.tostring(close - MM*h, format.mintick), style=label.style_label_left, color=color.new(color.green, 0), textcolor=color.white, size=size.tiny)

plotshape(showBO and boBuy,  title="Breakout BUY",  style=shape.triangleup,   location=location.belowbar, color=color.lime, size=size.small)
plotshape(showBO and boSell, title="Breakout SELL", style=shape.triangledown, location=location.abovebar, color=color.red,  size=size.small)

// =============================================================================
//  MODULE 2 — OTE+ LEGACY  (6 conditions + bonus institutionnels + grade)
// =============================================================================
// Biais HTF : H4 + H1 (legacy = alignement H4/H1)
h4d = request.security(syminfo.tickerid, htfTF,  ta.ema(close, 8) - ta.ema(close, 21), lookahead=barmerge.lookahead_off)
h1d = request.security(syminfo.tickerid, htf2TF, ta.ema(close, 8) - ta.ema(close, 21), lookahead=barmerge.lookahead_off)
htfBull = h4d > 0 and h1d > 0
htfBear = h4d < 0 and h1d < 0
dir = htfBull ? 1 : htfBear ? -1 : 0

// ── 6 conditions ───────────────────────────────────────────────────────────
fvgBull = low > high[2]
fvgBear = high < low[2]
disp = (high - low) > 1.5 * atrM
swH = ta.highest(high, 20)[1]
swL = ta.lowest(low, 20)[1]
sweepBull = low  < swL and close > swL
sweepBear = high > swH and close < swH
phPrice = ta.valuewhen(not na(ta.pivothigh(5, 5)), high[5], 0)
plPrice = ta.valuewhen(not na(ta.pivotlow(5, 5)),  low[5], 0)
legA = math.abs(phPrice - plPrice)
inOTEbuy  = dir ==  1 and close <= phPrice - 0.618*legA and close >= phPrice - 0.79*legA
inOTEsell = dir == -1 and close >= plPrice + 0.618*legA and close <= plPrice + 0.79*legA
inOTE = inOTEbuy or inOTEsell
emaFast = ta.ema(close, 8)
emaSlow = ta.ema(close, 21)
taOK    = (dir == 1 and emaFast > emaSlow) or (dir == -1 and emaFast < emaSlow)
sweepOK = (dir == 1 and sweepBull) or (dir == -1 and sweepBear)
fvgOK   = disp and ((dir == 1 and fvgBull) or (dir == -1 and fvgBear))

sHTF   = dir != 0 ? 4.0 : 0.0
sSB    = inSB     ? 2.0 : 0.0
sSweep = sweepOK  ? 2.0 : 0.0
sFVG   = fvgOK    ? 1.5 : 0.0
sOTE   = inOTE    ? 1.5 : 0.0
sTA    = taOK     ? 0.5 : 0.0
core   = sHTF + sSB + sSweep + sFVG + sOTE + sTA

// ── BONUS INSTITUTIONNELS (legacy, cappés +4.0) ─────────────────────────────
// OB retest : zone du dernier order block (bougie avant displacement) re-testée
var float obBullT = na
var float obBullB = na
var float obBearT = na
var float obBearB = na
if close > open and disp
    obBullT := high[1]
    obBullB := low[1]
if close < open and disp
    obBearT := high[1]
    obBearB := low[1]
obBullRetest = not na(obBullB) and dir ==  1 and low  <= obBullT and low  >= obBullB
obBearRetest = not na(obBearT) and dir == -1 and high >= obBearB and high <= obBearT
obRetest = obBullRetest or obBearRetest
sOB = obRetest ? 1.5 : 0.0

// Double top / bottom H4 (vendre 2e sommet / acheter 2e bas)
h4ph = request.security(syminfo.tickerid, htfTF, ta.pivothigh(3, 3), lookahead=barmerge.lookahead_off)
h4pl = request.security(syminfo.tickerid, htfTF, ta.pivotlow(3, 3),  lookahead=barmerge.lookahead_off)
var float ph1 = na
var float ph2 = na
var float pl1 = na
var float pl2 = na
if not na(h4ph)
    ph2 := ph1
    ph1 := h4ph
if not na(h4pl)
    pl2 := pl1
    pl1 := h4pl
dblTop = not na(ph1) and not na(ph2) and math.abs(ph1 - ph2) <= 0.30*atrD and dir == -1
dblBot = not na(pl1) and not na(pl2) and math.abs(pl1 - pl2) <= 0.30*atrD and dir ==  1
sDTB = (dblTop or dblBot) ? 2.0 : 0.0

// Triple confluence OTE + OB + FVG
sTriple = (inOTE and obRetest and fvgOK) ? 2.5 : 0.0

bonusRaw = sOB + sDTB + sTriple
bonus = math.min(bonusRaw, 4.0)
score = core + bonus

// ── Grade + nb d'ordres + seuil par fenêtre ─────────────────────────────────
effMin = inSB2 ? sb2Min : scoreMin
grade  = score >= 9.5 ? "A" : score >= 9.0 ? "B" : score >= effMin ? "C" : "—"
orders = (grade == "A" or grade == "B") ? 3 : grade == "C" ? 1 : 0

isBuyO = dir == 1
oteSignal = showOTE and inSB and dir != 0 and score >= effMin and not standAside

// ── Niveaux (calculés globalement) ──────────────────────────────────────────
slDistO = math.max(slFloor, math.min(slCeil, slPctD * atrD))
Aote    = legA > 0 ? legA : slDistO * 2.0
oteSL   = isBuyO ? close - slDistO : close + slDistO
oteTP1  = (isBuyO ? close + 1.618*Aote : close - 1.618*Aote) - (isBuyO ? tpBuf1 : -tpBuf1)
oteTP2  = (isBuyO ? close + 2.0  *Aote : close - 2.0  *Aote) - (isBuyO ? tpBuf2 : -tpBuf2)
oteTP3  = (isBuyO ? close + 2.618*Aote : close - 2.618*Aote) - (isBuyO ? tpBuf3 : -tpBuf3)

f_drawOTE(isBuy, sl, tp1, tp2, tp3, sc, gr, ords) =>
    line.new(bar_index, sl,  bar_index + FWD, sl,  color=color.new(color.red, 0),   width=2)
    line.new(bar_index, tp1, bar_index + FWD, tp1, color=color.new(color.green, 30))
    line.new(bar_index, tp2, bar_index + FWD, tp2, color=color.new(color.green, 15))
    line.new(bar_index, tp3, bar_index + FWD, tp3, color=color.new(color.green, 0))
    label.new(bar_index + FWD, sl,  "SL "  + str.tostring(sl,  format.mintick), style=label.style_label_left, color=color.new(color.red, 20),   textcolor=color.white, size=size.tiny)
    label.new(bar_index + FWD, tp1, "TP1 " + str.tostring(tp1, format.mintick), style=label.style_label_left, color=color.new(color.green, 30), textcolor=color.white, size=size.tiny)
    label.new(bar_index + FWD, tp2, "TP2 " + str.tostring(tp2, format.mintick), style=label.style_label_left, color=color.new(color.green, 15), textcolor=color.white, size=size.tiny)
    label.new(bar_index + FWD, tp3, "TP3 " + str.tostring(tp3, format.mintick), style=label.style_label_left, color=color.new(color.green, 0),  textcolor=color.white, size=size.tiny)
    label.new(bar_index, close, (isBuy ? "▲ " : "▼ ") + "G" + gr + " " + str.tostring(ords) + "ord  " + str.tostring(sc, "#.0"), style=isBuy ? label.style_label_up : label.style_label_down, color=isBuy ? color.new(color.teal, 10) : color.new(color.maroon, 10), textcolor=color.white, size=size.small)

var float lastBar = na
newOTE = oteSignal and (na(lastBar) or bar_index - lastBar > 3)
if newOTE
    f_drawOTE(isBuyO, oteSL, oteTP1, oteTP2, oteTP3, score, grade, orders)
    lastBar := bar_index

plotshape(showOTE and newOTE and isBuyO,      title="MIDAS BUY",  style=shape.diamond, location=location.belowbar, color=GOLD, size=size.tiny)
plotshape(showOTE and newOTE and dir == -1,   title="MIDAS SELL", style=shape.diamond, location=location.abovebar, color=GOLD, size=size.tiny)

// =============================================================================
//  MODULE 3 — BACKTEST win-rate (TP-avant-SL, SL d'abord sur égalité)
// =============================================================================
btTPo = oteTP1
if showBT and array.size(tDir) > 0
    i = array.size(tDir) - 1
    while i >= 0
        d = array.get(tDir, i)
        s = array.get(tSL, i)
        tp = array.get(tTP, i)
        md = array.get(tMod, i)
        exp = array.get(tExp, i)
        resolved = false
        win = false
        if d == 1
            if low <= s
                resolved := true
            else if high >= tp
                resolved := true
                win := true
        else
            if high >= s
                resolved := true
            else if low <= tp
                resolved := true
                win := true
        if not resolved and bar_index >= exp
            resolved := true
        if resolved
            wa = array.get(tWinAmt, i)
            la = array.get(tLossAmt, i)
            if md == 0
                if win
                    boW += 1
                    boGW += wa
                else
                    boL += 1
                    boGL += la
            else
                if win
                    oteW += 1
                    oteGW += wa
                else
                    oteL += 1
                    oteGL += la
            dTrades += 1
            if win
                dWins += 1
                dPnl += wa * lot * 100.0
            else
                dLosses += 1
                dPnl -= la * lot * 100.0
            array.remove(tDir, i)
            array.remove(tEntry, i)
            array.remove(tSL, i)
            array.remove(tTP, i)
            array.remove(tMod, i)
            array.remove(tExp, i)
            array.remove(tWinAmt, i)
            array.remove(tLossAmt, i)
        i -= 1

if showBT and boBuy
    h = boxRes - boxSup
    array.push(tDir, 1)
    array.push(tEntry, close)
    array.push(tSL, boxSup)
    array.push(tTP, close + MM*h)
    array.push(tMod, 0)
    array.push(tExp, bar_index + btFwd)
    array.push(tWinAmt, MM*h)
    array.push(tLossAmt, math.abs(close - boxSup))
if showBT and boSell
    h = boxRes - boxSup
    array.push(tDir, -1)
    array.push(tEntry, close)
    array.push(tSL, boxRes)
    array.push(tTP, close - MM*h)
    array.push(tMod, 0)
    array.push(tExp, bar_index + btFwd)
    array.push(tWinAmt, MM*h)
    array.push(tLossAmt, math.abs(boxRes - close))
if showBT and newOTE
    array.push(tDir, isBuyO ? 1 : -1)
    array.push(tEntry, close)
    array.push(tSL, oteSL)
    array.push(tTP, btTPo)
    array.push(tMod, 1)
    array.push(tExp, bar_index + btFwd)
    array.push(tWinAmt, math.abs(btTPo - close))
    array.push(tLossAmt, math.abs(close - oteSL))

f_wr(w, n) => n > 0 ? str.tostring(100.0*w/n, "#.0") + "%" : "—"
f_pf(gw, gl) => gl > 0 ? str.tostring(gw/gl, "#.00") : (gw > 0 ? "∞" : "—")

// =============================================================================
//  PANNEAUX
// =============================================================================
var table tbl = table.new(position.top_right, 2, 11, border_width=1, frame_color=color.new(GOLD, 40), frame_width=1)
if barstate.islast and showOTE
    table.cell(tbl, 0, 0, "⚡ MIDAS LEGACY", text_color=INK, bgcolor=GOLD)
    table.cell(tbl, 1, 0, standAside ? "STAND ASIDE" : (str.tostring(score, "#.0") + " G" + grade), text_color=standAside ? color.red : (score >= effMin ? GOLDLT : color.silver), bgcolor=INK)
    table.cell(tbl, 0, 1, "HTF H4+H1", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 1, str.tostring(sHTF,"#.0"), text_color=sHTF>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 2, "SB", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 2, str.tostring(sSB,"#.0"), text_color=sSB>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 3, "Sweep", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 3, str.tostring(sSweep,"#.0"), text_color=sSweep>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 4, "FVG+Disp", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 4, str.tostring(sFVG,"#.0"), text_color=sFVG>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 5, "OTE", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 5, str.tostring(sOTE,"#.0"), text_color=sOTE>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 6, "TA", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 6, str.tostring(sTA,"#.0"), text_color=sTA>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 7, "OB retest", text_color=color.aqua, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 7, str.tostring(sOB,"#.0"), text_color=sOB>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 8, "DblTop/Bot H4", text_color=color.aqua, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 8, str.tostring(sDTB,"#.0"), text_color=sDTB>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 9, "Triple/Bonus", text_color=color.aqua, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 9, str.tostring(bonus,"#.0")+" (cap4)", text_color=bonus>0?color.lime:color.gray, bgcolor=color.new(INK,15))
    table.cell(tbl, 0, 10, "Seuil/Ordres", text_color=color.silver, bgcolor=color.new(INK,15))
    table.cell(tbl, 1, 10, str.tostring(effMin,"#.0")+" / "+str.tostring(orders), text_color=GOLDLT, bgcolor=color.new(INK,15))

var table bt = table.new(position.bottom_right, 4, 4, border_width=1, frame_color=color.new(GOLD,40), frame_width=1)
if barstate.islast and showBT
    boN = boW + boL
    oteN = oteW + oteL
    table.cell(bt,0,0,"MIDAS Backtest",text_color=INK,bgcolor=GOLD)
    table.cell(bt,1,0,"Trd",text_color=INK,bgcolor=GOLD)
    table.cell(bt,2,0,"Win%",text_color=INK,bgcolor=GOLD)
    table.cell(bt,3,0,"PF",text_color=INK,bgcolor=GOLD)
    table.cell(bt,0,1,"Breakout",text_color=color.silver,bgcolor=color.new(INK,15))
    table.cell(bt,1,1,str.tostring(boN),text_color=color.silver,bgcolor=color.new(INK,15))
    table.cell(bt,2,1,f_wr(boW,boN),text_color=color.lime,bgcolor=color.new(INK,15))
    table.cell(bt,3,1,f_pf(boGW,boGL),text_color=GOLDLT,bgcolor=color.new(INK,15))
    table.cell(bt,0,2,"OTE+ Legacy",text_color=color.silver,bgcolor=color.new(INK,15))
    table.cell(bt,1,2,str.tostring(oteN),text_color=color.silver,bgcolor=color.new(INK,15))
    table.cell(bt,2,2,f_wr(oteW,oteN),text_color=color.lime,bgcolor=color.new(INK,15))
    table.cell(bt,3,2,f_pf(oteGW,oteGL),text_color=GOLDLT,bgcolor=color.new(INK,15))
    table.cell(bt,0,3,"TOTAL",text_color=GOLDLT,bgcolor=color.new(INK,5))
    table.cell(bt,1,3,str.tostring(boN+oteN),text_color=GOLDLT,bgcolor=color.new(INK,5))
    table.cell(bt,2,3,f_wr(boW+oteW,boN+oteN),text_color=GOLDLT,bgcolor=color.new(INK,5))
    table.cell(bt,3,3,f_pf(boGW+oteGW,boGL+oteGL),text_color=GOLDLT,bgcolor=color.new(INK,5))

var table wm = table.new(position.bottom_center, 1, 1)
if barstate.islast and showMark
    table.cell(wm, 0, 0, "⚡ MIDAS AI — Machine de Guerre (Legacy)", text_color=color.new(GOLD, 25), bgcolor=color.new(INK, 80), text_size=size.large)

// ── DAILY STATS box (English) — today's simulated trades from the signals ───
var table dt = table.new(position.top_left, 2, 5, border_width=1, frame_color=color.new(GOLD, 40), frame_width=1)
if barstate.islast
    table.cell(dt, 0, 0, "DAILY STATS", text_color=INK, bgcolor=GOLD)
    table.cell(dt, 1, 0, "(sim)", text_color=INK, bgcolor=GOLD)
    table.cell(dt, 0, 1, "Trades", text_color=color.silver, bgcolor=color.new(INK, 15))
    table.cell(dt, 1, 1, str.tostring(dTrades), text_color=color.white, bgcolor=color.new(INK, 15))
    table.cell(dt, 0, 2, "Wins", text_color=color.silver, bgcolor=color.new(INK, 15))
    table.cell(dt, 1, 2, str.tostring(dWins), text_color=color.lime, bgcolor=color.new(INK, 15))
    table.cell(dt, 0, 3, "Losses", text_color=color.silver, bgcolor=color.new(INK, 15))
    table.cell(dt, 1, 3, str.tostring(dLosses), text_color=color.red, bgcolor=color.new(INK, 15))
    table.cell(dt, 0, 4, "Day P&L", text_color=color.silver, bgcolor=color.new(INK, 10))
    table.cell(dt, 1, 4, (dPnl >= 0 ? "+$" : "-$") + str.tostring(math.abs(dPnl), "#.0"), text_color=dPnl >= 0 ? color.lime : color.red, bgcolor=color.new(INK, 10))

// ───────────────────────── ALERTES ─────────────────────────────────────────
alertcondition(boBuy,  title="MIDAS Breakout BUY",  message="⚡ MIDAS Breakout BUY XAUUSD M15")
alertcondition(boSell, title="MIDAS Breakout SELL", message="⚡ MIDAS Breakout SELL XAUUSD M15")
alertcondition(newOTE, title="MIDAS OTE+ Legacy signal", message="⚡ MIDAS OTE+ Legacy signal XAUUSD M15 (grade + score dans killzone)")

Preguntas frecuentes

¿Para qué instrumento y temporalidad?

Está calibrado para XAUUSD en M15 (su configuración «machine de guerre»). Puede cargarse en otros activos, pero los umbrales están pensados para el oro intradía.

¿Es lo mismo que STX Desk?

Es la réplica visual de la lógica de análisis. El motor real (daemon) ejecuta con datos y reglas adicionales; este indicador sirve para estudiar y visualizar el método.

¿Es gratis?

Sí, el código está disponible. Necesitas una cuenta de TradingView (el plan gratuito es suficiente para usarlo).

¿Da señales de compra/venta?

Marca contextos y niveles según el método, con alertas opcionales. Es un apoyo a la decisión educativo, no una recomendación de inversión.

Contenido exclusivamente educativo; no constituye asesoramiento financiero ni garantiza resultados. El trading implica riesgo de pérdida de capital.

¿Quieres entender el método detrás del score? Aprende la metodología ICT / Smart Money paso a paso en la Escuela de Trading gratuita, o descubre la sala STX Desk.