Indicator · Pine Script v5 · On the chart

Jigsa God Mode Pro

by jigsabersisa

This indicator overlays a 50 and 200 EMA trend filter, RSI confirmation and pivot-based zones on the price chart, and prints buy and sell signals with projected entry, ATR-based stop loss and risk to reward take profit lines.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code2,001
Settings40inputs
LicenceGPL-3.0
Last update6 months ago4 Apr 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

2,001 lines of Pine Script v5 from strategy.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

strategy.pine
//@version=5
indicator("Jigsa GOD MODE PRO", overlay=true, max_labels_count=200, max_lines_count=500, max_boxes_count=200)

// =====================================================
// INPUTS (ALL 100% ORIGINAL)
// =====================================================

// ================= TREND SETTINGS =================
groupTrend = "Trend Settings"

fastEmaLen = input.int(50, "Fast EMA", minval=1, group=groupTrend)
slowEmaLen = input.int(200, "Slow EMA", minval=1, group=groupTrend)
rsiLen     = input.int(14, "RSI Length", minval=1, group=groupTrend)

// ================= STRUCTURE SETTINGS =================
groupStructure = "Structure / Zones"

pivotLen        = input.int(8, "Pivot Length", minval=2, group=groupStructure)
zoneAtrMult     = input.float(0.50, "Zone Height ATR Multiplier", minval=0.1, step=0.1, group=groupStructure)
maxZoneAgeBars  = input.int(250, "Max Zone Age (bars)", minval=20, group=groupStructure)
eqTolerancePips = input.float(0.0008, "Equal High/Low Tolerance", step=0.0001, group=groupStructure)

// ================= SIGNAL SETTINGS =================
groupSignals = "Signal Settings"

rsiBullMin     = input.int(52, "Bullish RSI Confirm >=", minval=1, maxval=100, group=groupSignals)
rsiBearMax     = input.int(48, "Bearish RSI Confirm <=", minval=1, maxval=100, group=groupSignals)
riskReward     = input.float(2.0, "Risk:Reward", minval=0.5, step=0.1, group=groupSignals)
slAtrMult      = input.float(1.2, "Stop ATR Multiplier", minval=0.2, step=0.1, group=groupSignals)
retestLookback = input.int(8, "Retest Lookback Bars", minval=1, group=groupSignals)

// ================= DISPLAY SETTINGS =================
groupDisplay = "Display"
projectionBars = input.int(18, "Projection Bars", minval=6, maxval=100, group=groupDisplay)
liveMode        = input.bool(true, "LIVE MODE (Only current signal)", group=groupDisplay)
showEMAs        = input.bool(true, "Show EMAs", group=groupDisplay)
showPivotLevels = input.bool(false, "Show Pivot S/R", group=groupDisplay)
showLiquidity   = input.bool(false, "Show Liquidity Sweeps", group=groupDisplay)
showOrderBlocks = input.bool(false, "Show Order Blocks", group=groupDisplay)
showSignals     = input.bool(true, "Show Buy/Sell Signals", group=groupDisplay)
showTargets     = input.bool(true, "Show Entry / SL / TP", group=groupDisplay)
showDashboard   = input.bool(true, "Show Dashboard", group=groupDisplay)

// =====================================================
// NEW INSTITUTIONAL INPUTS (ADDITIONAL)
// =====================================================
groupSMC = "SMC / Institutional Features"

showFVG      = input.bool(false, "Show Fair Value Gaps (FVG)", group=groupSMC)
showCHoCH    = input.bool(false, "Show Change of Character (CHoCH)", group=groupSMC)
showSessions = input.bool(false, "Highlight Killzones (London/NY)", group=groupSMC)

// =====================================================
// NEW PATTERN INPUTS (ADDITIONAL)
// =====================================================
groupPatterns = "Pattern Detection"

showDescendingTriangles = input.bool(false, "Show Descending Triangles", group=groupPatterns)
showAscendingTriangles  = input.bool(false, "Show Ascending Triangles", group=groupPatterns)
showDoublePatterns      = input.bool(false, "Show Double Top / Bottom", group=groupPatterns)
showFlags               = input.bool(false, "Show Bull / Bear Flags", group=groupPatterns)
showHS                  = input.bool(false, "Show Head & Shoulders", group=groupPatterns)

// =====================================================
// LIQUIDITY TRAP SETTINGS
// =====================================================
groupLiquidity = "Liquidity Engine"
groupSilver = "Silver Bullet"
useSilverBullet = input.bool(true, "Enable Silver Bullet Filter", group=groupSilver)
groupPro = "Pro Execution"

maxTradesPerSession = input.int(3, "Max Trades Per Session", minval=1, maxval=10, group=groupPro)
setupExpiryBars     = input.int(12, "Setup Expiry Bars", minval=1, maxval=100, group=groupPro)
freshRetestBars     = input.int(2, "Fresh Retest Bars", minval=1, maxval=10, group=groupPro)
minRiskATR          = input.float(0.5, "Min Risk in ATR", minval=0.1, step=0.1, group=groupPro)
maxRiskATR          = input.float(3.0, "Max Risk in ATR", minval=0.5, step=0.1, group=groupPro)

useManualNewsBlock  = input.bool(false, "Use Manual NY News Block", group=groupPro)
newsBlock1          = input.session("0830-0845", "News Block 1 (NY)", group=groupPro)
newsBlock2          = input.session("0955-1010", "News Block 2 (NY)", group=groupPro)
showLiquidityTraps = input.bool(true, "Detect Liquidity Traps", group=groupLiquidity)
liqLookback = input.int(10, "Liquidity Lookback", minval=2, group=groupLiquidity)
liqTolerance = input.float(0.0005, "Liquidity Tolerance", step=0.0001, group=groupLiquidity)

// =====================================================
// CORE CALCS
// =====================================================
emaFast = ta.ema(close, fastEmaLen)
emaSlow = ta.ema(close, slowEmaLen)
rsiVal  = ta.rsi(close, rsiLen)
atrVal  = ta.atr(14)

// =====================================================
// INSTITUTIONAL VWAP FILTER
// =====================================================
vwapValue = ta.vwap(close)

institutionalBull = close > vwapValue
institutionalBear = close < vwapValue

// =====================================================
// ADX MARKET REGIME FILTER
// =====================================================
[diplus, diminus, adxVal] = ta.dmi(14, 14)

strongTrend = adxVal > 25
weakMarket  = adxVal < 18

// =====================================================
// VOLUME INTELLIGENCE
// =====================================================
volMA = ta.sma(volume, 20)

volumeSpike   = volume > volMA * 1.5
trendStrength = atrVal > 0 ? math.abs(emaFast - emaSlow) / atrVal : 0
trendFilter   = trendStrength > 0.7

trendPower =
     trendStrength > 3 ? "EXPLOSIVE" :
     trendStrength > 2 ? "STRONG" :
     trendStrength > 1 ? "MODERATE" :
     "WEAK"

bullTrend = close > emaSlow and emaFast > emaSlow
bearTrend = close < emaSlow and emaFast < emaSlow
sideways  = not bullTrend and not bearTrend

// =====================================================
// MARKET PHASE DETECTION (INSTITUTIONAL)
// =====================================================
phase = "NEUTRAL"

if bullTrend and close > emaFast
    phase := "EXPANSION"
else if bullTrend and close < emaFast
    phase := "PULLBACK"
else if bearTrend and close < emaFast
    phase := "DISTRIBUTION"
else if sideways
    phase := "ACCUMULATION"

trendText = bullTrend ? "BULLISH" : bearTrend ? "BEARISH" : "RANGE"

// =====================================================
// HIGHER TIMEFRAME TREND FILTER (AI UPGRADE)
// =====================================================
htf_tf = input.timeframe("", "HTF Trend Timeframe")

htfClose = request.security(syminfo.tickerid, htf_tf, close[1], lookahead=barmerge.lookahead_on)
htfEMA   = request.security(syminfo.tickerid, htf_tf, ta.ema(close, slowEmaLen)[1], lookahead=barmerge.lookahead_on)

htfBull = htfClose > htfEMA
htfBear = htfClose < htfEMA

// =====================================================
// PIVOTS / STRUCTURE (MTF STABLE)
// =====================================================
structureTF = input.timeframe("", "Structure Timeframe")

ph = ta.pivothigh(high, pivotLen, pivotLen)
pl = ta.pivotlow(low, pivotLen, pivotLen)

var float prevPivotHigh = na
var float prevPivotLow = na
var int prevPivotHighBar = na
var int prevPivotLowBar = na

var float lastPivotHigh = na
var float lastPivotLow = na
var int lastPivotHighBar = na
var int lastPivotLowBar = na

if not na(ph)
    prevPivotHigh := lastPivotHigh
    prevPivotHighBar := lastPivotHighBar
    lastPivotHigh := ph
    lastPivotHighBar := bar_index - pivotLen

if not na(pl)
    prevPivotLow := lastPivotLow
    prevPivotLowBar := lastPivotLowBar
    lastPivotLow := pl
    lastPivotLowBar := bar_index - pivotLen

var line pivotHighLine = na
var line pivotLowLine = na

if showPivotLevels
    if not na(ph)
        if not na(pivotHighLine)
            line.delete(pivotHighLine)
        pivotHighLine := line.new(bar_index - pivotLen, ph, bar_index + 10, ph, extend=extend.none, color=color.new(color.red, 70), width=1)

    if not na(pl)
        if not na(pivotLowLine)
            line.delete(pivotLowLine)
        pivotLowLine := line.new(bar_index - pivotLen, pl, bar_index + 10, pl, extend=extend.none, color=color.new(color.green, 70), width=1)

// =====================================================
// LIQUIDITY POOL DETECTION
// =====================================================
recentHigh = ta.highest(high[1], liqLookback)
recentLow  = ta.lowest(low[1], liqLookback)

