[SMC] Clean Liquidity Heatmap

Category: Indicators By: Iván González Created: March 24, 2026, 1:47 PM
March 24, 2026, 1:47 PM
Indicators
0 Comments

This indicator identifies Smart Money Concept (SMC) liquidity zones based on Order Block detection with volume confirmation. Active zones are drawn as colored rectangles that extend to the current bar, while broken zones are grayed out and trimmed to the bar where the breakout occurred.

 

How It Works

 

The indicator detects two types of Order Blocks:

 

Bullish OB — The previous bar makes a lower low compared to two bars ago, the current bar closes above the previous bar’s high, and volume exceeds the 20-period average by a configurable multiplier (default 1.3x). This suggests institutional accumulation.

 

Bearish OB — The previous bar makes a higher high compared to two bars ago, the current bar closes below the previous bar’s low, and volume exceeds the threshold. This suggests institutional distribution.

 

When an OB is detected, the indicator stores the zone defined by the previous bar’s high and low. Up to 5 zones per type (bullish/bearish) are tracked simultaneously using a FIFO buffer — when a new zone is detected and the maximum is reached, the oldest zone is dropped.

 

Zone Management

 

Each zone is checked on every bar for invalidation:

  • A bullish zone is broken when the close falls below the zone’s bottom
  • A bearish zone is broken when the close rises above the zone’s top

 

Active zones are drawn with their original color (teal for bullish, red for bearish) and extend to the current bar. Broken zones are drawn in gray with reduced opacity, trimmed to the bar where the break occurred. This behavior can be toggled with the hideOld parameter.

Signal arrows mark the exact bar where each OB was detected — arrow up for bullish, arrow down for bearish.

 

Settings

 

maxZones — Maximum number of active zones per type, from 1 to 5. Default: 5.

hideOld — Set to 1 to display broken zones in gray (default). Set to 0 to hide them completely.

volMultiplier — Multiplier applied to the 20-period average volume to define what counts as anomalous volume. Default: 1.3.

showsig — show signals (arrows). Default: false.

 

Code

 

//---------------------------------------------------------------//
// PRC_Clean Liquidity Heatmap [SMC]
// Adapted from PineScript (ALEKSDU) to ProBuilder
// version = 0
// Date: 24.03.2026
// Iván González @ www.prorealcode.com
// Sharing ProRealTime knowledge
//---------------------------------------------------------------//
defparam drawonlastbaronly = true
//---------------------------------------------------------------//
// --- Settings ---
//---------------------------------------------------------------//
maxZones = 5 // Max active zones per type BUY/SELL (1 to 5)
hideOld = 1 // 1 = gray out broken zones, 0 = hide them completely
volMultiplier = 1.3 // Anomalous volume multiplier
showsig = 0 // show signals (true / false)
//---------------------------------------------------------------//
// --- Volume Logic ---
//---------------------------------------------------------------//
avgVol = average[20](volume)
IF volume > avgVol * volMultiplier THEN
   isHighVol = 1
ELSE
   isHighVol = 0
ENDIF
//---------------------------------------------------------------//
// --- OB Detection ---
//---------------------------------------------------------------//
IF low[1] < low[2] AND close > high[1] AND isHighVol THEN
   isBullOB = 1
ELSE
   isBullOB = 0
ENDIF

IF high[1] > high[2] AND close < low[1] AND isHighVol THEN
   isBearOB = 1
ELSE
   isBearOB = 0
ENDIF

// ============================================================
// SIGNAL STORAGE ($arrays as read buffer)
// ============================================================
once bullSigCount = 0
once bearSigCount = 0

IF isBullOB THEN
   $bullSigBar[bullSigCount] = barindex
   $bullSigPrice[bullSigCount] = low - averagetruerange[14] * 0.3
   bullSigCount = bullSigCount + 1
ENDIF

IF isBearOB THEN
   $bearSigBar[bearSigCount] = barindex
   $bearSigPrice[bearSigCount] = high + averagetruerange[14] * 0.3
   bearSigCount = bearSigCount + 1
ENDIF

// ============================================================
// FIFO BULLISH ZONES (5 slots)
// Fields: Bar, Top, Bot, Active (1/0), BrokenBar
// ============================================================
once bullBar0 = 0
once bullTop0 = 0
once bullBot0 = 0
once bullActive0 = 0
once bullBrkBar0 = 0

once bullBar1 = 0
once bullTop1 = 0
once bullBot1 = 0
once bullActive1 = 0
once bullBrkBar1 = 0

