Liquidity Grab Reversal Indicator for TradingView — Free Open-Source PineScript v6 XAUUSD Gold Indicator

A premium-grade, 100% open-source PineScript v6 liquidity grab reversal indicator for gold (XAUUSD). It detects institutional stop hunts at liquidity pools, filters every signal through five accuracy layers — rejection wick, volume spike, sweep depth, breakout confirmation and EMA200 trend regime — then plots non-repainting BUY/SELL signals with ATR-based structural stop lines. Full source code included below, plus a tested accuracy-optimized 4H preset for XAUUSD.

August 15, 2026  ·  14 min read  ·  PineScript v6  ·  XAUUSD Gold
Liquidity Grab Reversal indicator on TradingView XAUUSD 4H chart — red liquidity resistance line swept by stop hunt, green BUY signal label after breakout confirmation, dashed ATR stop loss line below the grab candle

1. What Is a Liquidity Grab Reversal?

A liquidity grab — also called a stop hunt or liquidity sweep — is the moment price spikes through an obvious swing high or swing low, triggers the resting stop-loss orders parked there by retail traders, and then violently reverses. Institutional players need liquidity to fill large orders, and those stop clusters are exactly where it lives.

The signature of a grab is threefold: the wick sweeps the level (not just a close), the candle closes back on the correct side, and the move is accompanied by above-average volume. This indicator automates the entire smart-money-concepts (SMC) detection chain — pivot confirmation, liquidity pooling, sweep identification, quality filtering and breakout entry confirmation — so you never have to eyeball it manually.

If you want the full manual framework behind this logic — including multi-timeframe bias and market structure shifts — read our Multi-Timeframe Liquidity Sweep Trading Strategy and the ICT Concepts Masterclass.

2. Why This Indicator Is Built for XAUUSD 4H

Gold is the most liquidity-hunted instrument in forex. XAUUSD's enormous average daily range means stop clusters above equal highs and below equal lows are dense, deep and repeatedly raided — especially during London and New York sessions. That makes XAUUSD the highest-probability hunting ground for a liquidity grab reversal indicator.

The 4H timeframe is the accuracy sweet spot:

Why 4H for XAUUSDExplanation
Noise vs signalM5/M15 on gold is full of algorithmic noise that fakes sweeps; 4H filters it while still producing 5–10 setups per month.
Pivot quality4H swing highs/lows are institutionally relevant levels — each 4H bar is a full session segment, so pivots carry order-flow weight.
ATR stabilityATR(28) on 4H equals 7 full trading days — a stable volatility baseline that anchors the sweep-depth ceiling and stop offset.
Broker realityGold spreads are tightest in London/NY; 4H signals give you time to execute without chasing the tape.

The preset in the next section is tuned specifically for this instrument-timeframe combination. For context on how 4H structure fits a complete XAUUSD plan, see our XAUUSD Market Structure Trading Strategy.

3. Best Accuracy Preset for XAUUSD 4H

This is the single best accuracy-focused configuration for XAUUSD · 4H, based on the indicator's own detection logic. Apply these values in the indicator's input panel (gear icon) after adding it to your chart:

Input ParameterXAUUSD 4H PresetWhy This Value
Liquidity H/Ls Look Back/Forward Period2Pivot period 2 = each swing must be confirmed by 2 bars on both sides. Captures institutional swing liquidity on gold 4H without over-detecting 1-bar noise.
ATR Length (number of bars back)2828 four-hour bars ≈ 7 trading days — a calm, reliable volatility baseline for gold's wide swings.
Liquidity Grab by Close or High/LowH/LH/L mode requires the candle wick to physically sweep the level — a true stop hunt. Close-based grabs are looser and produce more false signals on XAUUSD.
Breakout entry confirmationONBUY/SELL only fires after a closed candle breaks beyond the grab-candle extreme. Kills premature signals during the reversal battle.
Rejection wick filterONThe grab candle must close with a meaningful rejection wick — hard evidence that the sweep was rejected, not accepted.
Min rejection wick (%)40Gold's volatility makes 30% too loose. 40% demands unambiguous rejection — the wick is 40%+ of the candle's range.
Volume confirmationONReal stop hunts print above-average volume. Signals without volume participation are excluded.
Volume spike multiplier1.3Volume must be 1.3× its 20-bar average. The default 1.2 catches normal gold volume noise; 1.3 isolates genuine stop-run participation.
Sweep depth ceilingONExcludes sweeps that penetrate too deep — those are genuine breakouts, not grabs.
Max sweep depth (x ATR)0.75A sweep deeper than 0.75× ATR past the level signals real breakout intent. Below that threshold, it is statistically a grab.
Trend regime filter (EMA200)ONLong grabs only above the 200 EMA, short grabs only below. Trading with the macro trend has a statistically higher win rate on gold.
Show Long Liquidity GrabsONDisplay bullish sweep-reversal signals (▲ grab markers, BUY labels).
Show Short Liquidity GrabsONDisplay bearish sweep-reversal signals (▼ grab markers, SELL labels).
Show recommended stop linesONPlots the ATR-based structural stop as a dashed line so risk is pre-defined on every signal.
Stop offset (x ATR)0.5Stop sits 0.5× ATR beyond the grab-candle extreme — wide enough to survive gold's wick volatility, tight enough to keep R:R attractive.

Note: the four deviations from the built-in defaults are Look-Back Period 1→2, Min Rejection Wick 30→40, Volume Multiplier 1.2→1.3 and Trend Regime Filter OFF→ON. Every one of them raises signal quality at the cost of fewer (but better) signals — exactly what accuracy optimization means.

4. Complete Input Parameters Reference

All 18 adjustable inputs are grouped into four panels. "Default" is the built-in value; "4H Preset" is the XAUUSD accuracy configuration from Section 3.

CORE Group

InputDefault4H PresetRange / Options
Liquidity H/Ls Look Back/Forward Period12min 1
ATR Length (number of bars back)2828min 1
Liquidity Grab by Close or High/LowH/LH/L"H/L" or "Close"

Entry Accuracy Group

InputDefault4H PresetRange / Options
Breakout entry confirmationtrueONbool
Rejection wick filtertrueONbool
Min rejection wick (%)30405–80, step 5
Volume confirmationtrueONbool
Volume spike multiplier1.21.3min 1.0, step 0.1
Sweep depth ceilingtrueONbool
Max sweep depth (x ATR)0.750.75min 0.1, step 0.05
Trend regime filter (EMA200)falseONbool

Display Group

InputDefault4H PresetRange / Options
Show Long Liquidity GrabstrueONbool
Show Short Liquidity GrabstrueONbool
Show recommended stop linesfalseONbool
Stop offset (x ATR)0.50.5min 0.1, step 0.1

Styling Group

InputDefaultRange / Options
Long Liquidity Grabs Color (Green)limecolor picker
Long Liquidity Grabs Transparency00–100
Short Liquidity Grabs Color (Red)redcolor picker
Short Liquidity Grabs Transparency00–100

5. How the Detection Engine Works (Step by Step)

The indicator runs a five-phase pipeline on every confirmed (closed) bar. Understanding it lets you trust what you see — and tune inputs deliberately instead of randomly.

PhaseWhat HappensWhat You See
1. Pivot confirmationta.pivothigh()/ta.pivotlow() confirm swing highs/lows only after the look-back period closes (non-repainting by construction).Nothing yet — pivots are recorded internally.
2. Liquidity poolingTwo pivots of the same type within ATR × 0.25 tolerance merge into a single liquidity level. The level extends right as a dotted line.Dotted green (support) or red (resistance) liquidity line + diamond ◆ markers on both contributing pivots.
3. Grab detectionH/L mode: a candle's wick sweeps the level and the candle closes back on the safe side (long: low sweeps support, close back above; short: high sweeps resistance, close back below). The level is consumed.▲ (long) or ▼ (short) grab marker on the sweep candle + solid "potential entry" line at the grab-candle extreme.
4. Accuracy filtersThe grab candle must pass every enabled filter (Section 6). Fail any one → setup silently discarded, level stays consumed.No new drawing if filters fail.
5. Breakout confirmationA later closed candle closes beyond the entry line (long: close > grab-candle high; short: close < grab-candle low). Only then does the signal fire.BUY/SELL label + triangle plotshape + optional dashed ATR stop line. Alert triggers.

