ICT Concepts Indicator

Category: Indicators By: Iván González Created: March 12, 2026, 9:30 AM
March 12, 2026, 9:30 AM
Indicators
0 Comments

This indicator brings together several key Inner Circle Trader (ICT) concepts into a single ProBuilder script. It covers market structure detection, fair value gaps, order blocks, liquidity zones, volume imbalances, displacement candles, and session killzones.

All modules can be toggled on or off independently via parameters, allowing you to display only the concepts you need on your chart.

 

Market Structure Shift (MSS) and Break of Structure (BOS)

 

The indicator uses a zigzag algorithm to identify swing highs and swing lows based on a configurable lookback period. It then monitors price action for two types of structural events:

 

MSS (Market Structure Shift) — Detected when price closes beyond a confirmed swing point in the opposite direction of the current trend. This signals a potential reversal. The indicator draws a horizontal line from the swing bar to the breakout bar, labeled “MSS”.

 

BOS (Break of Structure) — Detected when price closes beyond a confirmed swing point in the same direction as the established trend. This signals trend continuation. Drawn as a dotted horizontal line labeled “BOS”. The last two BOS levels are displayed.

 

The zigzag tracks the last 4 swing points using a FIFO buffer, which also feeds the liquidity scanner. The msLen parameter controls the pivot detection sensitivity (default: 5).

 

Fair Value Gaps (FVG / IFVG)

 

A Fair Value Gap is a three-candle pattern where a strong displacement candle creates a gap between the wicks of the candles before and after it. The indicator supports two modes, selectable via the fvgMode parameter:

 

FVG mode (fvgMode = 0) — Standard fair value gap. Bullish: the low of the current bar is above the high of two bars ago. Bearish: the high of the current bar is below the low of two bars ago. This represents a true gap with no price overlap.

 

IFVG mode (fvgMode = 1) — Implied fair value gap. Uses the inverse condition where there is an overlap between the wicks, but a displacement candle is still present. This captures “implied” imbalances that standard FVGs miss.

 

The indicator stores the last 4 bullish and 4 bearish FVGs simultaneously. Each FVG is drawn as a rectangle, extending to the right while active. When price breaks through the FVG (closes beyond its boundary), the rectangle is closed and recolored to indicate the break.

 

Order Blocks

 

Order Blocks represent institutional supply and demand zones. The indicator uses a separate swing detector with its own configurable lookback (obLen, default: 10) to identify swing points for OB detection.

 

Bullish OB — When price closes above a confirmed swing high, the indicator searches backward from the breakout bar to the swing bar and finds the candle with the lowest body. That candle’s body range defines the OB zone. Displayed as a horizontal line at the OB bottom, labeled “+OB”.

 

Bearish OB — When price closes below a confirmed swing low, the indicator finds the candle with the highest body in the range. Displayed as a horizontal line at the OB top, labeled “-OB”.

 

Breaker detection — When price penetrates an active OB (body closes beyond its boundary), it becomes a “breaker block” and is drawn as a filled rectangle instead of a line. If price then reverses and closes back beyond the opposite edge, the OB is invalidated and removed.

 

Liquidity Zones

 

Liquidity zones are areas where multiple swing highs or swing lows cluster at similar price levels, indicating pools of resting orders (stop losses, limit orders) that institutions may target.

 

The indicator maintains a buffer of the last 20 zigzag points. Each time a new pivot is confirmed, it scans all stored pivots of the same type (highs or lows) and counts how many fall within a tolerance band defined by ATR / liqMargin. If 3 or more pivots cluster within this band, a liquidity zone is created.

 

Buyside Liquidity — Clusters of swing highs. Drawn as a box with a horizontal line, labeled “Buyside liq.”. Colored in orange-red. Hidden once price breaks above the zone.

Sellside Liquidity — Clusters of swing lows. Drawn similarly but in cyan. Hidden once price breaks below the zone.

 

The liqMargin parameter controls cluster tightness. Lower values (2-3) create wider bands and detect more zones; higher values (5-7) require tighter clusters. Up to 2 zones per direction are displayed simultaneously.

 

Volume Imbalance

 

Volume Imbalances identify gaps between the bodies of consecutive candles where no trading occurred. These differ from FVGs in that they look at the relationship between two adjacent candle bodies rather than a three-candle wick pattern.

 

Bullish VI — The current candle opens above the previous candle’s body top, with the previous high below the current body bottom. This gap between the bodies indicates aggressive buying.

 

Bearish VI — The current candle opens below the previous candle’s body bottom, with the previous low above the current body top.

The last 2 Volume Imbalances are displayed as two parallel horizontal lines marking the gap boundaries, with a “VI” label.

 

Displacement

 

Displacement candles are strong momentum candles characterized by a large body relative to the recent average, with small upper and lower wicks (both less than 36% of the body size). These candles indicate aggressive institutional activity.

 

When enabled, the last 5 displacement candles are marked with a green dot (bullish) or red dot (bearish) plotted with an ATR-based offset from the candle’s extreme.

 

Killzones

 

Killzones highlight the key trading sessions with background coloring. ICT methodology emphasizes that significant price movements and liquidity sweeps tend to occur during specific time windows.

 

The default session times are configured in CET timezone and should be adjusted based on your broker’s server time:

New York — 13:00 to 15:00 CET (orange background)