once bullBar2 = 0
once bullTop2 = 0
once bullBot2 = 0
once bullActive2 = 0
once bullBrkBar2 = 0

once bullBar3 = 0
once bullTop3 = 0
once bullBot3 = 0
once bullActive3 = 0
once bullBrkBar3 = 0

once bullBar4 = 0
once bullTop4 = 0
once bullBot4 = 0
once bullActive4 = 0
once bullBrkBar4 = 0

once bullCount = 0

// ============================================================
// FIFO BEARISH ZONES (5 slots)
// ============================================================
once bearBar0 = 0
once bearTop0 = 0
once bearBot0 = 0
once bearActive0 = 0
once bearBrkBar0 = 0

once bearBar1 = 0
once bearTop1 = 0
once bearBot1 = 0
once bearActive1 = 0
once bearBrkBar1 = 0

once bearBar2 = 0
once bearTop2 = 0
once bearBot2 = 0
once bearActive2 = 0
once bearBrkBar2 = 0

once bearBar3 = 0
once bearTop3 = 0
once bearBot3 = 0
once bearActive3 = 0
once bearBrkBar3 = 0

once bearBar4 = 0
once bearTop4 = 0
once bearBot4 = 0
once bearActive4 = 0
once bearBrkBar4 = 0

once bearCount = 0

// ============================================================
// REGISTER NEW BULLISH OB
// ============================================================
IF isBullOB THEN
   IF bullCount >= maxZones THEN
      // FIFO shift
      bullBar0 = bullBar1
      bullTop0 = bullTop1
      bullBot0 = bullBot1
      bullActive0 = bullActive1
      bullBrkBar0 = bullBrkBar1
      
      bullBar1 = bullBar2
      bullTop1 = bullTop2
      bullBot1 = bullBot2
      bullActive1 = bullActive2
      bullBrkBar1 = bullBrkBar2
      
      bullBar2 = bullBar3
      bullTop2 = bullTop3
      bullBot2 = bullBot3
      bullActive2 = bullActive3
      bullBrkBar2 = bullBrkBar3
      
      bullBar3 = bullBar4
      bullTop3 = bullTop4
      bullBot3 = bullBot4
      bullActive3 = bullActive4
      bullBrkBar3 = bullBrkBar4
      
      IF maxZones = 1 THEN
         bullBar0 = barindex[1]
         bullTop0 = high[1]
         bullBot0 = low[1]
         bullActive0 = 1
         bullBrkBar0 = 0
      ELSIF maxZones = 2 THEN
         bullBar1 = barindex[1]
         bullTop1 = high[1]
         bullBot1 = low[1]
         bullActive1 = 1
         bullBrkBar1 = 0
      ELSIF maxZones = 3 THEN
         bullBar2 = barindex[1]
         bullTop2 = high[1]
         bullBot2 = low[1]
         bullActive2 = 1
         bullBrkBar2 = 0
      ELSIF maxZones = 4 THEN
         bullBar3 = barindex[1]
         bullTop3 = high[1]
         bullBot3 = low[1]
         bullActive3 = 1
         bullBrkBar3 = 0
      ELSIF maxZones = 5 THEN
         bullBar4 = barindex[1]
         bullTop4 = high[1]
         bullBot4 = low[1]
         bullActive4 = 1
         bullBrkBar4 = 0
      ENDIF
   ELSE
      IF bullCount = 0 THEN
         bullBar0 = barindex[1]
         bullTop0 = high[1]
         bullBot0 = low[1]
         bullActive0 = 1
         bullBrkBar0 = 0
      ELSIF bullCount = 1 THEN
         bullBar1 = barindex[1]
         bullTop1 = high[1]
         bullBot1 = low[1]
         bullActive1 = 1
         bullBrkBar1 = 0
      ELSIF bullCount = 2 THEN
         bullBar2 = barindex[1]
         bullTop2 = high[1]
         bullBot2 = low[1]
         bullActive2 = 1
         bullBrkBar2 = 0
      ELSIF bullCount = 3 THEN
         bullBar3 = barindex[1]
         bullTop3 = high[1]
         bullBot3 = low[1]
         bullActive3 = 1
         bullBrkBar3 = 0
      ELSIF bullCount = 4 THEN
         bullBar4 = barindex[1]
         bullTop4 = high[1]
         bullBot4 = low[1]
         bullActive4 = 1
         bullBrkBar4 = 0
      ENDIF
      bullCount = bullCount + 1
   ENDIF