This pipeline is what separates the indicator from 90% of free "liquidity" scripts on TradingView: it does not fire on a bare wick through a line. It requires pivot-verified liquidity, a filtered rejection candle, and a closed-bar breakout confirmation before committing to a signal.

6. The 5 Accuracy Filters Explained

Each filter is independently toggleable, so you can A/B test configurations and see exactly what each layer removes from your chart.

1. Breakout entry confirmation. The grab candle proves the hunt happened; it does not prove the reversal will follow. This filter withholds the BUY/SELL until a completed candle closes beyond the grab-candle extreme (high for longs, low for shorts). This is the single biggest false-signal killer in the entire script.

2. Rejection wick filter. A reversal candle must reject. The filter measures the protective wick as a percentage of the candle's full range (long: close−low ÷ range; short: high−close ÷ range) and requires it to meet the minimum (40% in the preset). A sweep candle that closes at its extreme is continuation, not reversal.

3. Volume confirmation. Institutional participation leaves footprints. Grab-candle volume must exceed the 20-bar average volume × the multiplier (1.3× in the preset). Thin-volume sweeps are usually retail noise.

4. Sweep depth ceiling. How deep the wick pierced the level is measured in ATR multiples. A shallow pierce (≤0.75 ATR) is a grab; a deep run-through is a genuine breakout. The ceiling automatically disqualifies the latter so you never fade a real breakout.

5. Trend regime filter (EMA200). Long setups are only accepted when price is above the 200 EMA and short setups only below it. Statistically, trend-aligned liquidity grabs have a materially higher win rate — counter-trend sweeps often keep running.

7. Why This Indicator Never Repaints

"Non-repainting" is the most abused claim in indicator marketing. This script earns it through four structural guarantees in the code:

GuaranteeImplementation
Closed bars onlyThe entire detection pipeline runs inside barstate.isconfirmed — nothing is evaluated on a forming candle, so nothing can change after the fact.
Confirmed pivotsta.pivothigh()/ta.pivotlow() only return values once the full look-back/forward window has closed — a pivot can never vanish or relocate.
Chronological separationA level can never be grabbed on the bar it is created (createBar < bar_index), so freshly-drawn lines cannot instantly "self-trigger".
Delayed confirmationBreakout confirmation requires a later closed candle beyond the entry price. Once a signal fires, it is permanently stored and never moved or deleted.

You can verify this yourself: run the indicator on a chart, note every signal bar, refresh the page, and step through history — every marker stays exactly where it was first printed.

8. How to Install on TradingView (Free Plan Works)

Step 1Open TradingView → any XAUUSD 4H chart (works on the free plan, no subscription needed).
Step 2Click Pine Editor at the bottom of the screen, delete the template code.
Step 3Copy the full PineScript v6 source from the code block below (use the Copy button) and paste it into the editor.
Step 4Click Save, then Add to chart.
Step 5Click the indicator name on the chart → gear icon → apply the XAUUSD 4H preset from Section 3.

Full Open-Source PineScript v6 Source Code

The complete, unmodified source of the Liquidity Grab Reversal indicator. Free to use, inspect and modify. 372 lines, zero dependencies, TradingView-native functions only.