London Open — 08:00 to 11:00 CET (cyan background)

London Close — 16:00 to 18:00 CET (blue background)

Asian — 02:00 to 06:00 CET (pink background)

 

All session start/end times are configurable via the kzNY1/kzNY2, kzLO1/kzLO2, kzLC1/kzLC2, kzAS1/kzAS2 parameters in HHMM format.

 

Parameters

 

msLen (default: 5) — Pivot detection lookback for market structure. Range: 3 to 10. Lower values detect more swings; higher values filter out noise.

showMS, showFVG, showDispl, showVI, showOB, showLiq, showKZ — Toggle each module on (1) or off (0). Disabling unused modules improves chart clarity and performance.

fvgMode (default: 0) — Set to 0 for standard FVG or 1 for Implied FVG (IFVG).

obLen (default: 10) — Swing lookback for Order Block detection. Independent from msLen.

liqMargin (default: 4) — Liquidity cluster tolerance. Range: 2 to 7. Lower = wider detection band.

Killzone times (kzNY1, kzNY2, etc.) — Session boundaries in HHMM format, CET timezone. Adjust for your broker.

 

Technical Notes

 

The indicator uses defparam drawonlastbaronly = true and performs all drawing inside an islastbarupdate block. This means calculations run on every historical bar (building up the state), but graphical elements are only rendered on the last chart update. Killzones use backgroundcolor outside the drawing block to paint the session backgrounds historically.

 

Data structures use named variable FIFOs for persistent state (zigzag, MSS, BOS, FVG, VI, OB) and a 20-slot $array buffer for the liquidity scanner. All modules share the zigzag but operate independently, so any combination can be enabled or disabled without side effects.

 

ProBuilder Code

 

//--------------------------------------------
// PRC_ICT Concepts (by LuxAlgo)
// version = 0
// 11.03.2026
// Iván González @ www.prorealcode.com
// Sharing ProRealTime knowledge
//--------------------------------------------
defparam drawonlastbaronly = true
//--------------------------------------------
// === PARAMETERS ===
msLen = 5         // Market Structure pivot lookback (3-10)
showMS = 1        // Show MSS/BOS
showFVG = 1       // Show Fair Value Gaps
fvgMode = 0       // 0=FVG, 1=IFVG
showDispl = 0     // Show Displacement candles
showVI = 1        // Show Volume Imbalance
showOB = 1        // Show Order Blocks
obLen = 10        // OB swing lookback
showLiq = 1       // Show Liquidity zones
liqMargin = 4     // Liquidity cluster margin (2-7, higher=tighter)
showKZ = 0        // Show Killzones


// Killzone hours (HHMM, CET timezone - adjust for your broker)
kzNY1 = 1300
kzNY2 = 1500
kzLO1 = 800
kzLO2 = 1100
kzLC1 = 1600
kzLC2 = 1800
kzAS1 = 200
kzAS2 = 600


// === INITIALIZATION ===
// Zigzag FIFO (4 pts, 0=newest)
once sw0Dir = 0
once sw0Bar = -1
once sw0Prc = 0
once sw1Dir = 0
once sw1Bar = -1
once sw1Prc = 0
once sw2Dir = 0
once sw2Bar = -1
once sw2Prc = 0
once sw3Dir = 0
once sw3Bar = -1
once sw3Prc = 0
once swCnt = 0


// Zigzag $array buffer for liquidity scanning (20 pts)
once zzIdx = 0


// MSS state
once mssDir = 0
once mssLvl = 0
once mssSBar = -1
once mssBBar = -1


// BOS FIFO (2, 0=newest)
once bosLvl0 = 0
once bosSB0 = -1
once bosBB0 = -1
once bosLvl1 = 0
once bosSB1 = -1
once bosBB1 = -1
once bosCnt = 0


// FVG Bull FIFO (4, 0=newest)
once fbTop0 = 0
once fbBtm0 = 0
once fbLft0 = -1
once fbAct0 = 0
once fbBrk0 = -1
once fbTop1 = 0
once fbBtm1 = 0
once fbLft1 = -1
once fbAct1 = 0
once fbBrk1 = -1
once fbTop2 = 0
once fbBtm2 = 0
once fbLft2 = -1
once fbAct2 = 0
once fbBrk2 = -1
once fbTop3 = 0
once fbBtm3 = 0
once fbLft3 = -1
once fbAct3 = 0
once fbBrk3 = -1


// FVG Bear FIFO (4, 0=newest)
once fsTop0 = 0
once fsBtm0 = 0
once fsLft0 = -1
once fsAct0 = 0
once fsBrk0 = -1
once fsTop1 = 0
once fsBtm1 = 0
once fsLft1 = -1
once fsAct1 = 0
once fsBrk1 = -1
once fsTop2 = 0
once fsBtm2 = 0
once fsLft2 = -1
once fsAct2 = 0
once fsBrk2 = -1
once fsTop3 = 0
once fsBtm3 = 0
once fsLft3 = -1
once fsAct3 = 0
once fsBrk3 = -1


// VI FIFO (2, 0=newest)
once viTop0 = 0
once viBtm0 = 0
once viLBar0 = -1
once viTop1 = 0
once viBtm1 = 0
once viLBar1 = -1
once viCnt = 0