liquidityAbove = math.abs(high - recentHigh) < liqTolerance
liquidityBelow = math.abs(low - recentLow) < liqTolerance

// =====================================================
// STOP HUNT DETECTION
// =====================================================
stopHuntUp =
     showLiquidityTraps and
     high > recentHigh and
     close < recentHigh

stopHuntDown =
     showLiquidityTraps and
     low < recentLow and
     close > recentLow

// =====================================================
// EQUAL HIGHS / LOWS
// =====================================================
eqHigh = not na(lastPivotHigh) and math.abs(high - lastPivotHigh) <= eqTolerancePips
eqLow  = not na(lastPivotLow) and math.abs(low - lastPivotLow) <= eqTolerancePips

// =====================================
// LIQUIDITY TARGET PREDICTOR
// =====================================
liqTargetHigh = ta.highest(high, 40)
liqTargetLow  = ta.lowest(low, 40)

nextLiquidityHigh = ta.highest(high, 40)
nextLiquidityLow  = ta.lowest(low, 40)

var line targetHighLine = na
var line targetLowLine = na
var label nextLiqLabel = na

if barstate.islast
    if not na(nextLiqLabel)
        label.delete(nextLiqLabel)
    nextLiqLabel := label.new(
         bar_index,
         bullTrend ? nextLiquidityHigh : nextLiquidityLow,
         bullTrend ? "Next Liquidity ↑" : "Next Liquidity ↓",
         style=bullTrend ? label.style_label_down : label.style_label_up,
         color=bullTrend ? color.red : color.green,
         textcolor=color.white,
         size=size.small)

// =====================================================
// LIQUIDITY HEATMAP (STOP HUNT ZONES)
// =====================================================
var box liqHighBox = na
var box liqLowBox = na

liqHighCluster = eqHigh and not eqHigh[1]
liqLowCluster  = eqLow and not eqLow[1]

if liqHighCluster
    if not na(liqHighBox)
        box.delete(liqHighBox)
    liqHighBox := box.new(
         bar_index - 1,
         high + atrVal * 0.15,
         bar_index + 15,
         high,
         bgcolor=color.new(color.red, 85),
         border_color=color.red)

if liqLowCluster
    if not na(liqLowBox)
        box.delete(liqLowBox)
    liqLowBox := box.new(
         bar_index - 1,
         low,
         bar_index + 15,
         low - atrVal * 0.15,
         bgcolor=color.new(color.green, 85),
         border_color=color.green)

// Improvement 1: Added barstate.isconfirmed to avoid repainting
bearSweep = showLiquidity and not na(lastPivotHigh) and high > lastPivotHigh and close < lastPivotHigh and high[1] <= lastPivotHigh
bullSweep = showLiquidity and not na(lastPivotLow) and low < lastPivotLow and close > lastPivotLow and low[1] >= lastPivotLow

if showLiquidity and not liveMode and eqHigh and not eqHigh[1]
    label.new(bar_index, high, "EQH", style=label.style_label_down, color=color.new(color.red, 70), textcolor=color.white, size=size.tiny)

if showLiquidity and not liveMode and eqLow and not eqLow[1]
    label.new(bar_index, low, "EQL", style=label.style_label_up, color=color.new(color.green, 70), textcolor=color.white, size=size.tiny)

if not liveMode and bearSweep and not bearSweep[1]
    label.new(bar_index, high, "Liquidity Sweep ↓", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.small)

if not liveMode and bullSweep and not bullSweep[1]
    label.new(bar_index, low, "Liquidity Sweep ↑", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)

// =====================================================
// LIQUIDITY SWEEP PREDICTOR
// =====================================================
liqPredictHigh = ta.highest(high, 15)
liqPredictLow  = ta.lowest(low, 15)

var line liqHighLine = na
var line liqLowLine = na

if bullTrend and barstate.islast
    if not na(liqHighLine)
        line.delete(liqHighLine)
    liqHighLine := line.new(bar_index, liqPredictHigh, bar_index + 3, liqPredictHigh, color=color.red, style=line.style_dotted)

if bearTrend and barstate.islast
    if not na(liqLowLine)
        line.delete(liqLowLine)
    liqLowLine := line.new(bar_index, liqPredictLow, bar_index + 3, liqPredictLow, color=color.green, style=line.style_dotted)

// =====================================================
// INSTITUTIONAL LIQUIDITY TARGET (NEXT STOP HUNT)
// =====================================================
var line nextHighLine = na
var line nextLowLine = na

if bullTrend and barstate.islast
    if not na(nextHighLine)
        line.delete(nextHighLine)
    nextHighLine := line.new(
         bar_index,
         nextLiquidityHigh,
         bar_index + 8,
         nextLiquidityHigh,
         color=color.red,
         style=line.style_dashed,
         width=2)

if bearTrend and barstate.islast
    if not na(nextLowLine)
        line.delete(nextLowLine)
    nextLowLine := line.new(
         bar_index,
         nextLiquidityLow,
         bar_index + 8,
         nextLiquidityLow,
         color=color.green,
         style=line.style_dashed,
         width=2)

// =====================================================
// BREAK OF STRUCTURE & CHoCH (INSTITUTIONAL)
// =====================================================
bullBOS = barstate.isconfirmed and not na(lastPivotHigh) and close > lastPivotHigh and close[1] <= lastPivotHigh
bearBOS = barstate.isconfirmed and not na(lastPivotLow) and close < lastPivotLow and close[1] >= lastPivotLow

bullCHoCH = bearTrend[1] and bullBOS
bearCHoCH = bullTrend[1] and bearBOS

if showCHoCH and not liveMode and bullCHoCH
    label.new(bar_index, low, "CHoCH ↑", style=label.style_label_up, color=color.aqua, textcolor=color.black, size=size.small)

if showCHoCH and not liveMode and bearCHoCH
    label.new(bar_index, high, "CHoCH ↓", style=label.style_label_down, color=color.orange, textcolor=color.black, size=size.small)

// =====================================================
// FAIR VALUE GAPS (FVG)
// =====================================================
bullFVG = high[2] < low
bearFVG = low[2] > high

if showFVG and not liveMode and bullFVG and barstate.isconfirmed
    box.new(bar_index[1], low, bar_index + 5, high[2], bgcolor=color.new(color.green, 90), border_color=na)

if showFVG and not liveMode and bearFVG and barstate.isconfirmed
    box.new(bar_index[1], high, bar_index + 5, low[2], bgcolor=color.new(color.red, 90), border_color=na)

// =====================================================
// SMART MONEY CANDLE DETECTION
// =====================================================
bodySize = math.abs(close - open)
avgBody  = ta.sma(math.abs(close - open), 20)

smartBull = bodySize > avgBody * 1.8 and close > open and bullTrend
smartBear = bodySize > avgBody * 1.8 and close < open and bearTrend

if not liveMode and smartBull and barstate.isconfirmed
    label.new(bar_index, low, "SMC BUY CANDLE", style=label.style_label_up, color=color.green, textcolor=color.white)

if not liveMode and smartBear and barstate.isconfirmed
    label.new(bar_index, high, "SMC SELL CANDLE", style=label.style_label_down, color=color.red, textcolor=color.white)

// =====================================================
// KILLZONES (SESSIONS)
// =====================================================
inLondon = not na(time(timeframe.period, "0700-1100:1234567"))
inNY     = not na(time(timeframe.period, "1200-1600:1234567"))

// ================= SILVER BULLET TIME FILTER =================
inLondonClose = not na(time(timeframe.period, "1000-1100:1234567", "America/New_York"))
inNYAM        = not na(time(timeframe.period, "0300-0400:1234567", "America/New_York"))
inNYPM        = not na(time(timeframe.period, "1400-1500:1234567", "America/New_York"))

silverBulletSession = inLondonClose or inNYAM or inNYPM
allowTrading = true
inNewsBlock1 = not na(time(timeframe.period, newsBlock1, "America/New_York"))
inNewsBlock2 = not na(time(timeframe.period, newsBlock2, "America/New_York"))
newsBlocked  = useManualNewsBlock and (inNewsBlock1 or inNewsBlock2)
bgcolor(showSessions and inLondon ? color.new(color.blue, 96) : showSessions and inNY ? color.new(color.orange, 96) : na)
bgcolor(useSilverBullet and silverBulletSession ? color.new(color.purple, 92) : na)

baseDayId = year * 10000 + month * 100 + dayofmonth
currentSessionId =
     inNYAM ? baseDayId * 10 + 1 :
     inLondonClose ? baseDayId * 10 + 2 :
     inNYPM ? baseDayId * 10 + 3 :
     0

var int lastSessionId = na
var int sessionTrades = 0

if currentSessionId != 0 and currentSessionId != lastSessionId
    sessionTrades := 0
    lastSessionId := currentSessionId

sessionTradeAllowed = true
// =====================================================
// DESCENDING TRIANGLE DETECTION
// =====================================================
var float triHigh1 = na
var float triHigh2 = na
var int triHighBar1 = na
var int triHighBar2 = na

var float triLow1 = na
var float triLow2 = na
var int triLowBar1 = na
var int triLowBar2 = na

if not na(ph)
    triHigh2 := triHigh1
    triHighBar2 := triHighBar1
    triHigh1 := ph
    triHighBar1 := bar_index - pivotLen

if not na(pl)
    triLow2 := triLow1
    triLowBar2 := triLowBar1
    triLow1 := pl
    triLowBar1 := bar_index - pivotLen

triangleTolerance = atrVal * 1.5

descendingTriangleRaw = showDescendingTriangles and not na(triHigh2) and not na(triLow2) and triHigh1 < triHigh2 and math.abs(triLow1 - triLow2) <= triangleTolerance
descendingTriangle = descendingTriangleRaw and not descendingTriangleRaw[1]

var line triangleResistance = na
var line triangleSupport = na