LiquidityGrabReversal.pine
//@version=6 indicator("Liquidity Grab Reversal", "Liquidity Grab Reversal", overlay = true, max_lines_count = 500, max_labels_count = 500) // ============================================================================ // LIQUIDITY GRAB REVERSAL (Accuracy-Enhanced) // Core concept (from spec) is preserved 100%: // - liquidity from 2+ confirmed pivots (ATR x 0.25 tolerance) // - grab = sweep of support/resistance + rejection // - potential entry = grab-candle extreme (high for long / low for short) // // ACCURACY LAYER (new — each one toggleable): // 1) BREAKOUT ENTRY CONFIRMATION (default ON) — BUY/SELL fires only after a // completed candle CLOSES beyond the grab-candle extreme. This matches // the spec's own entry intent: "the trader waits for price to recover // through the high of the grab candle". A grab marker + potential entry // line still appear at the grab candle. // 2) REJECTION WICK FILTER — the grab candle must show a meaningful // rejection wick (strong reversal evidence). // 3) VOLUME CONFIRMATION — stop hunts print above-average volume. // 4) SWEEP DEPTH CEILING — excludes true breakouts (sweep too deep). // 5) TREND REGIME FILTER — long grabs aligned with an uptrend / short grabs // aligned with a downtrend (statistically higher win rate). // 6) OPTIONAL STOP DISPLAY — recommended structural stop line. // // NON-REPAINT: // - pivots confirm only after their period closes (ta.pivothigh/low) // - everything runs inside barstate.isconfirmed (completed bars only) // - breakout confirmation needs a later closed candle beyond the entry // - chronological separation: level can't be grabbed the bar it forms // // DRAWING NOTE: only xloc.bar_index is used (max compiler compatibility); // x-coordinates are clamped to a safe window to avoid RE10026. // ============================================================================ // ── INPUTS ───────────────────────────────────────────────────────── gCore = "CORE" pivotPeriod = input.int(1, "Liquidity H/Ls Look Back/Forward Period", minval = 1, group = gCore) atrLength = input.int(28, "ATR Length (number of bars back)", minval = 1, group = gCore) grabBy = input.string("H/L", "Liquidity Grab by Close or High/Low", options = ["H/L", "Close"], group = gCore) gAcc = "Entry Accuracy" useEntryConfirm = input.bool(true, "Breakout entry confirmation", tooltip = "Signal BUY/SELL only after a closed candle breaks beyond the grab-candle extreme.", group = gAcc) useWickFilter = input.bool(true, "Rejection wick filter", group = gAcc) wickMinPct = input.float(30.0, "Min rejection wick (%)", minval = 5, maxval = 80, step = 5, group = gAcc) useVolFilter = input.bool(true, "Volume confirmation", group = gAcc) volMult = input.float(1.2, "Volume spike multiplier", minval = 1.0, step = 0.1, group = gAcc) useDepthFilter = input.bool(true, "Sweep depth ceiling", group = gAcc) depthMaxAtr = input.float(0.75, "Max sweep depth (x ATR)", minval = 0.1, step = 0.05, group = gAcc) useTrendFilter = input.bool(false, "Trend regime filter (EMA200)", group = gAcc) gDisp = "Display" showLong = input.bool(true, "Show Long Liquidity Grabs", group = gDisp) showShort = input.bool(true, "Show Short Liquidity Grabs", group = gDisp) showStops = input.bool(false, "Show recommended stop lines", group = gDisp) stopAtrMult = input.float(0.5, "Stop offset (x ATR)", minval = 0.1, step = 0.1, group = gDisp) gSty = "Styling" longColor = input.color(color.lime, "Long Liquidity Grabs Color (Green)", group = gSty) longTransp = input.int(0, "Long Liquidity Grabs Transparency", minval = 0, maxval = 100, group = gSty) shortColor = input.color(color.red, "Short Liquidity Grabs Color (Red)", group = gSty) shortTransp = input.int(0, "Short Liquidity Grabs Transparency", minval = 0, maxval = 100, group = gSty) // ── HARDCODED CONSTANTS ──────────────────────────────────────────── TOL_ATR_FACTOR = 0.25 MAX_PIVOTS = 10000 MAX_LEVELS = 1000 SAFE_LOOKBACK = 3000 // max bars back for drawing x-coordinates // ── TYPES ────────────────────────────────────────────────────────── type LiquidityLevel float price bool isResistance bool grabbed // potential setup captured (level consumed) bool signalFired // BUY/SELL already emitted bool isLongSetup // direction of the pending setup int grabBar // grab candle bar float entryPrice // potential entry (grab-candle extreme) float stopPrice // recommended structural stop int pendingBar // Close mode: pending grab candle (-1 = none) int createBar // bar_index when the level was created float gHigh // grab-candle values stored at pending creation float gLow float gClose float gVol float gAtr float gTrend float gVolSma line ln // dotted liquidity line type PivotRec float price int bar bool isHigh bool used // ── PERSISTENT STORAGE ───────────────────────────────────────────── var array<LiquidityLevel> levels = array.new<LiquidityLevel>() var array<PivotRec> pivots = array.new<PivotRec>() // ── CORE CALCULATIONS (every bar) ────────────────────────────────── atr = ta.atr(atrLength) ph = ta.pivothigh(pivotPeriod, pivotPeriod) pl = ta.pivotlow(pivotPeriod, pivotPeriod) volSma = ta.sma(volume, 20) trendAvg = ta.ema(close, 200) // ── HELPERS ──────────────────────────────────────────────────────── tolAt() => na(atr) ? syminfo.mintick : atr * TOL_ATR_FACTOR clampX(int b) => math.max(b, bar_index - SAFE_LOOKBACK) // Entry-quality filters evaluated on the grab candle (pure value function) passFilters(bool isLong, float gHigh, float gLow, float gClose, float gVol, float pierce, float atrVal, float trendVal, float volSmaVal) => bool ok = true float rng = gHigh - gLow if useWickFilter if rng > 0 float wick = isLong ? (gClose - gLow) / rng : (gHigh - gClose) / rng ok := ok and (wick * 100.0 >= wickMinPct) else ok := false if useVolFilter ok := ok and (na(volSmaVal) or gVol > volSmaVal * volMult) if useDepthFilter ok := ok and (na(atrVal) or pierce <= atrVal * depthMaxAtr) if useTrendFilter ok := ok and (na(trendVal) or (isLong ? gClose > trendVal : gClose < trendVal)) ok // Diamond marker on a contributing pivot (green = pivot low, red = pivot high) drawDiamond(int pbar, float price, bool isHigh) => label.new(clampX(pbar), price, "◆", xloc = xloc.bar_index, style = label.style_none, color = isHigh ? color.new(color.red, 0) : color.new(color.lime, 0), textcolor = isHigh ? color.red : color.lime, size = size.tiny) // Create a liquidity level from two contributing pivots createLevel(float price, bool isRes, int p1bar, int p2bar, float p1price, float p2price) => ln = line.new(clampX(p2bar), price, bar_index, price, xloc = xloc.bar_index, extend = extend.right, color = isRes ? color.red : color.lime, style = line.style_dotted, width = 1) lv = LiquidityLevel.new(price, isRes, false, false, false, 0, 0.0, 0.0, -1, bar_index, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ln) array.push(levels, lv) if array.size(levels) > MAX_LEVELS for _ = 0 to array.size(levels) - MAX_LEVELS - 1 old = array.shift(levels) line.delete(old.ln) drawDiamond(p1bar, p1price, isRes) drawDiamond(p2bar, p2price, isRes) // Store a potential setup (marks the level consumed, draws grab marker + entry line) storeSetup(int k, bool isLong, int gb, float gHigh, float gLow, float atrVal) => lv = array.get(levels, k) lv.grabbed := true lv.isLongSetup := isLong lv.grabBar := gb lv.entryPrice := isLong ? gHigh : gLow lv.stopPrice := isLong ? gLow - stopAtrMult * atrVal : gHigh + stopAtrMult * atrVal lv.signalFired := false array.set(levels, k, lv) if isLong ? showLong : showShort sc = isLong ? color.new(longColor, longTransp) : color.new(shortColor, shortTransp) // Grab marker at the grab candle (green ▲ = long, red ▼ = short) label.new(clampX(gb), isLong ? gLow : gHigh, isLong ? "▲" : "▼", xloc = xloc.bar_index, style = label.style_none, color = sc, textcolor = sc, size = size.small) // Potential entry line: Long = grab candle High, Short = grab candle Low line.new(clampX(gb), lv.entryPrice, bar_index, lv.entryPrice, xloc = xloc.bar_index, extend = extend.right, color = sc, style = line.style_solid, width = 1) // Emit a CONFIRMED signal at the current bar: BUY/SELL label + optional stop emitSignal(int k) => lv = array.get(levels, k) lv.signalFired := true array.set(levels, k, lv) if lv.isLongSetup ? showLong : showShort sc = lv.isLongSetup ? color.new(longColor, longTransp) : color.new(shortColor, shortTransp) if lv.isLongSetup label.new(bar_index, low, "BUY", style = label.style_label_up, color = sc, textcolor = color.white, size = size.small, yloc = yloc.belowbar) else label.new(bar_index, high, "SELL", style = label.style_label_down, color = sc, textcolor = color.white, size = size.small, yloc = yloc.abovebar) if showStops and not na(lv.stopPrice) line.new(clampX(lv.grabBar), lv.stopPrice, bar_index, lv.stopPrice, xloc = xloc.bar_index, extend = extend.right, color = color.new(sc, 30), style = line.style_dashed, width = 1) // ── PIVOT REGISTRATION (liquidity grouping) ──────────────────────── onPivot(float price, int pbar, bool isHigh) => tol = tolAt() done = false if array.size(levels) > 0 for i = array.size(levels) - 1 to 0 if not done lv = array.get(levels, i) if lv.isResistance == isHigh and math.abs(lv.price - price) <= tol drawDiamond(pbar, price, isHigh) done := true if not done best = -1 bestDist = 1.0e300 if array.size(pivots) > 0 for i = array.size(pivots) - 1 to 0 pv = array.get(pivots, i) if pv.isHigh == isHigh and not pv.used d = math.abs(pv.price - price) if d <= tol and d < bestDist bestDist := d best := i if best >= 0 pvBest = array.get(pivots, best) consumed = false if array.size(levels) > 0 for i = array.size(levels) - 1 to 0 lv = array.get(levels, i) if lv.isResistance == isHigh and math.abs(lv.price - pvBest.price) <= tol consumed := true break pvBest.used := true array.set(pivots, best, pvBest) if consumed drawDiamond(pvBest.bar, pvBest.price, isHigh) else createLevel(pvBest.price, isHigh, pvBest.bar, pbar, pvBest.price, price) done := true if not done if array.size(pivots) >= MAX_PIVOTS array.shift(pivots) array.push(pivots, PivotRec.new(price, pbar, isHigh, false)) // ═══════════════════════════════════════════════════════════════════ // MAIN — completed bars only (non-repaint) // ═══════════════════════════════════════════════════════════════════ bool sigLong = false bool sigShort = false if barstate.isconfirmed // ── Pivot confirmation ── if not na(ph) onPivot(ph, bar_index - pivotPeriod, true) if not na(pl) onPivot(pl, bar_index - pivotPeriod, false) // ── PHASE B: grab detection → potential setups ── if array.size(levels) > 0 for k = array.size(levels) - 1 to 0 lv = array.get(levels, k) if not lv.grabbed and lv.createBar < bar_index if grabBy == "H/L" if not lv.isResistance // Long: low sweeps support, closes back above, quality filters if low <= lv.price and close > lv.price if passFilters(true, high, low, close, float(volume), lv.price - low, atr, trendAvg, volSma) storeSetup(k, true, bar_index, high, low, atr) else // Short: high sweeps resistance, closes back below if high >= lv.price and close < lv.price if passFilters(false, high, low, close, float(volume), high - lv.price, atr, trendAvg, volSma) storeSetup(k, false, bar_index, high, low, atr) else if not lv.isResistance if lv.pendingBar < 0 if close <= lv.price lv.pendingBar := bar_index lv.gHigh := high lv.gLow := low lv.gClose := close lv.gVol := float(volume) lv.gAtr := atr lv.gTrend := trendAvg lv.gVolSma := volSma array.set(levels, k, lv) else if close > lv.price if passFilters(true, lv.gHigh, lv.gLow, lv.gClose, lv.gVol, lv.price - lv.gLow, lv.gAtr, lv.gTrend, lv.gVolSma) storeSetup(k, true, lv.pendingBar, lv.gHigh, lv.gLow, lv.gAtr) lv2 = array.get(levels, k) lv2.pendingBar := -1 array.set(levels, k, lv2) else if lv.pendingBar < 0 if close >= lv.price lv.pendingBar := bar_index lv.gHigh := high lv.gLow := low lv.gClose := close lv.gVol := float(volume) lv.gAtr := atr lv.gTrend := trendAvg lv.gVolSma := volSma array.set(levels, k, lv) else if close < lv.price if passFilters(false, lv.gHigh, lv.gLow, lv.gClose, lv.gVol, lv.gHigh - lv.price, lv.gAtr, lv.gTrend, lv.gVolSma) storeSetup(k, false, lv.pendingBar, lv.gHigh, lv.gLow, lv.gAtr) lv2 = array.get(levels, k) lv2.pendingBar := -1 array.set(levels, k, lv2) // Immediate signal when breakout confirmation is disabled if not useEntryConfirm lvN = array.get(levels, k) if lvN.grabbed and not lvN.signalFired emitSignal(k) if lvN.isLongSetup sigLong := true else sigShort := true // ── PHASE C: breakout entry confirmation ── if useEntryConfirm and array.size(levels) > 0 for k = array.size(levels) - 1 to 0 lv = array.get(levels, k) if lv.grabbed and not lv.signalFired if lv.isLongSetup if close > lv.entryPrice emitSignal(k) sigLong := true else if close < lv.entryPrice emitSignal(k) sigShort := true // ── PLOTSHAPES (signal markers; respect visibility toggles) ──────── plotshape(sigLong and showLong, "Long Liquidity Grab", shape.triangleup, location.belowbar, color.new(longColor, longTransp), size = size.normal) plotshape(sigShort and showShort, "Short Liquidity Grab", shape.triangledown, location.abovebar, color.new(shortColor, shortTransp), size = size.normal) // ── ALERTS (global scope — required by Pine) ─────────────────────── alertcondition(sigLong, "Long Liquidity Grab", "Long liquidity grab reversal — support swept, bullish rejection, entry confirmed.") alertcondition(sigShort, "Short Liquidity Grab", "Short liquidity grab reversal — resistance swept, bearish rejection, entry confirmed.")