ENDIF

// ============================================================
// REGISTER NEW BEARISH OB
// ============================================================
IF isBearOB THEN
   IF bearCount >= maxZones THEN
      // FIFO shift
      bearBar0 = bearBar1
      bearTop0 = bearTop1
      bearBot0 = bearBot1
      bearActive0 = bearActive1
      bearBrkBar0 = bearBrkBar1
      
      bearBar1 = bearBar2
      bearTop1 = bearTop2
      bearBot1 = bearBot2
      bearActive1 = bearActive2
      bearBrkBar1 = bearBrkBar2
      
      bearBar2 = bearBar3
      bearTop2 = bearTop3
      bearBot2 = bearBot3
      bearActive2 = bearActive3
      bearBrkBar2 = bearBrkBar3
      
      bearBar3 = bearBar4
      bearTop3 = bearTop4
      bearBot3 = bearBot4
      bearActive3 = bearActive4
      bearBrkBar3 = bearBrkBar4
      
      IF maxZones = 1 THEN
         bearBar0 = barindex[1]
         bearTop0 = high[1]
         bearBot0 = low[1]
         bearActive0 = 1
         bearBrkBar0 = 0
      ELSIF maxZones = 2 THEN
         bearBar1 = barindex[1]
         bearTop1 = high[1]
         bearBot1 = low[1]
         bearActive1 = 1
         bearBrkBar1 = 0
      ELSIF maxZones = 3 THEN
         bearBar2 = barindex[1]
         bearTop2 = high[1]
         bearBot2 = low[1]
         bearActive2 = 1
         bearBrkBar2 = 0
      ELSIF maxZones = 4 THEN
         bearBar3 = barindex[1]
         bearTop3 = high[1]
         bearBot3 = low[1]
         bearActive3 = 1
         bearBrkBar3 = 0
      ELSIF maxZones = 5 THEN
         bearBar4 = barindex[1]
         bearTop4 = high[1]
         bearBot4 = low[1]
         bearActive4 = 1
         bearBrkBar4 = 0
      ENDIF
   ELSE
      IF bearCount = 0 THEN
         bearBar0 = barindex[1]
         bearTop0 = high[1]
         bearBot0 = low[1]
         bearActive0 = 1
         bearBrkBar0 = 0
      ELSIF bearCount = 1 THEN
         bearBar1 = barindex[1]
         bearTop1 = high[1]
         bearBot1 = low[1]
         bearActive1 = 1
         bearBrkBar1 = 0
      ELSIF bearCount = 2 THEN
         bearBar2 = barindex[1]
         bearTop2 = high[1]
         bearBot2 = low[1]
         bearActive2 = 1
         bearBrkBar2 = 0
      ELSIF bearCount = 3 THEN
         bearBar3 = barindex[1]
         bearTop3 = high[1]
         bearBot3 = low[1]
         bearActive3 = 1
         bearBrkBar3 = 0
      ELSIF bearCount = 4 THEN
         bearBar4 = barindex[1]
         bearTop4 = high[1]
         bearBot4 = low[1]
         bearActive4 = 1
         bearBrkBar4 = 0
      ENDIF
      bearCount = bearCount + 1
   ENDIF
ENDIF

// ============================================================
// CHECK BROKEN ZONES (every bar)
// ============================================================
IF bullActive0 = 1 AND close < bullBot0 THEN
   bullActive0 = 0
   bullBrkBar0 = barindex
ENDIF
IF bullActive1 = 1 AND close < bullBot1 THEN
   bullActive1 = 0
   bullBrkBar1 = barindex
ENDIF
IF bullActive2 = 1 AND close < bullBot2 THEN
   bullActive2 = 0
   bullBrkBar2 = barindex
ENDIF
IF bullActive3 = 1 AND close < bullBot3 THEN
   bullActive3 = 0
   bullBrkBar3 = barindex
ENDIF
IF bullActive4 = 1 AND close < bullBot4 THEN
   bullActive4 = 0
   bullBrkBar4 = barindex
ENDIF

IF bearActive0 = 1 AND close > bearTop0 THEN
   bearActive0 = 0
   bearBrkBar0 = barindex
ENDIF
IF bearActive1 = 1 AND close > bearTop1 THEN
   bearActive1 = 0
   bearBrkBar1 = barindex
ENDIF
IF bearActive2 = 1 AND close > bearTop2 THEN
   bearActive2 = 0
   bearBrkBar2 = barindex