if descendingTriangle
    if not na(triangleResistance)
        line.delete(triangleResistance)
    if not na(triangleSupport)
        line.delete(triangleSupport)
    triangleResistance := na
    triangleSupport := na

triangleBreakRaw = descendingTriangleRaw and low < triLow1
triangleBreak = triangleBreakRaw and not triangleBreakRaw[1]

if not liveMode and triangleBreak
    label.new(bar_index, low, "Triangle Break ↓", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.small)

// =====================================================
// ASCENDING TRIANGLE DETECTION
// =====================================================
var float ascHigh1 = na
var float ascHigh2 = na
var int ascHighBar1 = na
var int ascHighBar2 = na

var float ascLow1 = na
var float ascLow2 = na
var int ascLowBar1 = na
var int ascLowBar2 = na

if not na(ph)
    ascHigh2 := ascHigh1
    ascHighBar2 := ascHighBar1
    ascHigh1 := ph
    ascHighBar1 := bar_index - pivotLen

if not na(pl)
    ascLow2 := ascLow1
    ascLowBar2 := ascLowBar1
    ascLow1 := pl
    ascLowBar1 := bar_index - pivotLen

ascendingTriangleRaw = showAscendingTriangles and not na(ascHigh2) and not na(ascLow2) and ascLow1 > ascLow2 and math.abs(ascHigh1 - ascHigh2) <= triangleTolerance
ascendingTriangle = ascendingTriangleRaw and not ascendingTriangleRaw[1]

var line ascResistance = na
var line ascSupport = na

if ascendingTriangle
    if not na(ascResistance)
        line.delete(ascResistance)
    if not na(ascSupport)
        line.delete(ascSupport)
    ascResistance := na
    ascSupport := na

ascendingBreakRaw = ascendingTriangleRaw and high > ascHigh1
ascendingBreak = ascendingBreakRaw and not ascendingBreakRaw[1]

if not liveMode and ascendingBreak
    ascEntry = close
    ascSL = ascLow1
    ascRisk = ascEntry - ascSL
    ascTP1 = ascEntry + (ascRisk * 1)
    ascTP2 = ascEntry + (ascRisk * 2)
    ascTP3 = ascEntry + (ascRisk * 3)

    label.new(
         bar_index,
         high,
         "TRIANGLE BREAKOUT\nENTRY: " + str.tostring(ascEntry, format.mintick) +
         "\nSL: " + str.tostring(ascSL, format.mintick) +
         "\nTP1: " + str.tostring(ascTP1, format.mintick) +
         "\nTP2: " + str.tostring(ascTP2, format.mintick) +
         "\nTP3: " + str.tostring(ascTP3, format.mintick),
         style=label.style_label_up,
         color=color.lime,
         textcolor=color.black)

    line.new(bar_index, ascEntry, bar_index + 6, ascEntry, color=color.green, width=2)
    line.new(bar_index, ascSL, bar_index + 6, ascSL, color=color.red, style=line.style_dashed)
    line.new(bar_index, ascTP1, bar_index + 6, ascTP1, color=color.green)
    line.new(bar_index, ascTP2, bar_index + 6, ascTP2, color=color.green)
    line.new(bar_index, ascTP3, bar_index + 6, ascTP3, color=color.green)

// =====================================================
// DOUBLE TOP / DOUBLE BOTTOM
// =====================================================
doubleTolerance = atrVal * 0.3

doubleTopRaw = showDoublePatterns and not na(prevPivotHigh) and not na(lastPivotHigh) and math.abs(lastPivotHigh - prevPivotHigh) <= doubleTolerance and lastPivotHighBar > prevPivotHighBar
doubleBottomRaw = showDoublePatterns and not na(prevPivotLow) and not na(lastPivotLow) and math.abs(lastPivotLow - prevPivotLow) <= doubleTolerance and lastPivotLowBar > prevPivotLowBar

doubleTop = doubleTopRaw and not doubleTopRaw[1]
doubleBottom = doubleBottomRaw and not doubleBottomRaw[1]

var line doubleTopLine = na
var line doubleBottomLine = na

if doubleTop
    if not na(doubleTopLine)
        line.delete(doubleTopLine)
    doubleTopLine := line.new(prevPivotHighBar, prevPivotHigh, lastPivotHighBar, lastPivotHigh, extend=extend.right, color=color.red, width=2)
    if not liveMode
        label.new(lastPivotHighBar, lastPivotHigh, "Double Top", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.small)

if doubleBottom
    if not na(doubleBottomLine)
        line.delete(doubleBottomLine)
    doubleBottomLine := line.new(prevPivotLowBar, prevPivotLow, lastPivotLowBar, lastPivotLow, extend=extend.right, color=color.green, width=2)
    if not liveMode
        label.new(lastPivotLowBar, lastPivotLow, "Double Bottom", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)

doubleTopBreakRaw = doubleTopRaw and not na(lastPivotLow) and low < lastPivotLow
doubleBottomBreakRaw = doubleBottomRaw and not na(lastPivotHigh) and high > lastPivotHigh

doubleTopBreak = doubleTopBreakRaw and not doubleTopBreakRaw[1]
doubleBottomBreak = doubleBottomBreakRaw and not doubleBottomBreakRaw[1]

// =====================================================
// BULL FLAG / BEAR FLAG
// =====================================================
bullImpulse = close > close[6] and close[3] > close[6]
bearImpulse = close < close[6] and close[3] < close[6]

bullFlagRaw = showFlags and bullTrend and bullImpulse and ta.falling(high, 3) and ta.falling(low, 3)
bearFlagRaw = showFlags and bearTrend and bearImpulse and ta.rising(high, 3) and ta.rising(low, 3)

bullFlag = bullFlagRaw and not bullFlagRaw[1]
bearFlag = bearFlagRaw and not bearFlagRaw[1]

var line bullFlagTop = na
var line bullFlagBot = na
var line bearFlagTop = na
var line bearFlagBot = na

if bullFlag
    if not na(bullFlagTop)
        line.delete(bullFlagTop)
    if not na(bullFlagBot)
        line.delete(bullFlagBot)
    bullFlagTop := line.new(bar_index - 4, ta.highest(high, 5), bar_index + 6, ta.highest(high, 5) - (atrVal * 0.3), color=color.green, width=2)
    bullFlagBot := line.new(bar_index - 4, ta.lowest(low, 5), bar_index + 6, ta.lowest(low, 5) - (atrVal * 0.3), extend=extend.right, color=color.green, width=2)
    if not liveMode
        label.new(bar_index, low, "Bull Flag", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)

if bearFlag
    if not na(bearFlagTop)
        line.delete(bearFlagTop)
    if not na(bearFlagBot)
        line.delete(bearFlagBot)
    bearFlagTop := line.new(bar_index - 4, ta.highest(high, 5), bar_index + 10, ta.highest(high, 5) + (atrVal * 0.3), extend=extend.right, color=color.red, width=2)
    bearFlagBot := line.new(bar_index - 4, ta.lowest(low, 5), bar_index + 10, ta.lowest(low, 5) + (atrVal * 0.3), extend=extend.right, color=color.red, width=2)
    if not liveMode
        label.new(bar_index, high, "Bear Flag", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.small)

bullFlagBreakRaw = bullFlagRaw and high > ta.highest(high, 5)[1]
bearFlagBreakRaw = bearFlagRaw and low < ta.lowest(low, 5)[1]

bullFlagBreak = bullFlagBreakRaw and not bullFlagBreakRaw[1]
bearFlagBreak = bearFlagBreakRaw and not bearFlagBreakRaw[1]

// =====================================================
// HEAD & SHOULDERS / INVERSE H&S
// =====================================================
var float hsHigh1 = na
var float hsHigh2 = na
var float hsHigh3 = na
var int hsHighBar1 = na
var int hsHighBar2 = na
var int hsHighBar3 = na

var float hsLow1 = na
var float hsLow2 = na
var float hsLow3 = na
var int hsLowBar1 = na
var int hsLowBar2 = na
var int hsLowBar3 = na

if not na(ph)
    hsHigh3 := hsHigh2
    hsHighBar3 := hsHighBar2
    hsHigh2 := hsHigh1
    hsHighBar2 := hsHighBar1
    hsHigh1 := ph
    hsHighBar1 := bar_index - pivotLen

if not na(pl)
    hsLow3 := hsLow2
    hsLowBar3 := hsLowBar2
    hsLow2 := hsLow1
    hsLowBar2 := hsLowBar1
    hsLow1 := pl
    hsLowBar1 := bar_index - pivotLen

hsTolerance = atrVal * 0.5

headShouldersRaw = showHS and not na(hsHigh3) and hsHigh2 > hsHigh1 and hsHigh2 > hsHigh3 and math.abs(hsHigh1 - hsHigh3) <= hsTolerance and not na(hsLow1) and not na(hsLow2)
inverseHSRaw = showHS and not na(hsLow3) and hsLow2 < hsLow1 and hsLow2 < hsLow3 and math.abs(hsLow1 - hsLow3) <= hsTolerance and not na(hsHigh1) and not na(hsHigh2)

headShoulders = headShouldersRaw and not headShouldersRaw[1]
inverseHS = inverseHSRaw and not inverseHSRaw[1]

necklineHS = not na(hsLow1) and not na(hsLow2) ? (hsLow1 + hsLow2) / 2.0 : na
necklineIHS = not na(hsHigh1) and not na(hsHigh2) ? (hsHigh1 + hsHigh2) / 2.0 : na

var line hsNeckline = na
var line ihsNeckline = na

if headShoulders
    if not na(hsNeckline)
        line.delete(hsNeckline)
    hsNeckline := line.new(hsLowBar2, hsLow2, hsLowBar1, hsLow1, extend=extend.right, color=color.red, width=2)
    if not liveMode
        label.new(hsHighBar2, hsHigh2, "Head & Shoulders", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.small)