// Displacement FIFO (5, 0=oldest)
once dpBar0 = -1
once dpPrc0 = 0
once dpDir0 = 0
once dpBar1 = -1
once dpPrc1 = 0
once dpDir1 = 0
once dpBar2 = -1
once dpPrc2 = 0
once dpDir2 = 0
once dpBar3 = -1
once dpPrc3 = 0
once dpDir3 = 0
once dpBar4 = -1
once dpPrc4 = 0
once dpDir4 = 0
once dpCnt = 0


// Order Blocks - separate swing detector
once obOs = 0
once obTopY = 0
once obTopX = -1
once obTopCr = 1
once obBtmY = 0
once obBtmX = -1
once obBtmCr = 1


// Bull OB (1 slot)
once obBTop = 0
once obBBtm = 0
once obBLoc = -1
once obBBrk = 0
once obBBrkLoc = -1


// Bear OB (1 slot)
once obSTop = 0
once obSBtm = 0
once obSLoc = -1
once obSBrk = 0
once obSBrkLoc = -1


// Liquidity FIFO - Buyside (2 slots)
once lbTop0 = 0
once lbBtm0 = 0
once lbStB0 = -1
once lbLnP0 = 0
once lbBrk0 = 0
once lbTop1 = 0
once lbBtm1 = 0
once lbStB1 = -1
once lbLnP1 = 0
once lbBrk1 = 0
once lbCnt = 0


// Liquidity FIFO - Sellside (2 slots)
once lsTop0 = 0
once lsBtm0 = 0
once lsStB0 = -1
once lsLnP0 = 0
once lsBrk0 = 0
once lsTop1 = 0
once lsBtm1 = 0
once lsStB1 = -1
once lsLnP1 = 0
once lsBrk1 = 0
once lsCnt = 0


// === COMMON CALCULATIONS ===
myBody = abs(close - open)
meanBody = average[20](myBody)
atrVal = averagetruerange[10]
atrOff = atrVal * 0.3
liqTol = atrVal / liqMargin


if close >= open then
bdTop = close
bdBtm = open
else
bdTop = open
bdBtm = close
endif


upWick = high - bdTop
loWick = bdBtm - low
percBd = 0.36


// Displacement detection
if myBody > meanBody AND upWick < myBody * percBd AND loWick < myBody * percBd then
if close > open then
isDispUp = 1
isDispDn = 0
else
isDispUp = 0
isDispDn = 1
endif
else
isDispUp = 0
isDispDn = 0
endif


// =====================================================
// MODULE 1: MARKET STRUCTURE (MSS/BOS) + ZIGZAG
// =====================================================
if showMS AND barindex >= msLen + 2 then
isPH = 0
isPL = 0
if high[1] = highest[msLen + 2](high) AND high[1] > high then
isPH = 1
endif
if low[1] = lowest[msLen + 2](low) AND low[1] < low then
isPL = 1
endif


// --- Zigzag update on pivot high ---
if isPH then
if sw0Dir < 1 then
// New direction: shift FIFO
sw3Dir = sw2Dir
sw3Bar = sw2Bar
sw3Prc = sw2Prc
sw2Dir = sw1Dir
sw2Bar = sw1Bar
sw2Prc = sw1Prc
sw1Dir = sw0Dir
sw1Bar = sw0Bar
sw1Prc = sw0Prc
sw0Dir = 1
sw0Bar = barindex - 1
sw0Prc = high[1]
if swCnt < 4 then
swCnt = swCnt + 1
endif
// Add to $array buffer for liquidity
if zzIdx >= 20 then
for si = 0 to 18 do
$zzDir[si] = $zzDir[si + 1]
$zzBar[si] = $zzBar[si + 1]
$zzPrc[si] = $zzPrc[si + 1]
next
zzIdx = 19
endif
$zzDir[zzIdx] = 1
$zzBar[zzIdx] = barindex - 1
$zzPrc[zzIdx] = high[1]
zzIdx = zzIdx + 1
else
if high[1] > sw0Prc then
sw0Bar = barindex - 1
sw0Prc = high[1]
// Update last entry in $array
if zzIdx > 0 then
$zzBar[zzIdx - 1] = barindex - 1
$zzPrc[zzIdx - 1] = high[1]
endif
endif
endif


// --- Liquidity scanning: buyside ---
if showLiq AND zzIdx > 2 then
lqCnt = 0
lqMinP = 0
lqMaxP = 999999
lqStB = 0
lqStP = 0
for si = 0 to zzIdx - 1 do
if $zzDir[si] = 1 then
if $zzPrc[si] > high[1] - liqTol AND $zzPrc[si] < high[1] + liqTol then
lqCnt = lqCnt + 1
lqStB = $zzBar[si]
lqStP = $zzPrc[si]
if $zzPrc[si] > lqMinP then
lqMinP = $zzPrc[si]
endif
if $zzPrc[si] < lqMaxP then
lqMaxP = $zzPrc[si]
endif
endif
endif
next
if lqCnt > 2 then
lqMid = (lqMinP + lqMaxP) / 2
// Check if same cluster as existing
newCluster = 1
if lbCnt > 0 AND lqStB = lbStB0 then
lbTop0 = lqMid + liqTol
lbBtm0 = lqMid - liqTol
lbLnP0 = lqStP
newCluster = 0
endif
if newCluster then
// Shift FIFO
lbTop1 = lbTop0
lbBtm1 = lbBtm0
lbStB1 = lbStB0
lbLnP1 = lbLnP0
lbBrk1 = lbBrk0
lbTop0 = lqMid + liqTol
lbBtm0 = lqMid - liqTol
lbStB0 = lqStB
lbLnP0 = lqStP
lbBrk0 = 0
if lbCnt < 2 then
lbCnt = lbCnt + 1
endif
endif
endif
endif
endif


