This indicator is a ProBuilder adaptation of the “RSI Liquidity Sweep Confluence Engine [PhenLabs]” pinescript. It fuses three ideas that usually live in separate tools into a single price overlay that only speaks up when they all agree.
Instead of reading the RSI in its own sub-window, the engine turns it into a source of dynamic support and resistance on price, watches for liquidity sweeps at swing pools, and fires a signal only when a sweep lands on an RSI-derived level and volume confirms. The result is a low-noise overlay: two smoothed S/R lines with a channel fill, plus clean BULL/BEAR markers at full-confluence bars.
RSI turned into price levels. Pivots are detected on the RSI series (not on price). Each time the RSI prints a pivot high, the high of that pivot bar is stored as a resistance level; each RSI pivot low stores the low as a support level. Only the most recent keepLevels levels per side are kept, in a rolling FIFO buffer.
Nearest active level. On every bar the engine scans the buffers for the resistance closest above the close and the support closest below it. These two values are persistent: when no level sits on the right side of price, the last known one is retained, so the lines never flicker to nothing.
Liquidity pools and sweeps. The swing high and low over sweepLookback bars (excluding the current bar, to avoid lookahead) define the liquidity pools. A bullish sweep is a wick below the low pool; a bearish sweep is a wick above the high pool. With sweepCloseBack enabled, the candle must also close back inside the pool — the classic stop-hunt reversal footprint.
Confluence gating. A raw sweep is not a signal. It becomes one only when:
Both filters are individually switchable (set the parameter to 0 to disable). Only when sweep + level + volume align does a BULL or BEAR signal print — on closed bars, with no repaint.
Display. The nearest resistance and support are smoothed with a short WMA and drawn as two lines with a soft channel fill between them. Each signal drops a label and a dotted segment across the swept pool.
//--------------------------------------------------------//
// PRC_RSI Liquidity Sweep Confluence Engine (by PhenLabs)
// version = 0
// 13.07.2026
// Ivan Gonzalez @ www.prorealcode.com
// Sharing ProRealTime knowledge
//--------------------------------------------------------//
// Overlay on the price chart.
// Fuses RSI-derived dynamic S/R levels + liquidity sweep + volume
// confluence gating. Signals fire ONLY on full confluence (closed bars).
// ===== Inputs =====
rsiLen = 14 // RSI length for dynamic S/R
pivotLeft = 5 // RSI pivot left bars
pivotRight = 5 // RSI pivot right bars
keepLevels = 4 // active RSI S/R levels kept (max 10)
smoothLen = 3 // level smoothing (WMA)
sweepLookback = 20 // liquidity pool lookback
sweepCloseBack = 1 // require close-back inside swept level (1/0)
levelTol = 0.30 // RSI level tolerance (ATR multiple; 0 disables)
volMult = 1.20 // volume multiplier (0 disables)
volLen = 20 // volume SMA length
atrLen = 14 // ATR length
showChannel = 1 // show S/R channel fill (1/0)
// ===== Colors (R,G,B) =====
bullR = 38
bullG = 166
bullB = 154
bearR = 239
bearG = 83
bearB = 80
chanR = 155
chanG = 140
chanB = 247
poolR = 50
poolG = 50
poolB = 222
// ===== Core calculation =====
rsiV = rsi[rsiLen](close)
atrV = averagetruerange[atrLen](close)
volSma = average[volLen](volume)
IF volMult <= 0 THEN
volOk = 1
ELSIF volSma <= 0 THEN
volOk = 0
ELSIF volume >= volSma * volMult THEN
volOk = 1
ELSE
volOk = 0
ENDIF
// ===== State init =====
IF barindex = 0 THEN
nRes = 0
nSup = 0
haveRes = 0
haveSup = 0
nearestRes = undefined
nearestSup = undefined
ENDIF
// ===== RSI pivots -> price S/R levels (FIFO, keep newest keepLevels) =====
win = pivotLeft + pivotRight + 1
IF barindex >= pivotLeft + pivotRight THEN
// pivot high on RSI => resistance anchored at high[pivotRight]
IF rsiV[pivotRight] = highest[win](rsiV) THEN
IF nRes >= keepLevels THEN
FOR i = 1 TO nRes - 1 DO
$resLvl[i] = $resLvl[i+1]
NEXT
nRes = nRes - 1
ENDIF
nRes = nRes + 1
$resLvl[nRes] = high[pivotRight]
ENDIF
// pivot low on RSI => support anchored at low[pivotRight]
IF rsiV[pivotRight] = lowest[win](rsiV) THEN
IF nSup >= keepLevels THEN
FOR i = 1 TO nSup - 1 DO
$supLvl[i] = $supLvl[i+1]
NEXT
nSup = nSup - 1
ENDIF
nSup = nSup + 1
$supLvl[nSup] = low[pivotRight]
ENDIF
ENDIF
// ===== Nearest RSI resistance above close / support below close (persistent) =====
haveFreshR = 0
freshRes = 0
IF nRes > 0 THEN
FOR i = 1 TO nRes DO
lvlR = $resLvl[i]
IF lvlR >= close THEN
IF haveFreshR = 0 THEN
freshRes = lvlR
haveFreshR = 1
ELSIF abs(lvlR - close) < abs(freshRes - close) THEN
freshRes = lvlR
ENDIF
ENDIF
NEXT
ENDIF
IF haveFreshR = 1 THEN
nearestRes = freshRes
haveRes = 1
ENDIF
haveFreshS = 0
freshSup = 0
IF nSup > 0 THEN
FOR i = 1 TO nSup DO
lvlS = $supLvl[i]
IF lvlS <= close THEN
IF haveFreshS = 0 THEN
freshSup = lvlS
haveFreshS = 1
ELSIF abs(lvlS - close) < abs(freshSup - close) THEN
freshSup = lvlS
ENDIF
ENDIF
NEXT
ENDIF
IF haveFreshS = 1 THEN
nearestSup = freshSup
haveSup = 1
ENDIF
// ===== Liquidity pools (swing high/low over lookback, exclude current bar) =====
swHigh = highest[sweepLookback](high)[1]
swLow = lowest[sweepLookback](low)[1]
// ===== Sweep detection: wick beyond pool then (optionally) close back inside =====
bullSweep = 0
IF low < swLow THEN
IF sweepCloseBack = 0 OR close > swLow THEN
bullSweep = 1
ENDIF
ENDIF
bearSweep = 0
IF high > swHigh THEN
IF sweepCloseBack = 0 OR close < swHigh THEN
bearSweep = 1
ENDIF
ENDIF
// ===== Confluence with RSI S/R level (tolerance in ATR units) =====
tol = atrV * levelTol
supConf = 0
IF haveSup = 1 THEN
IF levelTol <= 0 OR abs(low - nearestSup) <= tol THEN
supConf = 1
ENDIF
ENDIF
resConf = 0
IF haveRes = 1 THEN
IF levelTol <= 0 OR abs(high - nearestRes) <= tol THEN
resConf = 1
ENDIF
ENDIF
// ===== Full confluence signals =====
bullSignal = 0
IF bullSweep = 1 AND supConf = 1 AND volOk = 1 THEN
bullSignal = 1
ENDIF
bearSignal = 0
IF bearSweep = 1 AND resConf = 1 AND volOk = 1 THEN
bearSignal = 1
ENDIF
// ===== Smoothed display levels (WMA) =====
IF haveRes = 1 THEN
smR = average[smoothLen,2](nearestRes)
ELSE
smR = undefined
ENDIF
IF haveSup = 1 THEN
smS = average[smoothLen,2](nearestSup)
ELSE
smS = undefined
ENDIF
// ===== Channel fill between smoothed S/R lines =====
IF showChannel = 1 THEN
colorbetween(smR, smS, chanR, chanG, chanB, 30)
ENDIF
// ===== Signal markers (fixed-X on the event bar, like arrows) =====
IF bullSignal = 1 THEN
drawtext("BULL", barindex, low - atrV * 1.6) coloured(bullR, bullG, bullB)
drawarrowup(barindex, low - atrV * 0.6) coloured(bullR, bullG, bullB)
drawsegment(barindex - 2, swLow, barindex + 5, swLow) coloured(poolR, poolG, poolB, 200) STYLE(dottedline2,2)
ENDIF
IF bearSignal = 1 THEN
drawtext("BEAR", barindex, high + atrV * 1.6) coloured(bearR, bearG, bearB)
drawarrowdown(barindex, high + atrV * 0.6) coloured(bearR, bearG, bearB)
drawsegment(barindex - 2, swHigh, barindex + 5, swHigh) coloured(poolR, poolG, poolB, 200) STYLE(dottedline2,2)
ENDIF
RETURN smR COLOURED(bearR, bearG, bearB) STYLE(line, 1) AS "RSI Res", smS COLOURED(bullR, bullG, bullB) STYLE(line, 1) AS "RSI Sup"