if inverseHS
    if not na(ihsNeckline)
        line.delete(ihsNeckline)
    ihsNeckline := line.new(hsHighBar2, hsHigh2, hsHighBar1, hsHigh1, extend=extend.right, color=color.green, width=2)
    if not liveMode
        label.new(hsLowBar2, hsLow2, "Inverse H&S", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)

headShouldersBreakRaw = headShouldersRaw and not na(necklineHS) and close < necklineHS
inverseHSBreakRaw = inverseHSRaw and not na(necklineIHS) and close > necklineIHS

headShouldersBreak = headShouldersBreakRaw and not headShouldersBreakRaw[1]
inverseHSBreak = inverseHSBreakRaw and not inverseHSBreakRaw[1]

// =====================================================
// ORDER BLOCK LOGIC
// =====================================================
var box bullOB = na
var box bearOB = na
var float bullOBTop = na
var float bullOBBot = na
var float bearOBTop = na
var float bearOBBot = na
var int bullOBBar = na
var int bearOBBar = na

findLastBearishIndex(maxBars) =>
    int idx = na
    for i = 1 to maxBars
        if close[i] < open[i]
            idx := i
            break
    idx

findLastBullishIndex(maxBars) =>
    int idx = na
    for i = 1 to maxBars
        if close[i] > open[i]
            idx := i
            break
    idx

if bullBOS
    idx = findLastBearishIndex(12)
    if not na(idx)
        bullOBTop := math.max(open[idx], close[idx])
        bullOBBot := low[idx]
        bullOBBar := bar_index - idx

        if not na(bullOB)
            box.delete(bullOB)

        bullOB := box.new(
             bullOBBar,
             math.max(bullOBTop, bullOBBot),
             bar_index + 8,
             math.min(bullOBTop, bullOBBot),
             bgcolor=color.new(color.green, 85),
             border_color=color.new(color.green, 20))

        if showOrderBlocks and not liveMode
            label.new(
                 bullOBBar,
                 bullOBTop,
                 "Bullish OB",
                 style=label.style_label_up,
                 color=color.new(color.green, 20),
                 textcolor=color.white,
                 size=size.small)

if bearBOS
    idx = findLastBullishIndex(12)
    if not na(idx)
        bearOBTop := high[idx]
        bearOBBot := math.min(open[idx], close[idx])
        bearOBBar := bar_index - idx

        if not na(bearOB)
            box.delete(bearOB)

        bearOB := box.new(
             bearOBBar,
             math.max(bearOBTop, bearOBBot),
             bar_index + 8,
             math.min(bearOBTop, bearOBBot),
             bgcolor=color.new(color.red, 85),
             border_color=color.new(color.red, 20))

        if showOrderBlocks and not liveMode
            label.new(
                 bearOBBar,
                 bearOBBot,
                 "Bearish OB",
                 style=label.style_label_down,
                 color=color.new(color.red, 20),
                 textcolor=color.white,
                 size=size.small)

if not na(bullOB)
    if (bar_index - bullOBBar) <= maxZoneAgeBars
        box.set_right(bullOB, bar_index + 8)
    else
        box.delete(bullOB)
        bullOB := na
        bullOBTop := na
        bullOBBot := na

if not na(bearOB)
    if (bar_index - bearOBBar) <= maxZoneAgeBars
        box.set_right(bearOB, bar_index + 8)
    else
        box.delete(bearOB)
        bearOB := na
        bearOBTop := na
        bearOBBot := na

// =====================================================
// RETEST / ENTRY CONDITIONS
// =====================================================
inBullOB = not na(bullOBTop) and low[1] <= bullOBTop and high[1] >= bullOBBot
inBearOB = not na(bearOBTop) and high[1] >= bearOBBot and low[1] <= bearOBTop

retestBull = ta.barssince(inBullOB) <= retestLookback
retestBear = ta.barssince(inBearOB) <= retestLookback

retestFreshBull = ta.barssince(inBullOB) <= freshRetestBars
retestFreshBear = ta.barssince(inBearOB) <= freshRetestBars

bullConfirm = close > open and rsiVal >= rsiBullMin
bearConfirm = close < open and rsiVal <= rsiBearMax

// =====================================
// VOLATILITY FILTER
// =====================================
atrFilter = atrVal > ta.sma(atrVal, 20) * 0.9
candidateBuyEntry = na(bullOBBot) ? close : bullOBBot
candidateSellEntry = na(bearOBTop) ? close : bearOBTop

candidateBuySL = not na(candidateBuyEntry) ? candidateBuyEntry - (atrVal * slAtrMult) : na
candidateSellSL = not na(candidateSellEntry) ? candidateSellEntry + (atrVal * slAtrMult) : na

buyRiskATR = not na(candidateBuyEntry) and not na(candidateBuySL) ? math.abs(candidateBuyEntry - candidateBuySL) / atrVal : na
sellRiskATR = not na(candidateSellEntry) and not na(candidateSellSL) ? math.abs(candidateSellEntry - candidateSellSL) / atrVal : na

buyRiskValid = not na(buyRiskATR) and buyRiskATR >= minRiskATR and buyRiskATR <= maxRiskATR
sellRiskValid = not na(sellRiskATR) and sellRiskATR >= minRiskATR and sellRiskATR <= maxRiskATR

// =====================================================
// SNIPER ENTRY DETECTION + REVERSAL ENGINE
// =====================================================

// Candle anatomy
candleRange = high - low
bullBody = close - open
bearBody = open - close
lowerWick = math.min(open, close) - low
upperWick = high - math.max(open, close)

// Rejection candles
bullRejection =
     candleRange > 0 and
     lowerWick > bullBody * 1.2 and
     close > open and
     close >= low + candleRange * 0.60

bearRejection =
     candleRange > 0 and
     upperWick > bearBody * 1.2 and
     close < open and
     close <= low + candleRange * 0.40

// Early reversal reclaim logic
bullReclaim =
     not na(lastPivotLow) and
     close > lastPivotLow and
     low < lastPivotLow

bearReclaim =
     not na(lastPivotHigh) and
     close < lastPivotHigh and
     high > lastPivotHigh

// Reversal engines
reversalBuy =
     (stopHuntDown or bullSweep) and
     (
         bullRejection or
         bullCHoCH or
         bullBOS or
         bullReclaim or
         (close > open and close > close[1])  // 🔥 momentum reclaim
     ) and
     rsiVal > 38

reversalSell =
     (stopHuntUp or bearSweep) and
     (
         bearRejection or
         bearCHoCH or
         bearBOS or
         bearReclaim or
         (close < open and close < close[1])  // 🔥 momentum drop
     ) and
     rsiVal < 62

// Continuation sniper logic
sniperBuy =
     ((stopHuntDown and bullTrend) or reversalBuy) and
     rsiVal > 45

sniperSell =
     ((stopHuntUp and bearTrend) or reversalSell) and
     rsiVal < 55
// =====================================================
// AI PROBABILITY ENGINE V2 (Weighted Institutional Model)
// =====================================================
buyWeight = 0.0
sellWeight = 0.0

// -----------------------------------------------------
// TIER 1 — INSTITUTIONAL STRUCTURE (Very Strong)
// -----------------------------------------------------
buyWeight += bullBOS ? 4.0 : 0
sellWeight += bearBOS ? 4.0 : 0

buyWeight += bullSweep ? 3.5 : 0
sellWeight += bearSweep ? 3.5 : 0

buyWeight += stopHuntDown ? 3.5 : 0
sellWeight += stopHuntUp ? 3.5 : 0
buyWeight += bullRejection ? 2.0 : 0
sellWeight += bearRejection ? 2.0 : 0

buyWeight += reversalBuy ? 3.0 : 0
sellWeight += reversalSell ? 3.0 : 0
// SNIPER LIQUIDITY ENTRY BOOST
buyWeight += (stopHuntDown and bullTrend) ? 2.0 : 0
sellWeight += (stopHuntUp and bearTrend) ? 2.0 : 0

// -----------------------------------------------------
// TIER 2 — TREND + HTF CONFIRMATION
// -----------------------------------------------------
buyWeight += bullTrend ? 3.0 : 0
sellWeight += bearTrend ? 3.0 : 0

buyWeight += htfBull ? 2.5 : 0
sellWeight += htfBear ? 2.5 : 0

// -----------------------------------------------------
// TIER 3 — PATTERN STRUCTURE
// -----------------------------------------------------
buyWeight += (ascendingBreak and bullTrend) ? 2.0 : 0
buyWeight += (doubleBottomBreak and bullTrend) ? 2.0 : 0
buyWeight += (bullFlagBreak and bullTrend) ? 1.5 : 0
buyWeight += (inverseHSBreak and bullTrend) ? 2.5 : 0

sellWeight += (triangleBreak and bearTrend) ? 1.5 : 0
sellWeight += (doubleTopBreak and bearTrend) ? 1.5 : 0
sellWeight += (bearFlagBreak and bearTrend) ? 1.0 : 0
sellWeight += (headShouldersBreak and bearTrend) ? 2.0 : 0

// -----------------------------------------------------
// TIER 4 — CONFIRMATION SIGNALS
// -----------------------------------------------------
buyWeight += rsiVal >= rsiBullMin ? 1.5 : 0
sellWeight += rsiVal <= rsiBearMax ? 1.5 : 0

buyWeight += retestBull ? 1.5 : 0
sellWeight += retestBear ? 1.5 : 0

buyWeight += volumeSpike ? 1.0 : 0
sellWeight += volumeSpike ? 1.0 : 0

buyWeight += institutionalBull ? 1.5 : 0
sellWeight += institutionalBear ? 1.5 : 0

// =====================================================
// NORMALIZED PROBABILITY MODEL (FIXED)
// =====================================================
if bullTrend and not reversalSell
    sellWeight := sellWeight * 0.5

if bearTrend and not reversalBuy
    buyWeight := buyWeight * 0.5