// --- Zigzag update on pivot low ---
if isPL then
if sw0Dir > -1 then
sw3Dir = sw2Dir
sw3Bar = sw2Bar
sw3Prc = sw2Prc
sw2Dir = sw1Dir
sw2Bar = sw1Bar
sw2Prc = sw1Prc
sw1Dir = sw0Dir
sw1Bar = sw0Bar
sw1Prc = sw0Prc
sw0Dir = -1
sw0Bar = barindex - 1
sw0Prc = low[1]
if swCnt < 4 then
swCnt = swCnt + 1
endif
if zzIdx >= 20 then
for si = 0 to 18 do
$zzDir[si] = $zzDir[si + 1]
$zzBar[si] = $zzBar[si + 1]
$zzPrc[si] = $zzPrc[si + 1]
next
zzIdx = 19
endif
$zzDir[zzIdx] = -1
$zzBar[zzIdx] = barindex - 1
$zzPrc[zzIdx] = low[1]
zzIdx = zzIdx + 1
else
if low[1] < sw0Prc then
sw0Bar = barindex - 1
sw0Prc = low[1]
if zzIdx > 0 then
$zzBar[zzIdx - 1] = barindex - 1
$zzPrc[zzIdx - 1] = low[1]
endif
endif
endif


// --- Liquidity scanning: sellside ---
if showLiq AND zzIdx > 2 then
lqCnt = 0
lqMinP = 0
lqMaxP = 999999
lqStB = 0
lqStP = 0
for si = 0 to zzIdx - 1 do
if $zzDir[si] = -1 then
if $zzPrc[si] > low[1] - liqTol AND $zzPrc[si] < low[1] + liqTol then
lqCnt = lqCnt + 1
lqStB = $zzBar[si]
lqStP = $zzPrc[si]
if $zzPrc[si] > lqMinP then
lqMinP = $zzPrc[si]
endif
if $zzPrc[si] < lqMaxP then
lqMaxP = $zzPrc[si]
endif
endif
endif
next
if lqCnt > 2 then
lqMid = (lqMinP + lqMaxP) / 2
newCluster = 1
if lsCnt > 0 AND lqStB = lsStB0 then
lsTop0 = lqMid + liqTol
lsBtm0 = lqMid - liqTol
lsLnP0 = lqStP
newCluster = 0
endif
if newCluster then
lsTop1 = lsTop0
lsBtm1 = lsBtm0
lsStB1 = lsStB0
lsLnP1 = lsLnP0
lsBrk1 = lsBrk0
lsTop0 = lqMid + liqTol
lsBtm0 = lqMid - liqTol
lsStB0 = lqStB
lsLnP0 = lqStP
lsBrk0 = 0
if lsCnt < 2 then
lsCnt = lsCnt + 1
endif
endif
endif
endif
endif


// --- MSS / BOS detection ---
if swCnt >= 3 then
if sw2Dir = 1 then
iHP = sw2Prc
iHB = sw2Bar
iLP = sw1Prc
iLB = sw1Bar
else
iHP = sw1Prc
iHB = sw1Bar
iLP = sw2Prc
iLB = sw2Bar
endif


mssFired = 0


if close > iHP AND mssDir < 1 then
mssDir = 1
mssLvl = iHP
mssSBar = iHB
mssBBar = barindex
bosCnt = 0
mssFired = 1
endif


if close < iLP AND mssDir > -1 AND mssFired = 0 then
mssDir = -1
mssLvl = iLP
mssSBar = iLB
mssBBar = barindex
bosCnt = 0
mssFired = 1
endif


if mssFired = 0 AND mssDir = 1 AND close > iHP then
if iHP <> mssLvl then
canAdd = 1
if bosCnt > 0 AND iHP = bosLvl0 then
canAdd = 0
endif
if canAdd then
bosLvl1 = bosLvl0
bosSB1 = bosSB0
bosBB1 = bosBB0
bosLvl0 = iHP
bosSB0 = iHB
bosBB0 = barindex
if bosCnt < 2 then
bosCnt = bosCnt + 1
endif
endif
endif
endif


if mssFired = 0 AND mssDir = -1 AND close < iLP then
if iLP <> mssLvl then
canAdd = 1
if bosCnt > 0 AND iLP = bosLvl0 then
canAdd = 0
endif
if canAdd then
bosLvl1 = bosLvl0
bosSB1 = bosSB0
bosBB1 = bosBB0
bosLvl0 = iLP
bosSB0 = iLB
bosBB0 = barindex
if bosCnt < 2 then
bosCnt = bosCnt + 1
endif
endif
endif
endif
endif
endif


