Liquidity Sweeps [Kodexius]Liquidity Sweeps is a price action indicator built to visualize and react to common “stop run” behavior around recent swing highs and swing lows. It continuously detects pivot-based liquidity levels (recent resistance and support), extends them forward in time, and then classifies the interaction when price probes beyond a level but fails to hold through it.
The script focuses on two outcomes:
Buy-Side Liquidity Sweep (BSL): price takes liquidity above a recent swing high (high breaks above the level) but closes back at or below the level.
Sell-Side Liquidity Sweep (SSL): price takes liquidity below a recent swing low (low breaks below the level) but closes back at or above the level.
To support real trading workflows, it keeps charts readable by limiting active levels, offers clean styling options, and optionally filters sweep signals using relative volume (RVOL) so you can require participation before a sweep is considered valid.
🔹 Features
🔸 Pivot-Based Liquidity Level Detection (Swing Highs and Swing Lows)
The indicator uses a user-defined Pivot Length to identify confirmed swing points:
Pivot Highs become resistance liquidity levels (buy-side liquidity above highs).
Pivot Lows become support liquidity levels (sell-side liquidity below lows).
Each detected level is drawn as a horizontal line and automatically extended to the current bar until it is swept or broken.
🔸 Automatic Level Management (De-Cluttering)
To prevent chart overload, the script stores levels in internal arrays and enforces Maximum Active Levels:
When new levels are added and the limit is exceeded, the oldest level is removed.
This keeps only the most relevant, recent liquidity zones visible.
🔸 Clear Sweep Classification (BSL and SSL)
The sweep logic is intentionally strict and practical:
- BSL Sweep triggers when the bar’s high is above resistance but the close is back below or at resistance.
- SSL Sweep triggers when the bar’s low is below support but the close is back above or at support.
This models the “probe and reject” behavior typical of liquidity grabs.
🔸 Optional Volume Confirmation Using RVOL
When Enable Volume Filter is turned on, sweeps are only valid if the current bar’s volume is strong relative to the last 20 bars:
The script computes a 20-period volume average.
You can require volume to exceed the average by a chosen Volume Multiplier (example: 1.5 means 150% of the average).
If the filter is disabled, sweeps are evaluated purely on price conditions.
🔸 Sweep Labels and Level Highlighting
On a valid sweep:
A label is printed on the sweep bar:
- ▼ BSL for buy-side liquidity sweeps (yellow)
- ▲ SSL for sell-side liquidity sweeps (blue)
The swept level is highlighted by drawing an additional colored line over the swept range.
The script also prints the bar’s RVOL percentage near the midpoint of the swept line segment:
- BSL volume text is placed above the line midpoint
- SSL volume text is placed below the line midpoint
This makes it easy to see whether a sweep was low-effort or supported by strong participation.
🔸 Styling Controls
You can fully tailor the visual output:
Resistance and support line colors
Line style selection: Solid, Dotted, Dashed
Toggle sweep labels on or off
🔸 Alerts
The indicator exposes alert conditions for both sweep types and also fires explicit alert messages once per bar close when a sweep is confirmed:
- Buy Liquidity Sweep (BSL)
- Sell Liquidity Sweep (SSL)
🔹 Calculations
1) Pivot High / Pivot Low Detection
float ph = ta.pivothigh(high, pivotPeriodInput, pivotPeriodInput)
float pl = ta.pivotlow(low, pivotPeriodInput, pivotPeriodInput)
Interpretation:
A pivot is only confirmed after pivotPeriodInput bars have passed.
Once confirmed, the level is anchored at the pivot bar and then extended forward.
2) Creating and Storing Liquidity Levels
New Resistance (Pivot High):
if not na(ph)
line newL = line.new(bar_index , ph, bar_index, ph,
color = resistanceColorInput, width = 1, style = getLineStyle(lineStyleInput))
resistanceLevels.push(LiquidityLevel.new(ph, bar_index , newL))
if resistanceLevels.size() > maxLinesInput
(resistanceLevels.shift()).delete()
New Support (Pivot Low):
if not na(pl)
line newL = line.new(bar_index , pl, bar_index, pl,
color = supportColorInput, width = 1, style = getLineStyle(lineStyleInput))
supportLevels.push(LiquidityLevel.new(pl, bar_index , newL))
if supportLevels.size() > maxLinesInput
(supportLevels.shift()).delete()
This enforces the “Maximum Active Levels” limit by deleting the oldest stored level when the cap is exceeded.
3) Relative Volume (RVOL) and Volume Filter
float volAvg = ta.sma(volume, 20)
float volRelative = (volume / volAvg) * 100
bool isVolStrong = not useVolFilterInput or (volume > volAvg * volMultiplierInput)
volRelative expresses the sweep bar’s volume as a percentage of the last 20-bar average.
If the filter is enabled, a sweep is valid only when isVolStrong is true.
4) Sweep Conditions (Core Logic)
Buy-Side Liquidity Sweep (Resistance Sweep)
A resistance level is considered swept when price trades above it but closes back at or below it.
bool priceSwept = high > lvl.price and close <= lvl.price
bool broken = close > lvl.price
priceSwept captures the “probe and reject” behavior.
broken invalidates the level if price closes above it.
The confirmation and cleanup flow:
if priceSwept and isVolStrong
buySweepOccurred := true
if showLabelsInput
label.new(bar_index, high, "▼ BSL",
style = label.style_label_down, color = #00000000,
textcolor = C_SWEEP_BUY, size = size.small)
line.new(lvl.startBar, lvl.price, bar_index, lvl.price, color = C_SWEEP_BUY, width = 1)
int midX = math.round((lvl.startBar + bar_index) / 2)
label.new(midX, lvl.price, str.tostring(volRelative, "#") + "% VOL",
color = #00000000, textcolor = color.new(C_SWEEP_BUY, 20),
style = label.style_label_down, size = size.tiny)
resistanceLevels.remove(i).delete()
else if broken
resistanceLevels.remove(i).delete()
Sell-Side Liquidity Sweep (Support Sweep)
A support level is considered swept when price trades below it but closes back at or above it.
bool priceSwept = low < lvl.price and close >= lvl.price
bool broken = close < lvl.price
The confirmation and cleanup flow:
if priceSwept and isVolStrong
sellSweepOccurred := true
if showLabelsInput
label.new(bar_index, low, "▲ SSL",
style = label.style_label_up, color = #00000000,
textcolor = C_SWEEP_SELL, size = size.small)
line.new(lvl.startBar, lvl.price, bar_index, lvl.price, color = C_SWEEP_SELL, width = 1)
int midX = math.round((lvl.startBar + bar_index) / 2)
label.new(midX, lvl.price, str.tostring(volRelative, "#") + "% VOL",
color = #00000000, textcolor = color.new(C_SWEEP_SELL, 20),
style = label.style_label_up, size = size.tiny)
supportLevels.remove(i).delete()
else if broken
supportLevels.remove(i).delete()
5) Level Extension to Current Bar
method update(LiquidityLevel this) =>
line.set_x2(this.lineObj, bar_index)
This keeps each active liquidity level extended to the current candle until it is swept or decisively broken.
6) Alerts
alertcondition(buySweepOccurred, "Buy Liquidity Sweep", "BSL Swept!")
alertcondition(sellSweepOccurred, "Sell Liquidity Sweep", "SSL Swept!")
if buySweepOccurred
alert("Kodexius BSL Sweep: " + str.tostring(close), alert.freq_once_per_bar_close)
if sellSweepOccurred
alert("Kodexius SSL Sweep: " + str.tostring(close), alert.freq_once_per_bar_close)
อินดิเคเตอร์ Pine Script®






