totalWeight = buyWeight + sellWeight

buyProbability =
     totalWeight > 0
     ? math.round(math.min((buyWeight / totalWeight) * 100, 95))
     : 0

sellProbability =
     totalWeight > 0
     ? math.round(math.min((sellWeight / totalWeight) * 100, 95))
     : 0

if bullTrend and not reversalSell
    sellProbability := math.round(sellProbability * 0.3)

if bearTrend and not reversalBuy
    buyProbability := math.round(buyProbability * 0.3)

tradeProbability =
     buyProbability > sellProbability
     ? buyProbability
     : sellProbability
// =====================================================
// CORE SIGNAL ENGINE
// =====================================================
// TRADE COOLDOWN ENGINE
// =====================================================
var int lastTradeBar = na
cooldownBars = 5
canTrade = na(lastTradeBar) or bar_index - lastTradeBar > cooldownBars
// =====================================================
// 🚀 FINAL SIGNAL ENGINE (SNIPER FILTER)
// =====================================================

// BUY SIGNAL
buySignal =
     canTrade and
     allowTrading and
     sessionTradeAllowed and
     not newsBlocked and
     atrFilter and
     buyRiskValid and
     (
         (
             bullTrend and
             htfBull and
             institutionalBull and
             barstate.isconfirmed and   // keep confirmation ONLY here
             tradeProbability >= 70 and
             (retestBull or sniperBuy)
         )
         or
         (
             reversalBuy and
             tradeProbability >= 55     // 🔥 EARLY ENTRY (no confirmation)
         )
     )


// SELL SIGNAL
sellSignal =
     canTrade and
     allowTrading and
     sessionTradeAllowed and
     not newsBlocked and
     atrFilter and
     sellRiskValid and
     (
         (
             bearTrend and
             htfBear and
             institutionalBear and
             barstate.isconfirmed and   // only continuation waits
             tradeProbability >= 70 and
             (retestBear or sniperSell)
         )
         or
         (
             reversalSell and
             tradeProbability >= 55     // 🔥 early sniper
         )
     )

// =====================================================

// =====================================================
// SIGNAL DETECTION (FULLY UPDATED)
// =====================================================
// ENTRY / SL / TP - STATE
// =====================================================
var float lastEntry = na
var float lastSL = na
var float lastTP1 = na
var float lastTP2 = na
var float lastTP3 = na
var string lastDir = "NONE"
var int tradeStartBar = na
var int tradeEndBar = na
var int safeEndBar = na
var int setupState = 0   // 0 = none, 1 = pending, 2 = filled
tradeClosed = false
var int setupCreatedBar = na
refreshBuy = buySignal and not buySignal[1] and canTrade
refreshSell = sellSignal and not sellSignal[1] and canTrade
// Only trigger a "New" buy if we aren't already in one
isNewBuy  = refreshBuy and (lastDir == "NONE" or lastDir == "SELL")
isNewSell = refreshSell and (lastDir == "NONE" or lastDir == "BUY")

// =====================================================
// 🔥 AUTO FLIP ENGINE (INSTANT REVERSAL EXIT)
// =====================================================

// =====================================================
// 🧠 SMART AUTO FLIP ENGINE (REFINED)
// =====================================================

// Define strong reversal conditions
strongSellFlip =
     reversalSell and
     tradeProbability >= 60 and
     sellProbability > buyProbability

strongBuyFlip =
     reversalBuy and
     tradeProbability >= 60 and
     buyProbability > sellProbability

// Flip BUY → SELL only on STRONG reversal
if lastDir == "BUY" and strongSellFlip
    tradeClosed := true
    setupState := 0
    lastDir := "NONE"

// Flip SELL → BUY only on STRONG reversal
if lastDir == "SELL" and strongBuyFlip
    tradeClosed := true
    setupState := 0
    lastDir := "NONE"

if isNewBuy or isNewSell
    tradeStartBar := bar_index + 1
    tradeEndBar := bar_index + projectionBars

// =====================================================
// SIGNAL GRADING
// =====================================================
signalGrade = "NONE"

if tradeProbability >= 80
    signalGrade := "A+"
else if tradeProbability >= 65
    signalGrade := "A"
else if tradeProbability >= 50
    signalGrade := "B"
else if tradeProbability >= 35
    signalGrade := "C"
else
    signalGrade := "WEAK"

// =====================================================
// ALERT CONDITIONS
// =====================================================
alertcondition(isNewBuy, title="JIGSA GOD MODE BUY", message="BUY Signal | {{ticker}} | Price: {{close}} | TF: {{interval}}")
alertcondition(isNewSell, title="JIGSA GOD MODE SELL", message="SELL Signal | {{ticker}} | Price: {{close}} | TF: {{interval}}")

// =====================================================
// ENTRY / SL / TP - STATE
// =====================================================

// TRADE VISUAL OBJECTS
var box riskBox = na
var box rewardBox = na

var line entL = na
var line slL = na
var line tp1L = na
var line tp2L = na
var line tp3L = na

var label entLb = na
var label slLb = na
var label tp1Lb = na
var label tp2Lb = na
var label tp3Lb = na
var label liveSignalLabel = na
var bool tp1Hit = false
var bool tp2Hit = false
var bool tp3Hit = false
// =====================================================
// CLEAR CURRENT VISUALS
// =====================================================
clearCurrentVisuals = false
if liveMode and barstate.isconfirmed and tradeClosed
    clearCurrentVisuals := true

if clearCurrentVisuals
    lastDir := "NONE"
    lastEntry := na
    lastSL := na
    lastTP1 := na
    lastTP2 := na
    lastTP3 := na
    tradeStartBar := na

    if not na(riskBox)
        box.delete(riskBox)
    if not na(rewardBox)
        box.delete(rewardBox)

    if not na(entL)
        line.delete(entL)
    if not na(slL)
        line.delete(slL)
    if not na(tp1L)
        line.delete(tp1L)
    if not na(tp2L)
        line.delete(tp2L)
    if not na(tp3L)
        line.delete(tp3L)

    if not na(entLb)
        label.delete(entLb)
    if not na(slLb)
        label.delete(slLb)
    if not na(tp1Lb)
        label.delete(tp1Lb)
    if not na(tp2Lb)
        label.delete(tp2Lb)
    if not na(tp3Lb)
        label.delete(tp3Lb)

    if not na(liveSignalLabel)
        label.delete(liveSignalLabel)

    riskBox := na
    rewardBox := na
    entL := na
    slL := na
    tp1L := na
    tp2L := na
    tp3L := na
    entLb := na
    slLb := na
    tp1Lb := na
    tp2Lb := na
    tp3Lb := na
    liveSignalLabel := na

// =====================================================
// ENTRY INVALIDATION (ONLY FOR NON-LIVE MODE)
// =====================================================
maxEntryDistance = atrVal * 8.0

if not liveMode and lastDir == "BUY" and not na(lastEntry) and not na(tradeStartBar)
    if math.abs(close - lastEntry) > maxEntryDistance and bar_index - tradeStartBar > 4
        lastDir := "NONE"
        lastEntry := na
        lastSL := na
        lastTP1 := na
        lastTP2 := na
        lastTP3 := na
        tradeStartBar := na

        if not na(riskBox)
            box.delete(riskBox)
        if not na(rewardBox)
            box.delete(rewardBox)

        if not na(entL)
            line.delete(entL)
        if not na(slL)
            line.delete(slL)
        if not na(tp1L)
            line.delete(tp1L)
        if not na(tp2L)
            line.delete(tp2L)
        if not na(tp3L)
            line.delete(tp3L)

        if not na(entLb)
            label.delete(entLb)
        if not na(slLb)
            label.delete(slLb)
        if not na(tp1Lb)
            label.delete(tp1Lb)
        if not na(tp2Lb)
            label.delete(tp2Lb)
        if not na(tp3Lb)
            label.delete(tp3Lb)

        riskBox := na
        rewardBox := na
        entL := na
        slL := na
        tp1L := na
        tp2L := na
        tp3L := na
        entLb := na
        slLb := na
        tp1Lb := na
        tp2Lb := na
        tp3Lb := na

if not liveMode and lastDir == "SELL" and not na(lastEntry) and not na(tradeStartBar)
    if math.abs(close - lastEntry) > maxEntryDistance and bar_index - tradeStartBar > 4
        lastDir := "NONE"
        lastEntry := na
        lastSL := na
        lastTP1 := na
        lastTP2 := na
        lastTP3 := na
        tradeStartBar := na

        if not na(riskBox)
            box.delete(riskBox)
        if not na(rewardBox)
            box.delete(rewardBox)

        if not na(entL)
            line.delete(entL)
        if not na(slL)
            line.delete(slL)
        if not na(tp1L)
            line.delete(tp1L)
        if not na(tp2L)
            line.delete(tp2L)
        if not na(tp3L)
            line.delete(tp3L)

        if not na(entLb)
            label.delete(entLb)
        if not na(slLb)
            label.delete(slLb)
        if not na(tp1Lb)
            label.delete(tp1Lb)
        if not na(tp2Lb)
            label.delete(tp2Lb)
        if not na(tp3Lb)
            label.delete(tp3Lb)

        riskBox := na
        rewardBox := na
        entL := na
        slL := na
        tp1L := na
        tp2L := na
        tp3L := na
        entLb := na
        slLb := na
        tp1Lb := na
        tp2Lb := na
        tp3Lb := na