// --- Liquidity break detection ---
if showLiq then
if lbCnt >= 1 AND lbBrk0 = 0 AND lbStB0 > 0 then
if close > lbTop0 then
lbBrk0 = 1
endif
endif
if lbCnt >= 2 AND lbBrk1 = 0 AND lbStB1 > 0 then
if close > lbTop1 then
lbBrk1 = 1
endif
endif
if lsCnt >= 1 AND lsBrk0 = 0 AND lsStB0 > 0 then
if close < lsBtm0 then
lsBrk0 = 1
endif
endif
if lsCnt >= 2 AND lsBrk1 = 0 AND lsStB1 > 0 then
if close < lsBtm1 then
lsBrk1 = 1
endif
endif
endif


// =====================================================
// MODULE 2: FVG / IFVG (4+4 FIFO)
// =====================================================
if showFVG AND barindex >= 3 then
fvgBull = 0
fvgBear = 0
if fvgMode = 0 then
if isDispUp[1] = 1 AND low > high[2] then
fvgBull = 1
endif
if isDispDn[1] = 1 AND high < low[2] then
fvgBear = 1
endif
else
if isDispUp[1] = 1 AND low < high[2] then
fvgBull = 1
endif
if isDispDn[1] = 1 AND high > low[2] then
fvgBear = 1
endif
endif


// --- Bull FVG ---
if fvgBull then
if fvgMode = 0 then
nfTop = low
nfBtm = high[2]
else
nfTop = high[2]
nfBtm = low
endif
// Shift FIFO 3←2←1←0, new→0
fbTop3 = fbTop2
fbBtm3 = fbBtm2
fbLft3 = fbLft2
fbAct3 = fbAct2
fbBrk3 = fbBrk2
fbTop2 = fbTop1
fbBtm2 = fbBtm1
fbLft2 = fbLft1
fbAct2 = fbAct1
fbBrk2 = fbBrk1
fbTop1 = fbTop0
fbBtm1 = fbBtm0
fbLft1 = fbLft0
fbAct1 = fbAct0
fbBrk1 = fbBrk0
fbTop0 = nfTop
fbBtm0 = nfBtm
fbLft0 = barindex - 2
fbAct0 = 1
fbBrk0 = -1
endif


// --- Bear FVG ---
if fvgBear then
if fvgMode = 0 then
nfTop = low[2]
nfBtm = high
else
nfTop = high
nfBtm = low[2]
endif
fsTop3 = fsTop2
fsBtm3 = fsBtm2
fsLft3 = fsLft2
fsAct3 = fsAct2
fsBrk3 = fsBrk2
fsTop2 = fsTop1
fsBtm2 = fsBtm1
fsLft2 = fsLft1
fsAct2 = fsAct1
fsBrk2 = fsBrk1
fsTop1 = fsTop0
fsBtm1 = fsBtm0
fsLft1 = fsLft0
fsAct1 = fsAct0
fsBrk1 = fsBrk0
fsTop0 = nfTop
fsBtm0 = nfBtm
fsLft0 = barindex - 2
fsAct0 = 1
fsBrk0 = -1
endif


// --- FVG break detection ---
if fbAct0 = 1 AND fbLft0 > 0 AND low < fbBtm0 then
fbAct0 = 0
fbBrk0 = barindex
endif
if fbAct1 = 1 AND fbLft1 > 0 AND low < fbBtm1 then
fbAct1 = 0
fbBrk1 = barindex
endif
if fbAct2 = 1 AND fbLft2 > 0 AND low < fbBtm2 then
fbAct2 = 0
fbBrk2 = barindex
endif
if fbAct3 = 1 AND fbLft3 > 0 AND low < fbBtm3 then
fbAct3 = 0
fbBrk3 = barindex
endif
if fsAct0 = 1 AND fsLft0 > 0 AND high > fsTop0 then
fsAct0 = 0
fsBrk0 = barindex
endif
if fsAct1 = 1 AND fsLft1 > 0 AND high > fsTop1 then
fsAct1 = 0
fsBrk1 = barindex
endif
if fsAct2 = 1 AND fsLft2 > 0 AND high > fsTop2 then
fsAct2 = 0
fsBrk2 = barindex
endif
if fsAct3 = 1 AND fsLft3 > 0 AND high > fsTop3 then
fsAct3 = 0
fsBrk3 = barindex
endif
endif


// =====================================================
// MODULE 3: DISPLACEMENT
// =====================================================
if showDispl then
if isDispUp = 1 OR isDispDn = 1 then
dpBar0 = dpBar1
dpPrc0 = dpPrc1
dpDir0 = dpDir1
dpBar1 = dpBar2
dpPrc1 = dpPrc2
dpDir1 = dpDir2
dpBar2 = dpBar3
dpPrc2 = dpPrc3
dpDir2 = dpDir3
dpBar3 = dpBar4
dpPrc3 = dpPrc4
dpDir3 = dpDir4
dpBar4 = barindex
if isDispUp = 1 then
dpDir4 = 1
dpPrc4 = low - atrOff
else
dpDir4 = -1
dpPrc4 = high + atrOff
endif
if dpCnt < 5 then
dpCnt = dpCnt + 1
endif
endif
endif


// =====================================================
// MODULE 4: VOLUME IMBALANCE
// =====================================================
if showVI AND barindex >= 2 then
if close[1] >= open[1] then
prevBdTop = close[1]
prevBdBtm = open[1]
else
prevBdTop = open[1]
prevBdBtm = close[1]
endif