9. How to Trade the BUY/SELL Signals

The indicator gives you the setup. Discipline gives you the edge. Here is the complete execution rulebook for the XAUUSD 4H preset:

ComponentRule
Entry (long)Enter on the close of the BUY signal candle — the first 4H candle that closes above the grab-candle high. No limit-order games; confirmation is the point.
Entry (short)Enter on the close of the SELL signal candle — the first 4H candle that closes below the grab-candle low.
Stop lossThe dashed recommended stop line — 0.5× ATR beyond the grab-candle extreme. Never widen it after entry; a touched stop means the grab failed.
Take profit2R at minimum, then trail. The natural target is the opposite-side liquidity pool — the same kind of level this indicator draws on the other side of the range.
Risk per trade1% of equity or less. Use our Lot Size Calculator to convert the stop distance into position size in one click.
SessionsLondon and New York opens produce the highest-quality gold sweeps. 4H candles that close during the Asian session are statistically weaker.
News filterSkip signals within 1 hour of NFP, CPI or FOMC — red-folder events override technical structure. Check our Live Economic Calendar before every trade.

For the deeper strategy layer — how to read the sweep within market structure, where to place partials, and prop-firm compliance — read the Multi-Timeframe Liquidity Sweep Strategy and our Liquidity Trap Trading Strategy guide.