// =====================================================
// CREATE / REFRESH BUY SETUP
// =====================================================
if refreshBuy

    // 🔥 ADD THIS BLOCK RIGHT HERE
    if not na(riskBox)
        box.delete(riskBox)
        riskBox := na

    if not na(rewardBox)
        box.delete(rewardBox)
        rewardBox := na

    if not na(entL)
        line.delete(entL)
        entL := na

    if not na(slL)
        line.delete(slL)
        slL := na

    if not na(tp1L)
        line.delete(tp1L)
        tp1L := na

    if not na(tp2L)
        line.delete(tp2L)
        tp2L := na

    if not na(tp3L)
        line.delete(tp3L)
        tp3L := na

    if not na(entLb)
        label.delete(entLb)
        entLb := na

    if not na(slLb)
        label.delete(slLb)
        slLb := na

    if not na(tp1Lb)
        label.delete(tp1Lb)
        tp1Lb := na

    if not na(tp2Lb)
        label.delete(tp2Lb)
        tp2Lb := na

    if not na(tp3Lb)
        label.delete(tp3Lb)
        tp3Lb := na

    if not na(liveSignalLabel)
        label.delete(liveSignalLabel)
        liveSignalLabel := na
    // delete previous setup completely
    if not na(riskBox)
        box.delete(riskBox)
    if not na(rewardBox)
        box.delete(rewardBox)

    if not na(entL)
        line.delete(entL)
    if not na(slL)
        line.delete(slL)
    if not na(tp1L)
        line.delete(tp1L)
    if not na(tp2L)
        line.delete(tp2L)
    if not na(tp3L)
        line.delete(tp3L)

    if not na(entLb)
        label.delete(entLb)
    if not na(slLb)
        label.delete(slLb)
    if not na(tp1Lb)
        label.delete(tp1Lb)
    if not na(tp2Lb)
        label.delete(tp2Lb)
    if not na(tp3Lb)
        label.delete(tp3Lb)

    if not na(liveSignalLabel)
        label.delete(liveSignalLabel)

    tradeStartBar := bar_index + 1
    safeEndBar    := tradeStartBar + projectionBars
    setupCreatedBar := bar_index
    setupState := 1
    tp1Hit := false
    tp2Hit := false
    tp3Hit := false
    lastDir := "BUY"

    lastEntry :=
     reversalBuy
     ? low                              // 🔥 wick entry for reversal
     : (na(bullOBBot) ? low : bullOBBot) // normal logic
    lastSL    := lastEntry - (ta.atr(14) * slAtrMult)

    risk = math.abs(lastEntry - lastSL)
    lastTP1 := lastEntry + risk * riskReward
    lastTP2 := lastEntry + risk * (riskReward + 1)
    lastTP3 := lastEntry + risk * (riskReward + 2)

    if showTargets
        entL := line.new(tradeStartBar, lastEntry, safeEndBar, lastEntry, color=color.rgb(41, 98, 255), width=2)
        slL  := line.new(tradeStartBar, lastSL,    safeEndBar, lastSL,    color=color.rgb(255, 82, 82), width=2)
        tp1L := line.new(tradeStartBar, lastTP1,   safeEndBar, lastTP1,   color=color.rgb(76, 175, 80), width=2)
        tp2L := line.new(tradeStartBar, lastTP2,   safeEndBar, lastTP2,   color=color.rgb(76, 175, 80), width=2)
        tp3L := line.new(tradeStartBar, lastTP3,   safeEndBar, lastTP3,   color=color.rgb(76, 175, 80), width=2)

        riskBox := box.new(
         tradeStartBar,
         math.max(lastSL, lastEntry),
         safeEndBar,
         math.min(lastSL, lastEntry),
         bgcolor=color.new(color.red, 86),
         border_color=color.new(color.red, 25))

        rewardBox := box.new(
         tradeStartBar,
         math.max(lastEntry, lastTP1),
         safeEndBar,
         math.min(lastEntry, lastTP1),
         bgcolor=color.new(color.green, 82),
         border_color=color.new(color.green, 25))

        labelX = safeEndBar + 1
        entLb := label.new(labelX, lastEntry, "Entry: " + str.tostring(lastEntry, format.mintick), style=label.style_label_right, color=color.rgb(41, 98, 255), textcolor=color.white, size=size.normal)
        slLb  := label.new(labelX, lastSL,    "SL: " + str.tostring(lastSL, format.mintick),       style=label.style_label_right, color=color.rgb(255, 82, 82), textcolor=color.white, size=size.normal)
        tp1Lb := label.new(labelX, lastTP1,   "TP1: " + str.tostring(lastTP1, format.mintick),     style=label.style_label_right, color=color.rgb(76, 175, 80), textcolor=color.white, size=size.normal)
        tp2Lb := label.new(labelX, lastTP2,   "TP2: " + str.tostring(lastTP2, format.mintick),     style=label.style_label_right, color=color.rgb(76, 175, 80), textcolor=color.white, size=size.normal)
        tp3Lb := label.new(labelX, lastTP3,   "TP3: " + str.tostring(lastTP3, format.mintick),     style=label.style_label_right, color=color.rgb(76, 175, 80), textcolor=color.white, size=size.normal)

    if liveMode
        liveSignalLabel := label.new(bar_index, low, "BUY", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.large)

// =====================================================
// CREATE / REFRESH SELL SETUP
// =====================================================
if refreshSell
    // 🔥 ADD THIS BLOCK RIGHT HERE
    if not na(riskBox)
        box.delete(riskBox)
        riskBox := na

    if not na(rewardBox)
        box.delete(rewardBox)
        rewardBox := na

    if not na(entL)
        line.delete(entL)
        entL := na

    if not na(slL)
        line.delete(slL)
        slL := na

    if not na(tp1L)
        line.delete(tp1L)
        tp1L := na

    if not na(tp2L)
        line.delete(tp2L)
        tp2L := na

    if not na(tp3L)
        line.delete(tp3L)
        tp3L := na

    if not na(entLb)
        label.delete(entLb)
        entLb := na

    if not na(slLb)
        label.delete(slLb)
        slLb := na

    if not na(tp1Lb)
        label.delete(tp1Lb)
        tp1Lb := na

    if not na(tp2Lb)
        label.delete(tp2Lb)
        tp2Lb := na

    if not na(tp3Lb)
        label.delete(tp3Lb)
        tp3Lb := na

    if not na(liveSignalLabel)
        label.delete(liveSignalLabel)
        liveSignalLabel := na
    
    riskBox := na
    rewardBox := na
    entL := na
    slL := na
    tp1L := na
    tp2L := na
    tp3L := na
    entLb := na
    slLb := na
    tp1Lb := na
    tp2Lb := na
    tp3Lb := na
    liveSignalLabel := na
    if not na(entL)
        line.delete(entL)
    if not na(slL)
        line.delete(slL)
    if not na(tp1L)
        line.delete(tp1L)
    if not na(tp2L)
        line.delete(tp2L)
    if not na(tp3L)
        line.delete(tp3L)

    if not na(entLb)
        label.delete(entLb)
    if not na(slLb)
        label.delete(slLb)
    if not na(tp1Lb)
        label.delete(tp1Lb)
    if not na(tp2Lb)
        label.delete(tp2Lb)
    if not na(tp3Lb)
        label.delete(tp3Lb)

    if not na(liveSignalLabel)
        label.delete(liveSignalLabel)

    tradeStartBar := bar_index + 1
    safeEndBar    := tradeStartBar + projectionBars
    setupCreatedBar := bar_index
    setupState := 1
    tp1Hit := false
    tp2Hit := false
    tp3Hit := false
    lastDir := "SELL"

    lastEntry :=
     reversalSell
     ? high                             // 🔥 wick entry for reversal
     : (na(bearOBTop) ? high : bearOBTop)
    lastSL    := lastEntry + (ta.atr(14) * slAtrMult)

    risk = math.abs(lastSL - lastEntry)
    lastTP1 := lastEntry - risk * riskReward
    lastTP2 := lastEntry - risk * (riskReward + 1)
    lastTP3 := lastEntry - risk * (riskReward + 2)

    if showTargets
        entL := line.new(tradeStartBar, lastEntry, safeEndBar, lastEntry, color=color.rgb(41, 98, 255), width=2)
        slL  := line.new(tradeStartBar, lastSL,    safeEndBar, lastSL,    color=color.rgb(255, 82, 82), width=2)
        tp1L := line.new(tradeStartBar, lastTP1,   safeEndBar, lastTP1,   color=color.rgb(76, 175, 80), width=2)
        tp2L := line.new(tradeStartBar, lastTP2,   safeEndBar, lastTP2,   color=color.rgb(76, 175, 80), width=2)
        tp3L := line.new(tradeStartBar, lastTP3,   safeEndBar, lastTP3,   color=color.rgb(76, 175, 80), width=2)

        riskBox := box.new(
         tradeStartBar,
         math.max(lastSL, lastEntry),
         safeEndBar,
         math.min(lastSL, lastEntry),
         bgcolor=color.new(color.red, 86),
         border_color=color.new(color.red, 25))

        rewardBox := box.new(
         tradeStartBar,
         math.max(lastEntry, lastTP1),
         safeEndBar,
         math.min(lastEntry, lastTP1),
         bgcolor=color.new(color.green, 82),
         border_color=color.new(color.green, 25))

        labelX = safeEndBar + 1
        entLb := label.new(labelX, lastEntry, "Entry: " + str.tostring(lastEntry, format.mintick), style=label.style_label_right, color=color.rgb(41, 98, 255), textcolor=color.white)
        slLb  := label.new(labelX, lastSL,    "SL: " + str.tostring(lastSL, format.mintick),       style=label.style_label_right, color=color.rgb(255, 82, 82), textcolor=color.white)
        tp1Lb := label.new(labelX, lastTP1,   "TP1: " + str.tostring(lastTP1, format.mintick),      style=label.style_label_right, color=color.rgb(76, 175, 80), textcolor=color.white)
        tp2Lb := label.new(labelX, lastTP2,   "TP2: " + str.tostring(lastTP2, format.mintick),      style=label.style_label_right, color=color.rgb(76, 175, 80), textcolor=color.white)
        tp3Lb := label.new(labelX, lastTP3,   "TP3: " + str.tostring(lastTP3, format.mintick),      style=label.style_label_right, color=color.rgb(76, 175, 80), textcolor=color.white)    
    if liveMode
        liveSignalLabel := label.new(bar_index + 1, high, "SELL", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.large)