viBull = 0
viBear = 0
if open > prevBdTop AND high[1] > low AND close > close[1] AND open > open[1] AND high[1] < bdBtm then
viBull = 1
endif
if open < prevBdBtm AND low[1] < high AND close < close[1] AND open < open[1] AND low[1] > bdTop then
viBear = 1
endif


if viBull then
viTop1 = viTop0
viBtm1 = viBtm0
viLBar1 = viLBar0
viTop0 = prevBdTop
viBtm0 = bdBtm
viLBar0 = barindex - 1
if viCnt < 2 then
viCnt = viCnt + 1
endif
endif
if viBear then
viTop1 = viTop0
viBtm1 = viBtm0
viLBar1 = viLBar0
viTop0 = bdTop
viBtm0 = prevBdBtm
viLBar0 = barindex - 1
if viCnt < 2 then
viCnt = viCnt + 1
endif
endif
endif


// =====================================================
// MODULE 5: ORDER BLOCKS
// =====================================================
if showOB AND barindex >= obLen + 2 then
// Separate swing detector for OB
obUpper = highest[obLen](high)
obLower = lowest[obLen](low)
if high[obLen] > obUpper then
obOsNew = 0
elsif low[obLen] < obLower then
obOsNew = 1
else
obOsNew = obOs
endif


// Detect new swing high (os changes from 1 to 0)
if obOsNew = 0 AND obOs = 1 then
obTopY = high[obLen]
obTopX = barindex - obLen
obTopCr = 0
endif
// Detect new swing low (os changes from 0 to 1)
if obOsNew = 1 AND obOs = 0 then
obBtmY = low[obLen]
obBtmX = barindex - obLen
obBtmCr = 0
endif
obOs = obOsNew


// --- Bullish OB: close breaks above swing high ---
if close > obTopY AND obTopCr = 0 AND obTopX > 0 then
obTopCr = 1
obSearchLen = barindex - obTopX - 1
if obSearchLen > 0 then
obMinima = bdBtm
obMaxima = bdTop
obOBLoc = barindex
for si = 1 to obSearchLen do
if close[si] >= open[si] then
siBtm = open[si]
siTop = close[si]
else
siBtm = close[si]
siTop = open[si]
endif
if siBtm < obMinima then
obMinima = siBtm
obMaxima = siTop
obOBLoc = barindex - si
endif
next
obBTop = obMaxima
obBBtm = obMinima
obBLoc = obOBLoc
obBBrk = 0
obBBrkLoc = -1
endif
endif


// --- Bearish OB: close breaks below swing low ---
if close < obBtmY AND obBtmCr = 0 AND obBtmX > 0 then
obBtmCr = 1
obSearchLen = barindex - obBtmX - 1
if obSearchLen > 0 then
obMaxima = bdTop
obMinima = bdBtm
obOBLoc = barindex
for si = 1 to obSearchLen do
if close[si] >= open[si] then
siBtm = open[si]
siTop = close[si]
else
siBtm = close[si]
siTop = open[si]
endif
if siTop > obMaxima then
obMaxima = siTop
obMinima = siBtm
obOBLoc = barindex - si
endif
next
obSTop = obMaxima
obSBtm = obMinima
obSLoc = obOBLoc
obSBrk = 0
obSBrkLoc = -1
endif
endif


// --- Breaker detection ---
// Bull OB broken: close below OB bottom
if obBBrk = 0 AND obBLoc > 0 then
if bdBtm < obBBtm then
obBBrk = 1
obBBrkLoc = barindex
endif
endif
// If breaker and close above OB top: invalidate
if obBBrk = 1 AND obBLoc > 0 then
if close > obBTop then
obBLoc = -1
endif
endif
// Bear OB broken: close above OB top
if obSBrk = 0 AND obSLoc > 0 then
if bdTop > obSTop then
obSBrk = 1
obSBrkLoc = barindex
endif
endif
if obSBrk = 1 AND obSLoc > 0 then
if close < obSBtm then
obSLoc = -1
endif
endif
endif


// =====================================================
// MODULE 6: KILLZONES (backgroundcolor)
// =====================================================
if showKZ then
curTime = hour * 100 + minute
kzA = 18
if curTime >= kzNY1 AND curTime < kzNY2 then
backgroundcolor(255, 93, 0, kzA)
endif
if curTime >= kzLO1 AND curTime < kzLO2 then
backgroundcolor(0, 188, 212, kzA)
endif
if curTime >= kzLC1 AND curTime < kzLC2 then
backgroundcolor(33, 87, 243, kzA)
endif
if kzAS1 < kzAS2 then
if curTime >= kzAS1 AND curTime < kzAS2 then
backgroundcolor(233, 30, 99, kzA)
endif
else
if curTime >= kzAS1 OR curTime < kzAS2 then
backgroundcolor(233, 30, 99, kzA)
endif
endif
endif


// =====================================================
// DRAWING
// =====================================================
if islastbarupdate then


// --- MSS/BOS colors ---
if mssDir >= 1 then
mR = 0
mG = 230
mB = 161
mOff2 = atrOff
else
mR = 230
mG = 4
mB = 0
mOff2 = 0 - atrOff
endif


// --- Draw MSS ---
if showMS AND mssSBar > 0 then
drawsegment(mssSBar, mssLvl, mssBBar, mssLvl) coloured(mR, mG, mB) style(line, 2)
midM = round((mssSBar + mssBBar) / 2)
drawtext("MSS", midM, mssLvl + mOff2) coloured(mR, mG, mB)
endif