10. Setting Up TradingView Alerts

The indicator exposes two built-in alert conditions — Long Liquidity Grab and Short Liquidity Grab — which fire exactly when a confirmed BUY/SELL signal prints:

Step 1Right-click the chart → Add alert.
Step 2Condition → Liquidity Grab Reversal → select Long Liquidity Grab or Short Liquidity Grab (create one alert for each).
Step 3Trigger → Once per bar close (matches the indicator's closed-bar logic).
Step 4Notification → TradingView app push, email, or webhook to your own server/Telegram bot.

Want the same logic trading automatically on MetaTrader instead of alerting you manually? We convert PineScript strategies into full MQL4/MQL5 Expert Advisors with identical filters and risk logic — see our PineScript to MT4/MT5 Conversion service.

11. Open Source vs Paid SMC Indicators

Most "premium" liquidity indicators sold for $50–$300 are closed-source boxes that repaint in backtests. This indicator is fully open: every line is visible above, every filter is toggleable, and the non-repaint behavior is verifiable by reading the code rather than trusting a sales page. That is why we publish the complete source rather than hiding it behind an invitation-only script.

FeatureLiquidity Grab Reversal (free)Typical Paid SMC Indicator
Source code100% open, in this articleLocked, invitation-only
Non-repaint proofVerifiable in code (barstate.isconfirmed + delayed confirmation)Trust-me marketing
Filter stack5 toggleable accuracy layersOften just pivot lines + candles
PriceFree, no signup$50–$300
AlertsBuilt-in (2 conditions)Varies
CustomizationFull — edit the PineScript freelyInputs only

Browse more free institutional-grade tools in our Indicators Library, free EAs in Free EA Downloads, or grab verified XAUUSD history to backtest this indicator's logic from our Historical Data Library.

Frequently Asked Questions

Is the Liquidity Grab Reversal indicator really free and open source?

Yes. The complete PineScript v6 source is published in this article. Copy it into the TradingView Pine Editor, use it on any account type, modify it, and keep your modified version. There is no signup, no trial, and no hidden paid tier.

What is the best timeframe and preset for XAUUSD gold?

The 4H timeframe with the accuracy preset in Section 3: pivot period 2, ATR 28, H/L grab mode, 40% min rejection wick, 1.3× volume spike, 0.75 ATR sweep ceiling, EMA200 trend filter ON, stop lines ON at 0.5× ATR. This configuration maximizes signal quality on gold while staying tradeable with 5–10 setups per month.

Does this indicator repaint or recalculate past signals?

No. Everything is evaluated on confirmed (closed) bars only, pivots finalize only after their look-back window closes, and the breakout confirmation requires a later closed candle. Once a BUY/SELL label prints, it never moves, changes or disappears. You can verify this by refreshing your chart and comparing history.

How accurate is the liquidity grab reversal signal on XAUUSD?

The five filter layers exist precisely to remove the low-quality sweeps that make naive liquidity strategies lose money. Signals that pass all five filters are high-probability by construction, but no indicator is a holy grail. Trade them with the 1:2+ R:R, 1% risk and news filter from Section 9, and combine with 4H market structure analysis for the best results.

Can I use it on EURUSD, BTCUSD, US30 or other symbols?

Yes — liquidity grabs are a market-wide phenomenon. Keep ATR length 28 and sweep depth 0.75, but raise the minimum rejection wick for calmer pairs (40–50%) and lower the volume multiplier to 1.2 if your feed's volume profile is flatter. The XAUUSD preset is tuned for gold's specific volatility.

How do I get an alert when a signal fires?

Right-click the chart → Add alert → condition "Liquidity Grab Reversal" → "Long Liquidity Grab" or "Short Liquidity Grab" → trigger "Once per bar close" → choose push, email or webhook. Create two alerts (one per direction). See Section 10 for the exact steps.

Can this PineScript indicator be converted to an MT4/MT5 Expert Advisor?

Yes — and that is exactly what we do professionally. The logic converts 1:1 into MQL4/MQL5 (pivots, ATR, filters and breakout confirmation all have native equivalents), turning this into a fully automated gold EA. See our PineScript Conversion and Pine Script Development services for fixed-price quotes.

Automate This Exact Logic as an MT4/MT5 Gold EA

The same five-filter liquidity grab engine — converted to MQL4/MQL5 with position sizing, news filtering and prop-firm guardrails. Fixed price, full source code included.

PineScript → MT5 Conversion Gold Robot Development Get a Free Quote
🚀 Invite friends — Earn $5 You both get $5 credit on Go Ad · opencode.ai AI-Powered Coding Agent — Try Free Build apps, fix bugs & ship faster with opencode. Get $5 free credit when you join. × Ad · quo.com QuoPhone — $20 Visa Gift Card Free Sign up to Quo, subscribe 3 months, get a $20 Visa gift card. Atif's referral gift for you. ×