// =====================================================
// SETUP LIFECYCLE: PENDING / FILLED / EXPIRED
// =====================================================

// Pending fill
if setupState == 1 and lastDir == "BUY" and low <= lastEntry
    setupState := 2
    sessionTrades += 1
    lastTradeBar := bar_index

if setupState == 1 and lastDir == "SELL" and high >= lastEntry
    setupState := 2
    sessionTrades += 1
    lastTradeBar := bar_index

// Pending expiry
if setupState == 1 and not na(setupCreatedBar) and bar_index - setupCreatedBar > setupExpiryBars
    setupState := 0
    lastDir := "NONE"
    lastEntry := na
    lastSL := na
    lastTP1 := na
    lastTP2 := na
    lastTP3 := na
    tradeStartBar := na
    tradeEndBar := na
    setupCreatedBar := na

    if not na(riskBox)
        box.delete(riskBox)
    if not na(rewardBox)
        box.delete(rewardBox)

    if not na(entL)
        line.delete(entL)
    if not na(slL)
        line.delete(slL)
    if not na(tp1L)
        line.delete(tp1L)
    if not na(tp2L)
        line.delete(tp2L)
    if not na(tp3L)
        line.delete(tp3L)

    if not na(entLb)
        label.delete(entLb)
    if not na(slLb)
        label.delete(slLb)
    if not na(tp1Lb)
        label.delete(tp1Lb)
    if not na(tp2Lb)
        label.delete(tp2Lb)
    if not na(tp3Lb)
        label.delete(tp3Lb)

    riskBox := na
    rewardBox := na
    entL := na
    slL := na
    tp1L := na
    tp2L := na
    tp3L := na
    entLb := na
    slLb := na
    tp1Lb := na
    tp2Lb := na
    tp3Lb := na

// =====================================================
// BREAKEVEN LOGIC (NON-LIVE MODE ONLY)
// =====================================================
if not liveMode and lastDir == "BUY" and not na(lastTP1) and high >= lastTP1
    lastSL := lastEntry

if not liveMode and lastDir == "SELL" and not na(lastTP1) and low <= lastTP1
    lastSL := lastEntry

// SIGNAL KILLER: If price moves against us, delete the signal immediately

if setupState == 1 and lastDir == "BUY"
    if low <= lastSL
        tradeClosed := true

if setupState == 1 and lastDir == "SELL"
    if high >= lastSL
        tradeClosed := true

if setupState == 2 and lastDir == "BUY"
    if low <= lastSL
        tradeClosed := true

if setupState == 2 and lastDir == "SELL"
    if high >= lastSL
        tradeClosed := true

if tradeClosed
    setupState := 0
    setupCreatedBar := na
    lastDir := "NONE"
    lastEntry := na
    lastSL := na
    lastTP1 := na
    lastTP2 := na
    lastTP3 := na
    tradeStartBar := na
    tradeEndBar := na
    // This part physically deletes the old boxes from your screen
    if not na(riskBox)
        box.delete(riskBox)
    if not na(rewardBox)
        box.delete(rewardBox)
    // Clear lines
    if not na(entL)
        line.delete(entL)
    if not na(slL)
        line.delete(slL)
    if not na(tp1L)
        line.delete(tp1L)
    if not na(tp2L)
        line.delete(tp2L)
    if not na(tp3L)
        line.delete(tp3L)

    if not na(entLb)
        label.delete(entLb)
    if not na(slLb)
        label.delete(slLb)
    if not na(tp1Lb)
        label.delete(tp1Lb)
    if not na(tp2Lb)
        label.delete(tp2Lb)
    if not na(tp3Lb)
        label.delete(tp3Lb)

    if not na(liveSignalLabel)
        label.delete(liveSignalLabel)

    riskBox := na
    rewardBox := na
    entL := na
    slL := na
    tp1L := na
    tp2L := na
    tp3L := na
    entLb := na
    slLb := na
    tp1Lb := na
    tp2Lb := na
    tp3Lb := na
    liveSignalLabel := na


if setupState == 2 and lastDir == "BUY"
    if not tp1Hit and high >= lastTP1
        tp1Hit := true
        label.new(bar_index, lastTP1, "TP1", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)
    if not tp2Hit and high >= lastTP2
        tp2Hit := true
        label.new(bar_index, lastTP2, "TP2", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)
    if not tp3Hit and high >= lastTP3
        tp3Hit := true
        label.new(bar_index, lastTP3, "TP3", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)

if setupState == 2 and lastDir == "SELL"
    if not tp1Hit and low <= lastTP1
        tp1Hit := true
        label.new(bar_index, lastTP1, "TP1", style=label.style_label_down, color=color.green, textcolor=color.white, size=size.small)
    if not tp2Hit and low <= lastTP2
        tp2Hit := true
        label.new(bar_index, lastTP2, "TP2", style=label.style_label_down, color=color.green, textcolor=color.white, size=size.small)
    if not tp3Hit and low <= lastTP3
        tp3Hit := true
        label.new(bar_index, lastTP3, "TP3", style=label.style_label_down, color=color.green, textcolor=color.white, size=size.small)
// =====================================
// ORDER TYPE DETECTOR
// =====================================
var string orderType = "NONE"
orderType := "NONE"

if lastDir == "BUY"
    orderType := lastEntry > close ? "BUY STOP" : "BUY LIMIT"

if lastDir == "SELL"
    orderType := lastEntry > close ? "SELL LIMIT" : "SELL STOP"

marketMomentum = rsiVal > 60 ? "STRONG BULLS" : rsiVal < 40 ? "STRONG BEARS" : "NEUTRAL"

// =====================================================
// SNIPER ENTRY ALERTS
// =====================================================
if not liveMode and sniperBuy and not sniperBuy[1] and barstate.isconfirmed
    label.new(bar_index, low, "SNIPER BUY", style=label.style_label_up, color=color.lime, textcolor=color.black)

if not liveMode and sniperSell and not sniperSell[1] and barstate.isconfirmed
    label.new(bar_index, high, "SNIPER SELL", style=label.style_label_down, color=color.orange, textcolor=color.white)

// =====================================================
// VISUALS
// =====================================================
plot(showEMAs ? emaFast : na, "EMA Fast", color=color.aqua, linewidth=2)
plot(vwapValue, "VWAP", color=color.yellow, linewidth=2)
plot(showEMAs ? emaSlow : na, "EMA Slow", color=color.orange, linewidth=2)

bgcolor(na)

plotshape(
     not liveMode and showSignals and isNewBuy and barstate.isconfirmed,
     title="BUY",
     text="BUY",
     style=shape.labelup,
     location=location.belowbar,
     color=color.green,
     textcolor=color.white,
     size=size.normal)

plotshape(
     not liveMode and showSignals and isNewSell and barstate.isconfirmed,
     title="SELL",
     text="SELL",
     style=shape.labeldown,
     location=location.abovebar,
     color=color.red,
     textcolor=color.white,
     size=size.normal)
     
// RIGHT-SIDE LABEL SYNC
if not na(entLb) and lastDir != "NONE"
    label.set_x(entLb, safeEndBar + 1)
    label.set_y(entLb, lastEntry)

if not na(slLb) and lastDir != "NONE"
    label.set_x(slLb, safeEndBar + 1)
    label.set_y(slLb, lastSL)

if not na(tp1Lb) and lastDir != "NONE"
    label.set_x(tp1Lb, safeEndBar + 1)
    label.set_y(tp1Lb, lastTP1)

if not na(tp2Lb) and lastDir != "NONE"
    label.set_x(tp2Lb, safeEndBar + 1)
    label.set_y(tp2Lb, lastTP2)

if not na(tp3Lb) and lastDir != "NONE"
    label.set_x(tp3Lb, safeEndBar + 1)
    label.set_y(tp3Lb, lastTP3)

if not na(entL) and lastDir != "NONE"
    line.set_xy1(entL, tradeStartBar, lastEntry)
    line.set_xy2(entL, safeEndBar, lastEntry)

if not na(slL) and lastDir != "NONE"
    line.set_xy1(slL, tradeStartBar, lastSL)
    line.set_xy2(slL, safeEndBar, lastSL)

if not na(tp1L) and lastDir != "NONE"
    line.set_xy1(tp1L, tradeStartBar, lastTP1)
    line.set_xy2(tp1L, safeEndBar, lastTP1)

if not na(tp2L) and lastDir != "NONE"
    line.set_xy1(tp2L, tradeStartBar, lastTP2)
    line.set_xy2(tp2L, safeEndBar, lastTP2)

if not na(tp3L) and lastDir != "NONE"
    line.set_xy1(tp3L, tradeStartBar, lastTP3)
    line.set_xy2(tp3L, safeEndBar, lastTP3)
// ✅ RISK BOX (SL AREA)
if not na(riskBox) and lastDir != "NONE"
    box.set_left(riskBox, tradeStartBar)
    box.set_right(riskBox, safeEndBar)
    box.set_top(riskBox, math.max(lastEntry, lastSL))
    box.set_bottom(riskBox, math.min(lastEntry, lastSL))

// ✅ REWARD BOX (TP AREA)
if not na(rewardBox) and lastDir != "NONE"
    box.set_left(rewardBox, tradeStartBar)
    box.set_right(rewardBox, safeEndBar)
    box.set_top(rewardBox, math.max(lastEntry, lastTP1))
    box.set_bottom(rewardBox, math.min(lastEntry, lastTP1))// =====================================================
// LIQUIDITY MAGNET AI
// =====================================================
magnetLookback = 12

magnetHigh = ta.highest(high, magnetLookback)
magnetLow = ta.lowest(low, magnetLookback)