// --- Draw BOS ---
if showMS AND bosCnt >= 1 AND bosSB0 > 0 then
drawsegment(bosSB0, bosLvl0, bosBB0, bosLvl0) coloured(mR, mG, mB) style(dottedline, 1)
midB0 = round((bosSB0 + bosBB0) / 2)
drawtext("BOS", midB0, bosLvl0 + mOff2) coloured(mR, mG, mB)
endif
if showMS AND bosCnt >= 2 AND bosSB1 > 0 then
drawsegment(bosSB1, bosLvl1, bosBB1, bosLvl1) coloured(mR, mG, mB) style(dottedline, 1)
midB1 = round((bosSB1 + bosBB1) / 2)
drawtext("BOS", midB1, bosLvl1 + mOff2) coloured(mR, mG, mB)
endif


// --- Draw FVG Bull (4 slots) ---
if showFVG AND fbLft0 > 0 then
if fbAct0 = 1 then
drawrectangle(fbLft0, fbBtm0, barindex + 8, fbTop0) coloured(0, 230, 118) fillcolor(0, 230, 118, 25)
else
drawrectangle(fbLft0, fbBtm0, fbBrk0, fbTop0) coloured(128, 128, 0) fillcolor(128, 128, 0, 13)
endif
if fvgMode = 0 then
drawtext("FVG", fbLft0 + 1, (fbTop0 + fbBtm0) / 2) coloured(0, 230, 118)
else
drawtext("IFVG", fbLft0 + 1, (fbTop0 + fbBtm0) / 2) coloured(0, 230, 118)
endif
endif
if showFVG AND fbLft1 > 0 then
if fbAct1 = 1 then
drawrectangle(fbLft1, fbBtm1, barindex + 8, fbTop1) coloured(0, 230, 118) fillcolor(0, 230, 118, 25)
else
drawrectangle(fbLft1, fbBtm1, fbBrk1, fbTop1) coloured(128, 128, 0) fillcolor(128, 128, 0, 13)
endif
endif
if showFVG AND fbLft2 > 0 then
if fbAct2 = 1 then
drawrectangle(fbLft2, fbBtm2, barindex + 8, fbTop2) coloured(0, 230, 118) fillcolor(0, 230, 118, 25)
else
drawrectangle(fbLft2, fbBtm2, fbBrk2, fbTop2) coloured(128, 128, 0) fillcolor(128, 128, 0, 13)
endif
endif
if showFVG AND fbLft3 > 0 then
if fbAct3 = 1 then
drawrectangle(fbLft3, fbBtm3, barindex + 8, fbTop3) coloured(0, 230, 118) fillcolor(0, 230, 118, 25)
else
drawrectangle(fbLft3, fbBtm3, fbBrk3, fbTop3) coloured(128, 128, 0) fillcolor(128, 128, 0, 13)
endif
endif


// --- Draw FVG Bear (4 slots) ---
if showFVG AND fsLft0 > 0 then
if fsAct0 = 1 then
drawrectangle(fsLft0, fsBtm0, barindex + 8, fsTop0) coloured(255, 82, 82) fillcolor(255, 82, 82, 25)
else
drawrectangle(fsLft0, fsBtm0, fsBrk0, fsTop0) coloured(255, 0, 0) fillcolor(255, 0, 0, 13)
endif
if fvgMode = 0 then
drawtext("FVG", fsLft0 + 1, (fsTop0 + fsBtm0) / 2) coloured(255, 82, 82)
else
drawtext("IFVG", fsLft0 + 1, (fsTop0 + fsBtm0) / 2) coloured(255, 82, 82)
endif
endif
if showFVG AND fsLft1 > 0 then
if fsAct1 = 1 then
drawrectangle(fsLft1, fsBtm1, barindex + 8, fsTop1) coloured(255, 82, 82) fillcolor(255, 82, 82, 25)
else
drawrectangle(fsLft1, fsBtm1, fsBrk1, fsTop1) coloured(255, 0, 0) fillcolor(255, 0, 0, 13)
endif
endif
if showFVG AND fsLft2 > 0 then
if fsAct2 = 1 then
drawrectangle(fsLft2, fsBtm2, barindex + 8, fsTop2) coloured(255, 82, 82) fillcolor(255, 82, 82, 25)
else
drawrectangle(fsLft2, fsBtm2, fsBrk2, fsTop2) coloured(255, 0, 0) fillcolor(255, 0, 0, 13)
endif
endif
if showFVG AND fsLft3 > 0 then
if fsAct3 = 1 then
drawrectangle(fsLft3, fsBtm3, barindex + 8, fsTop3) coloured(255, 82, 82) fillcolor(255, 82, 82, 25)
else
drawrectangle(fsLft3, fsBtm3, fsBrk3, fsTop3) coloured(255, 0, 0) fillcolor(255, 0, 0, 13)
endif
endif


// --- Draw VI ---
if showVI AND viCnt >= 1 AND viLBar0 > 0 then
viR0 = viLBar0 + 4
drawsegment(viLBar0, viTop0, viR0, viTop0) coloured(6, 178, 208)
drawsegment(viLBar0 + 1, viBtm0, viR0, viBtm0) coloured(6, 178, 208)
drawtext("VI", viR0, (viTop0 + viBtm0) / 2) coloured(6, 178, 208)
endif
if showVI AND viCnt >= 2 AND viLBar1 > 0 then
viR1 = viLBar1 + 4
drawsegment(viLBar1, viTop1, viR1, viTop1) coloured(6, 178, 208)
drawsegment(viLBar1 + 1, viBtm1, viR1, viBtm1) coloured(6, 178, 208)
drawtext("VI", viR1, (viTop1 + viBtm1) / 2) coloured(6, 178, 208)
endif


// --- Draw Order Blocks ---
// Bullish OB
if showOB AND obBLoc > 0 then
if obBBrk = 0 then
// Active: line at bottom + label
drawsegment(obBLoc, obBBtm, barindex + 10, obBBtm) coloured(62, 137, 250) style(line, 2)
drawtext("+OB", barindex + 10, obBBtm - atrOff) coloured(62, 137, 250)
else
// Breaker: filled rectangle
drawrectangle(obBLoc, obBBtm, barindex + 10, obBTop) coloured(71, 133, 249) fillcolor(71, 133, 249, 38)
endif
endif
// Bearish OB
if showOB AND obSLoc > 0 then
if obSBrk = 0 then
drawsegment(obSLoc, obSTop, barindex + 10, obSTop) coloured(255, 49, 49) style(line, 2)
drawtext("-OB", barindex + 10, obSTop + atrOff) coloured(255, 49, 49)
else
drawrectangle(obSLoc, obSBtm, barindex + 10, obSTop) coloured(249, 255, 87) fillcolor(249, 255, 87, 38)
endif
endif


// --- Draw Liquidity ---
// Buyside
if showLiq AND lbCnt >= 1 AND lbStB0 > 0 AND lbBrk0 = 0 then
drawsegment(lbStB0, lbLnP0, barindex + 3, lbLnP0) coloured(250, 69, 28)
drawrectangle(lbStB0, lbBtm0, barindex + 3, lbTop0) coloured(250, 69, 28) fillcolor(250, 69, 28, 0)
drawtext("Buyside liq.", lbStB0, lbBtm0 - atrOff) coloured(250, 69, 28)
endif
if showLiq AND lbCnt >= 2 AND lbStB1 > 0 AND lbBrk1 = 0 then
drawsegment(lbStB1, lbLnP1, barindex + 3, lbLnP1) coloured(250, 69, 28)
drawrectangle(lbStB1, lbBtm1, barindex + 3, lbTop1) coloured(250, 69, 28) fillcolor(250, 69, 28, 0)
endif
// Sellside
if showLiq AND lsCnt >= 1 AND lsStB0 > 0 AND lsBrk0 = 0 then
drawsegment(lsStB0, lsLnP0, barindex + 3, lsLnP0) coloured(28, 228, 250)
drawrectangle(lsStB0, lsBtm0, barindex + 3, lsTop0) coloured(28, 228, 250) fillcolor(28, 228, 250, 0)
drawtext("Sellside liq.", lsStB0, lsTop0 + atrOff) coloured(28, 228, 250)
endif
if showLiq AND lsCnt >= 2 AND lsStB1 > 0 AND lsBrk1 = 0 then
drawsegment(lsStB1, lsLnP1, barindex + 3, lsLnP1) coloured(28, 228, 250)
drawrectangle(lsStB1, lsBtm1, barindex + 3, lsTop1) coloured(28, 228, 250) fillcolor(28, 228, 250, 0)
endif


// --- Draw Displacement ---
if showDispl then
if dpCnt >= 1 AND dpBar0 > 0 then
if dpDir0 = 1 then
drawpoint(dpBar0, dpPrc0, 3) coloured(0, 230, 118)
else
drawpoint(dpBar0, dpPrc0, 3) coloured(255, 82, 82)
endif
endif
if dpCnt >= 2 AND dpBar1 > 0 then
if dpDir1 = 1 then
drawpoint(dpBar1, dpPrc1, 3) coloured(0, 230, 118)
else
drawpoint(dpBar1, dpPrc1, 3) coloured(255, 82, 82)
endif
endif
if dpCnt >= 3 AND dpBar2 > 0 then
if dpDir2 = 1 then
drawpoint(dpBar2, dpPrc2, 3) coloured(0, 230, 118)
else
drawpoint(dpBar2, dpPrc2, 3) coloured(255, 82, 82)
endif
endif
if dpCnt >= 4 AND dpBar3 > 0 then
if dpDir3 = 1 then
drawpoint(dpBar3, dpPrc3, 3) coloured(0, 230, 118)
else
drawpoint(dpBar3, dpPrc3, 3) coloured(255, 82, 82)
endif
endif
if dpCnt >= 5 AND dpBar4 > 0 then
if dpDir4 = 1 then
drawpoint(dpBar4, dpPrc4, 3) coloured(0, 230, 118)
else
drawpoint(dpBar4, dpPrc4, 3) coloured(255, 82, 82)
endif
endif
endif


endif


return

Download
Filename: PRC_ICT-Concepts.itf
Downloads: 14
Iván González Master
Currently debugging life, so my bio is on hold. Check back after the next commit for an update.
Author’s Profile

Comments

Logo Logo
Loading...