ENDIF
IF bearActive3 = 1 AND close > bearTop3 THEN
   bearActive3 = 0
   bearBrkBar3 = barindex
ENDIF
IF bearActive4 = 1 AND close > bearTop4 THEN
   bearActive4 = 0
   bearBrkBar4 = barindex
ENDIF

// ============================================================
// DRAW EVERYTHING (only on last bar update)
// ============================================================
IF islastbarupdate THEN
   
   // --- SIGNAL ARROWS (from $arrays) ---
   IF bullSigCount > 0 and showsig THEN
      FOR i = 0 TO bullSigCount - 1
         drawarrowup($bullSigBar[i], $bullSigPrice[i]) coloured(0,128,128)
      NEXT
   ENDIF
   
   IF bearSigCount > 0 and showsig THEN
      FOR i = 0 TO bearSigCount - 1
         drawarrowdown($bearSigBar[i], $bearSigPrice[i]) coloured(255,0,0)
      NEXT
   ENDIF
   
   // --- BULLISH ZONES (teal active / gray broken) ---
   IF bullBar0 > 0 THEN
      IF bullActive0 = 1 THEN
         drawrectangle(bullBar0, bullTop0, barindex, bullBot0) coloured(0,128,128,180) bordercolor(0,128,128,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bullBar0, bullTop0, bullBrkBar0, bullBot0) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bullBar1 > 0 THEN
      IF bullActive1 = 1 THEN
         drawrectangle(bullBar1, bullTop1, barindex, bullBot1) coloured(0,128,128,180) bordercolor(0,128,128,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bullBar1, bullTop1, bullBrkBar1, bullBot1) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bullBar2 > 0 THEN
      IF bullActive2 = 1 THEN
         drawrectangle(bullBar2, bullTop2, barindex, bullBot2) coloured(0,128,128,180) bordercolor(0,128,128,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bullBar2, bullTop2, bullBrkBar2, bullBot2) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bullBar3 > 0 THEN
      IF bullActive3 = 1 THEN
         drawrectangle(bullBar3, bullTop3, barindex, bullBot3) coloured(0,128,128,180) bordercolor(0,128,128,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bullBar3, bullTop3, bullBrkBar3, bullBot3) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bullBar4 > 0 THEN
      IF bullActive4 = 1 THEN
         drawrectangle(bullBar4, bullTop4, barindex, bullBot4) coloured(0,128,128,180) bordercolor(0,128,128,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bullBar4, bullTop4, bullBrkBar4, bullBot4) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   // --- BEARISH ZONES (red active / gray broken) ---
   IF bearBar0 > 0 THEN
      IF bearActive0 = 1 THEN
         drawrectangle(bearBar0, bearTop0, barindex, bearBot0) coloured(255,0,0,180) bordercolor(255,0,0,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bearBar0, bearTop0, bearBrkBar0, bearBot0) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bearBar1 > 0 THEN
      IF bearActive1 = 1 THEN
         drawrectangle(bearBar1, bearTop1, barindex, bearBot1) coloured(255,0,0,180) bordercolor(255,0,0,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bearBar1, bearTop1, bearBrkBar1, bearBot1) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bearBar2 > 0 THEN
      IF bearActive2 = 1 THEN
         drawrectangle(bearBar2, bearTop2, barindex, bearBot2) coloured(255,0,0,180) bordercolor(255,0,0,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bearBar2, bearTop2, bearBrkBar2, bearBot2) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bearBar3 > 0 THEN
      IF bearActive3 = 1 THEN
         drawrectangle(bearBar3, bearTop3, barindex, bearBot3) coloured(255,0,0,180) bordercolor(255,0,0,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bearBar3, bearTop3, bearBrkBar3, bearBot3) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
   IF bearBar4 > 0 THEN
      IF bearActive4 = 1 THEN
         drawrectangle(bearBar4, bearTop4, barindex, bearBot4) coloured(255,0,0,180) bordercolor(255,0,0,0)
      ELSIF hideOld = 1 THEN
         drawrectangle(bearBar4, bearTop4, bearBrkBar4, bearBot4) coloured(128,128,128,30) bordercolor(128,128,128,0)
      ENDIF
   ENDIF
   
ENDIF
//---------------------------------------------------------------//
RETURN

Download
Filename: PRC_SMC-Clean-LiquidityHeatmap.itf
Downloads: 22
Iván González Master
Operating in the shadows, I hack problems one by one. My bio is currently encrypted by a complex algorithm. Decryption underway...
Author’s Profile

Comments

Logo Logo
Loading...