magnetPrice =
     bullTrend ? magnetHigh :
     bearTrend ? magnetLow :
     close

var line magnetLine = na
var label magnetLabel = na

if barstate.islast
    if not na(magnetLine)
        line.delete(magnetLine)
    magnetLine := line.new(
         bar_index,
         magnetPrice,
         bar_index + 8,
         magnetPrice,
         extend=extend.right,
         color=color.fuchsia,
         width=2,
         style=line.style_dashed)

    if not na(magnetLabel)
        label.delete(magnetLabel)
    magnetLabel := label.new(
         bar_index,
         magnetPrice,
         "MAGNET",
         style=label.style_label_left,
         color=color.fuchsia,
         textcolor=color.white)

// TEXT VERSION FOR DASHBOARD
nextLiquidityText =
     bullTrend ? str.tostring(nextLiquidityHigh, format.mintick) :
     bearTrend ? str.tostring(nextLiquidityLow, format.mintick) :
     "N/A"

float aiScore = math.round(math.max(buyWeight, sellWeight))

// =====================================================
// DASHBOARD
// =====================================================
var table dash = table.new(position.top_right, 2, 17, border_width=1)

if showDashboard and barstate.islast
    table.cell(dash, 0, 0, "JIGSA GOD MODE", bgcolor=color.black, text_color=color.white)
    table.cell(dash, 1, 0, syminfo.ticker, bgcolor=color.black, text_color=color.white)

    table.cell(dash, 0, 1, "Trend", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 1, trendText, bgcolor=bullTrend ? color.green : bearTrend ? color.red : color.gray)

    table.cell(dash, 0, 2, "RSI", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 2, str.tostring(rsiVal, "#.0"), bgcolor=color.blue)

    table.cell(dash, 0, 3, "Last Pivot High", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 3, na(lastPivotHigh) ? "N/A" : str.tostring(lastPivotHigh, format.mintick), bgcolor=color.red)

    table.cell(dash, 0, 4, "Last Pivot Low", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 4, na(lastPivotLow) ? "N/A" : str.tostring(lastPivotLow, format.mintick), bgcolor=color.green)

    zone_color = inBullOB ? color.green : inBearOB ? color.red : sideways ? color.orange : color.gray
    zone_text =
         inBullOB ? "BUY ZONE (OB)" :
         inBearOB ? "SELL ZONE (OB)" :
         sideways ? "RANGE" :
         "WAIT"

    table.cell(dash, 0, 5, "Zone Bias", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 5, zone_text, bgcolor=zone_color)

    table.cell(dash, 0, 6, "Signal", bgcolor=color.gray, text_color=color.white)

    statusText =
         setupState == 1 and lastDir == "BUY" ? "BUY PENDING" :
         setupState == 1 and lastDir == "SELL" ? "SELL PENDING" :
         setupState == 2 and lastDir == "BUY" ? "BUY FILLED" :
         setupState == 2 and lastDir == "SELL" ? "SELL FILLED" :
         buySignal ? "BUY SETUP" :
         sellSignal ? "SELL SETUP" :
         tradeProbability >= 45 and allowTrading and not newsBlocked ? "SETUP FORMING" :
         "WAIT"

    statusColor =
         setupState == 1 ? color.orange :
         setupState == 2 and lastDir == "BUY" ? color.green :
         setupState == 2 and lastDir == "SELL" ? color.red :
         buySignal ? color.green :
         sellSignal ? color.red :
         color.orange

    table.cell(dash, 1, 6, statusText, bgcolor=statusColor, text_color=color.white)

    table.cell(dash, 0, 7, "Order Type", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 7, orderType, bgcolor=color.orange)

    table.cell(dash, 0, 8, "RR", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 8, str.tostring(riskReward) + "R", bgcolor=color.purple)

    table.cell(dash, 0, 9, "AI Score", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 9, str.tostring(aiScore), bgcolor=color.teal)

    table.cell(dash, 0, 10, "Probability", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 10, str.tostring(tradeProbability) + "%", bgcolor=color.blue)

    table.cell(dash, 0, 11, "Grade", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 11, signalGrade, bgcolor=color.yellow)

    table.cell(dash, 0, 12, "Market Phase", bgcolor=color.gray, text_color=color.white)
    table.cell(dash, 1, 12, phase, bgcolor=color.orange)

    table.cell(dash, 0, 13, "Trend Power", bgcolor=color.gray)
    table.cell(dash, 1, 13, trendPower, bgcolor=color.purple)

    table.cell(dash, 0, 14, "Momentum", bgcolor=color.gray)
    table.cell(dash, 1, 14, marketMomentum, bgcolor=rsiVal > 60 ? color.green : rsiVal < 40 ? color.red : color.orange)

    table.cell(dash, 0, 15, "Next Liquidity", bgcolor=color.gray)
    table.cell(dash, 1, 15, nextLiquidityText, bgcolor=color.teal)

    table.cell(dash, 0, 16, "Magnet Price", bgcolor=color.gray)
    table.cell(dash, 1, 16, str.tostring(magnetPrice, format.mintick), bgcolor=color.fuchsia)

Overview

Optional layers include liquidity sweeps, order blocks, fair value gaps, change of character, London and New York killzones, a silver bullet time filter and chart patterns such as flags and triangles. A dashboard summarises the current setup.

Details

Published by

jigsabersisa on GitHub

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

SMC / ICT / price action, Trend, Sessions & time, Screeners & dashboards

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Fast EMAint50fastEmaLen
Slow EMAint200slowEmaLen
RSI Lengthint14rsiLen
Pivot Lengthint8pivotLen
Zone Height ATR Multiplierfloat0.50zoneAtrMult
Max Zone Age (bars)int250maxZoneAgeBars
Equal High/Low Tolerancefloat0.0008eqTolerancePips
Bullish RSI Confirm >=int52rsiBullMin
Bearish RSI Confirm <=int48rsiBearMax
Risk:Rewardfloat2.0riskReward
Stop ATR Multiplierfloat1.2slAtrMult
Retest Lookback Barsint8retestLookback
Show all 40 settings
SettingTypeDefaultVariable
Projection Barsint18projectionBars
LIVE MODE (Only current signal)booltrueliveMode
Show EMAsbooltrueshowEMAs
Show Pivot S/RboolfalseshowPivotLevels
Show Liquidity SweepsboolfalseshowLiquidity
Show Order BlocksboolfalseshowOrderBlocks
Show Buy/Sell SignalsbooltrueshowSignals
Show Entry / SL / TPbooltrueshowTargets
Show DashboardbooltrueshowDashboard
Show Fair Value Gaps (FVG)boolfalseshowFVG
Show Change of Character (CHoCH)boolfalseshowCHoCH
Highlight Killzones (London/NY)boolfalseshowSessions
Show Descending TrianglesboolfalseshowDescendingTriangles
Show Ascending TrianglesboolfalseshowAscendingTriangles
Show Double Top / BottomboolfalseshowDoublePatterns
Show Bull / Bear FlagsboolfalseshowFlags
Show Head & ShouldersboolfalseshowHS
Enable Silver Bullet FilterbooltrueuseSilverBullet
Max Trades Per Sessionint3maxTradesPerSession
Setup Expiry Barsint12setupExpiryBars
Fresh Retest Barsint2freshRetestBars
Min Risk in ATRfloat0.5minRiskATR
Max Risk in ATRfloat3.0maxRiskATR
Use Manual NY News BlockboolfalseuseManualNewsBlock
News Block 1 (NY)session0830-0845newsBlock1
News Block 2 (NY)session0955-1010newsBlock2
Detect Liquidity TrapsbooltrueshowLiquidityTraps
Liquidity Lookbackint10liqLookback
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This indicator overlays a market structure dashboard on the price chart. It reads up to seven user-selected timeframes, each with an on/off switch and a trend weight, and shows columns for EMA trend, swing highs and lows, structure, order blocks, and fair valu

Indicator v6 Screeners & dashboardsSMC / ICT / price action
Updated 3 months ago · None stated GitHub repository of Market Structure Dashboard | Flux Charts

Auric Sentinel

by arslanahmad429
1 stars

A multi-layer overlay that combines an EMA ribbon with a higher-timeframe EMA and price context, swing-based order blocks, a premium and discount zone, session and volatility filters, and a risk table. Settings choose the EMA lengths, swing bars, invalidation

Indicator v6 SMC / ICT / price actionTrend
Updated 4 months ago · None stated GitHub repository of Auric Sentinel

GOD Conviction Engine

by Oluwacutyp
1 stars

A large all-in-one overlay aimed at gold and Bitcoin charts. It combines trend EMAs, an HMA baseline, an elastic EMA, order blocks, fair value gaps, breaker blocks, liquidity sweeps, an Asian range box, key levels, VWAP, market structure and several tables inc

Indicator v6 SMC / ICT / price actionTrend
Updated 2 weeks ago · Unlicense GitHub repository of GOD Conviction Engine
1 stars

This overlay indicator maps smart-money market structure on the price chart. It labels swing points as higher highs, higher lows, lower highs, and lower lows, and draws Break of Structure and Change of Character lines when structure breaks. A multi-timeframe t

Indicator v6 SMC / ICT / price actionScreeners & dashboards
Updated 4 months ago · None stated GitHub repository of SMC Market Structure + MTF
257 stars

This indicator overlays an intraday SPX and ES chart with a midnight session range, regular-trading-hours opening levels, and a VWAP projection box. It draws the midnight high, mid, and low, flags edge rejections within an absolute tolerance, and plots optiona

Indicator v6 TrendSupport & resistance
Updated 6 weeks ago · None stated GitHub repository of SPX Midnight Box + Snag Logic

Golden Bullet Strategy

by TradersPost
218 stars

The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh

Indicator v6 SMC / ICT / price actionSessions & time
Updated 3 months ago · None stated GitHub repository of Golden Bullet Strategy

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers