Indicator

Liquidity Structure & Order Flow [UAlgo]Liquidity Structure & Order Flow is a range based market participation tool that combines a custom volume profile, value area analysis, liquidity void detection, and unusual volume tagging into a single chart overlay. Its goal is to show not only where volume has concentrated across price, but also how that activity was distributed between estimated buying pressure and selling pressure inside the recent market structure.
The script begins by scanning a rolling lookback range, then divides that vertical price space into a configurable number of bins. Each bin becomes a price segment that stores estimated buy volume, sell volume, and total volume. From there, the script builds a profile that highlights the Point of Control, the value area, and the internal order flow balance across the studied range.
What makes this indicator especially useful is that it does more than draw a standard profile. It also identifies areas where participation is abnormally thin relative to both the Point of Control and local neighboring bins. These low participation areas are marked as liquidity voids, helping the user see where the market moved through price with relatively little acceptance.
In addition, the script monitors the current bar for unusually large activity using a volume z score and a directional delta ratio filter. When a bar shows both exceptional size and meaningful directional imbalance, the script prints a bubble style marker above or below price. This gives the user a way to spot unusual participation events as they happen.
The result is a tool that can be used for profile analysis, liquidity mapping, imbalance recognition, and structural context. It helps answer several practical questions at once: where the market accepted price, where it rejected or skipped through price, where the strongest concentration of activity formed, and whether recent candles are showing exceptional directional participation.
🔹 Features
🔸 Custom Range Based Volume Profile
The script constructs a manual volume profile over the selected lookback period. Instead of relying on a built in profile engine, it divides the recent range into user defined price bins and allocates each bar’s volume into those bins. This gives full control over how the profile is built and how the final distribution is interpreted.
🔸 Buy Volume and Sell Volume Estimation
Every candle contributes both buy side and sell side estimates. The script uses the candle’s open, high, low, and close to derive a buy volume ratio, then splits total volume into buy volume and sell volume accordingly. This creates a practical order flow style approximation that is more informative than total volume alone.
🔸 Proportional Price Overlap Allocation
When a candle spans multiple bins, the script distributes its buy volume, sell volume, and total volume proportionally according to how much of the candle overlaps each bin. This produces a more realistic internal structure than simply dropping the full bar volume into one price row.
🔸 Point of Control Detection
The indicator finds the bin with the highest total volume and marks it as the Point of Control. This gives the user an immediate view of the strongest participation price inside the studied range.
🔸 Value Area Calculation
After the Point of Control is found, the script expands upward and downward through neighboring bins until the selected percentage of total profile volume is captured. This defines Value Area High and Value Area Low, allowing the user to distinguish the central acceptance region from the rest of the range.
🔸 Profile Coloring by Participation Side
The profile is drawn as stacked horizontal boxes showing estimated buy side participation and sell side participation inside each row. Bins inside the value area use stronger coloring, while bins outside the value area use softer coloring. This makes the internal structure easy to read visually.
🔸 Liquidity Void Detection
The script scans for bins with unusually weak participation outside the value area. A bin qualifies as a liquidity void candidate only if it is both small relative to the Point of Control and also weaker than its nearby neighbors. Consecutive weak bins are grouped into a larger void zone and labeled directly on the chart.
🔸 Unusual Volume Bubble Markers
Current bar activity is evaluated using a long period volume average and standard deviation. If the bar’s volume is statistically unusual and its estimated delta ratio is large enough, the script prints a directional bubble marker. Positive directional activity is shown below price, and negative directional activity is shown above price.
🔸 Optional Profile and Void Display
The user can independently control whether the volume profile, liquidity voids, and unusual volume markers are shown. This makes the script flexible enough for both full structure analysis and lighter chart layouts.
🔸 Extendable Structural Levels
The Point of Control, Value Area High, and Value Area Low can be drawn as either compact structure references or extended lines, depending on the chosen setting. This allows the user to decide whether the levels should function as local annotations or ongoing chart references.
🔸 Useful for Acceptance and Imbalance Analysis
The combination of profile structure, value area, void zones, and unusual activity markers gives the indicator a broader purpose than a standard profile. It can help identify accepted price, skipped price, directional participation, and possible future reaction areas.
🔹 Calculations
1) Building the Volume Profile Container
type PriceBin
float price
float buyVol = 0.0
float sellVol = 0.0
float totalVol = 0.0
type VolumeProfile
float highPrice = na
float lowPrice = na
float binSize = na
array bins
float pocPrice = na
float pocVol = 0.0
float vah = na
float val = na
float totalVol = 0.0
This is the foundation of the whole script.
Each PriceBin stores one price level area inside the profile. It contains:
the row midpoint price,
estimated buy volume,
estimated sell volume,
and total volume.
The VolumeProfile structure stores the full profile state:
the highest price of the lookback range,
the lowest price of the lookback range,
the bin size,
the array of bins,
and the final analytical values such as Point of Control, Value Area High, Value Area Low, and total profile volume.
So before any analysis happens, the script defines a complete custom data model for price distribution and order flow style estimation.
2) Initializing the Bins Across the Lookback Range
method initBins(VolumeProfile this, float h, float l, int numBins) =>
this.highPrice := h
this.lowPrice := l
this.binSize := (h - l) / numBins
this.pocPrice := na
this.pocVol := 0.0
this.totalVol := 0.0
this.vah := na
this.val := na
this.bins := array.new()
for i = 0 to numBins - 1
this.bins.push(PriceBin.new(price = l + i * this.binSize + (this.binSize / 2)))
This method creates the working profile rows.
First, it stores the high and low of the selected lookback period. Then it calculates binSize , which is the vertical price height of each row. That is simply the full range height divided by the number of bins.
After resetting all major profile outputs, the script creates a fresh bin array. Each new bin is assigned a midpoint price:
l + i * this.binSize + (this.binSize / 2)
That midpoint becomes the visual and analytical center of the row.
In practical terms, this is where the script transforms the raw market range into a structured ladder of price rows that can later receive allocated volume.
3) Locating the Correct Bin for a Price
method getBinIndex(VolumeProfile this, float p) =>
if na(this.lowPrice) or na(this.binSize) or this.binSize == 0
0
else
int idx = math.floor((p - this.lowPrice) / this.binSize)
math.max(0, math.min(idx, this.bins.size() - 1))
This helper method maps any price to its correct row index inside the profile.
It works by measuring how far the price sits above the profile low, then dividing that distance by the bin size. The result is the raw row index. After that, the value is clamped so it always stays inside the valid bin range.
This is important because the script repeatedly needs to know which rows are touched by each candle’s low and high. Without this mapping step, the profile could not distribute volume across price space correctly.
4) Estimating Buy Volume and Sell Volume From Candle Structure
float hlR = high - low
float bVR = hlR == 0 ? 0.5 : (close - low + high - open) / (2 * hlR)
float currentBuyVol = volume * bVR
float currentSellVol = volume * (1 - bVR)
float delta = currentBuyVol - currentSellVol
This snippet explains how the script approximates order flow direction on the current bar.
First, it measures the candle range from high to low. Then it computes a buy volume ratio using the relative location of the open and close inside that range:
(close - low + high - open) / (2 * hlR)
This ratio becomes a practical estimate of how much of the bar’s total volume behaved like buying pressure versus selling pressure. If the candle closes stronger and opens higher inside its range, the ratio leans more bullish. If the candle structure is weaker, the ratio leans more bearish.
That ratio is then used to split total volume into:
currentBuyVol
and
currentSellVol
Finally, the script calculates delta as the difference between estimated buy volume and estimated sell volume.
This is not true transaction tagged exchange delta, but it is a useful chart based directional participation model.
5) Distributing Candle Volume Across Touched Price Rows
method addBarVolume(VolumeProfile this, float h, float l, float c, float o, float v) =>
float hlRange = h - l
float buyVolRatio = hlRange == 0 ? 0.5 : (c - l + h - o) / (2 * hlRange)
float buyV = v * buyVolRatio
float sellV = v * (1 - buyVolRatio)
int startIdx = this.getBinIndex(l)
int endIdx = this.getBinIndex(h)
for i = startIdx to endIdx
if i >= 0 and i < this.bins.size()
PriceBin b = this.bins.get(i)
float binTop = b.price + (this.binSize / 2)
float binBot = b.price - (this.binSize / 2)
float overlapTop = math.min(h, binTop)
float overlapBot = math.max(l, binBot)
float overlap = math.max(0.0, overlapTop - overlapBot)
float weight = hlRange > 0 ? overlap / hlRange : (1.0 / (endIdx - startIdx + 1))
b.buyVol += buyV * weight
b.sellVol += sellV * weight
b.totalVol += v * weight
this.bins.set(i, b)
this.totalVol += v * weight
This is one of the most important calculations in the entire script.
For each candle inside the lookback period, the script first computes estimated buy volume and sell volume. Then it finds which profile rows are touched by the candle’s low and high.
For every touched row, it measures how much of the candle overlaps that specific row. That overlap becomes a weighting factor:
weight = overlap / hlRange
If a candle overlaps a row heavily, that row receives a larger share of the bar’s volume. If the overlap is small, the row receives only a small share.
The script then adds weighted buy volume, weighted sell volume, and weighted total volume into that bin.
This is much more realistic than assigning all volume to a single row because it respects the actual price space the candle traveled through.
6) Determining the Point of Control
method calcValueArea(VolumeProfile this, float pct) =>
float midPrice = (this.highPrice + this.lowPrice) / 2
float maxVol = -1.0
float bestPrice = na
int pocIdx = -1
for i = 0 to this.bins.size() - 1
PriceBin b = this.bins.get(i)
if b.totalVol > maxVol
maxVol := b.totalVol
bestPrice := b.price
pocIdx := i
else if b.totalVol == maxVol and maxVol > 0
if math.abs(b.price - midPrice) < math.abs(bestPrice - midPrice)
bestPrice := b.price
pocIdx := i
this.pocVol := maxVol
this.pocPrice := bestPrice
This is the first phase of the value area calculation.
The script scans all bins and finds the row with the greatest total volume. That row becomes the Point of Control. If two rows have the same maximum volume, the script breaks the tie by choosing the one closer to the middle of the full lookback range.
That tie handling matters because it avoids unstable selection when multiple bins have identical strength.
After the winning row is found, the script stores:
the Point of Control volume in pocVol
and the Point of Control price in pocPrice
So the Point of Control is not simply a visual midpoint. It is the actual strongest participation row in the profile.
7) Expanding Upward and Downward to Build the Value Area
float targetVol = this.totalVol * pct / 100.0
float currentVol = 0.0
if pocIdx >= 0 and pocIdx < this.bins.size()
currentVol := this.bins.get(pocIdx).totalVol
int upIdx = pocIdx + 1
int dnIdx = pocIdx - 1
while currentVol < targetVol and (upIdx < this.bins.size() or dnIdx >= 0)
float upVol = upIdx < this.bins.size() ? this.bins.get(upIdx).totalVol : -1.0
float dnVol = dnIdx >= 0 ? this.bins.get(dnIdx).totalVol : -1.0
After finding the Point of Control, the script calculates the target volume required for the value area. For example, if the input is 70 percent, the target becomes 70 percent of total profile volume.
The expansion begins from the Point of Control row itself. currentVol starts with the Point of Control row’s own total volume. Then the script looks one row up and one row down, repeatedly expanding until the accumulated volume reaches the target.
This is the standard logic of building a value area around the strongest participation center.
8) Deciding Whether to Expand Up or Down
if upVol > dnVol and upVol != -1.0
currentVol += upVol
upIdx += 1
else if dnVol > upVol and dnVol != -1.0
currentVol += dnVol
dnIdx -= 1
else if upVol == dnVol and upVol != -1.0
if currentVol + upVol > targetVol
if math.abs(this.bins.get(upIdx).price - midPrice) < math.abs(this.bins.get(dnIdx).price - midPrice)
currentVol += upVol
upIdx += 1
else
currentVol += dnVol
dnIdx -= 1
else
currentVol += upVol + dnVol
upIdx += 1
dnIdx -= 1
This block decides which side to include next in the value area.
If the row above has more volume than the row below, the script expands upward. If the row below has more volume, it expands downward. If both sides are equal, it uses distance to the overall midpoint as a tie breaker when necessary.
This is important because value area growth should follow participation strength, not arbitrary direction. The final result is a value area that naturally wraps around the highest volume concentration.
9) Final VAH and VAL Assignment
int finalUpIdx = math.max(pocIdx, upIdx - 1)
int finalDnIdx = math.min(pocIdx, dnIdx + 1)
this.vah := finalUpIdx < this.bins.size() ? this.bins.get(finalUpIdx).price : this.highPrice
this.val := finalDnIdx >= 0 ? this.bins.get(finalDnIdx).price : this.lowPrice
Once expansion is complete, the script converts the final included rows into value area boundaries.
The highest included row becomes Value Area High.
The lowest included row becomes Value Area Low.
These values define the central price zone where the chosen percentage of the profile’s total volume was traded.
So VAH and VAL are directly derived from the row by row structure of the profile, not from any fixed percentage of price range.
10) Detecting Unusual Volume Activity
float volSma = ta.sma(volume, 200)
float volStdev = ta.stdev(volume, 200)
float zScore = volStdev == 0 ? 0 : (volume - volSma) / volStdev
float deltaRatio = volume > 0 ? math.abs(delta) / volume : 0
bool isUnusual = zScore > zScoreThreshold and deltaRatio >= deltaRatioThreshold
This block evaluates whether the current bar is unusually active.
First, the script computes a 200 period average volume and standard deviation. Then it transforms the current bar’s volume into a z score, which shows how many standard deviations the bar stands above normal background activity.
Next, it calculates deltaRatio , which measures how large the directional imbalance is relative to total volume.
A bar is marked unusual only if both conditions are true:
the volume is statistically large enough,
and the directional imbalance is meaningful enough.
This double filter helps reduce false signals from large but directionless bars.
11) Printing Unusual Volume Bubbles
if showUnusual and isUnusual
string lblText = (delta > 0 ? "🟢 " : "🔴 ") + str.tostring(math.round(volume))
color lblColor = delta > 0 ? color.new(color.green, 0) : color.new(color.red, 0)
label uLbl = label.new(bar_index, delta > 0 ? low : high, text=lblText, style=label.style_none, textcolor=lblColor, yloc=delta > 0 ? yloc.belowbar : yloc.abovebar, size=size.small)
When an unusual bar is detected, the script prints a directional marker.
If estimated delta is positive, the bubble is shown below price in green.
If estimated delta is negative, the bubble is shown above price in red.
The displayed text also includes the rounded volume value. This allows the user to quickly see both direction and size of the unusual participation event.
So these markers are not random momentum tags. They specifically highlight bars where both participation size and directional imbalance stand out.
12) Rebuilding the Profile on the Last Bar
float highestPrice = ta.highest(high, lookback)
float lowestPrice = ta.lowest(low, lookback)
if barstate.islast and bar_index >= lookback - 1
profile.initBins(highestPrice, lowestPrice, rows)
for i = 0 to lookback - 1
profile.addBarVolume(high , low , close , open , volume )
profile.calcValueArea(vaPct)
This is the main execution block for the profile.
First, the script finds the highest high and lowest low across the chosen lookback window. That defines the total vertical space of the analysis.
Then, on the last visible bar, it:
initializes the bins,
loops through every candle inside the lookback,
adds each candle’s weighted volume into the profile,
and finally calculates the value area.
Running this only on the last bar is efficient because the full profile is a visual structure based on the current lookback window. It does not need to be redrawn historically on every past bar.
13) Scaling and Drawing the Profile Histogram
float maxVol = profile.pocVol
float allVols = array.new_float()
for i = 0 to profile.bins.size() - 1
allVols.push(profile.bins.get(i).totalVol)
float avgVol = allVols.avg()
float stdVol = allVols.stdev()
float clampedMaxVol = math.max(math.min(maxVol, avgVol + (stdVol * 2)), 0.000001)
Before drawing the profile, the script prepares a safer scaling reference.
Instead of using raw Point of Control volume alone without adjustment, it clamps the maximum drawable scale using the average row volume plus two standard deviations. This helps prevent a single extreme row from making the rest of the profile look too compressed.
In practical terms, this means the visual histogram remains readable even when one row is exceptionally dominant.
14) Drawing Buy Side and Sell Side Inside Each Row
int buyLen = math.round((b.buyVol / b.totalVol) * (drawVol / clampedMaxVol) * profileWidth)
int sellLen = math.round((b.sellVol / b.totalVol) * (drawVol / clampedMaxVol) * profileWidth)
bool inVA = b.price <= profile.vah and b.price >= profile.val
bool isPocRow = math.abs(b.price - profile.pocPrice) <= profile.binSize * 0.5
int x1 = profileRight
int x2 = x1 - buyLen
if buyLen > 0
box bB = box.new(x1, topP, x2, botP, border_color=c_border, bgcolor=c_buy)
int x3 = x2
int x4 = x3 - sellLen
if sellLen > 0
box bS = box.new(x3, topP, x4, botP, border_color=c_border, bgcolor=c_sell)
This is the actual profile drawing logic.
For each row, the script determines how much of the row’s total activity came from estimated buy volume and how much came from estimated sell volume. It then converts those fractions into horizontal lengths.
The buy portion is drawn first, then the sell portion continues from the end of the buy section. This creates a stacked horizontal bar that reveals both total participation and internal directional composition.
The row also receives context coloring:
rows inside the value area use stronger color treatment,
and the Point of Control row can receive a distinct border.
So the histogram communicates three layers at once:
how much volume was traded there,
whether that row sits inside the value area,
and how that row’s activity was split between estimated buying and selling pressure.
15) Drawing POC, VAH, and VAL Lines
line pocL = line.new(lineStartX, profile.pocPrice, lineEndX, profile.pocPrice, color=col_poc, width=2, style=line.style_solid)
profileLines.push(pocL)
line vahL = line.new(lineStartX, profile.vah, lineEndX, profile.vah, color=col_vah, width=1, style=line.style_dashed)
profileLines.push(vahL)
line valL = line.new(lineStartX, profile.val, lineEndX, profile.val, color=col_val, width=1, style=line.style_dashed)
profileLines.push(valL)
Once the profile is built, the script draws the three most important structural references:
Point of Control,
Value Area High,
and Value Area Low.
These lines can behave as compact annotations near the profile or as broader structure references if extension is enabled.
This gives the user a quick way to read acceptance and central balance without needing to inspect every row manually.
16) Detecting Liquidity Voids
float voidLimit = profile.pocVol * (voidThreshold / 100.0)
bool inVoid = false
float voidStartPrice = na
for i = 0 to profile.bins.size() - 1
PriceBin b = profile.bins.get(i)
bool isOutsideVA = b.price > profile.vah or b.price < profile.val
This is the beginning of the liquidity void logic.
A row is never treated as a void candidate solely because its volume is small. The script first requires that the row be outside the value area. This matters because low volume inside the main acceptance zone does not carry the same meaning as low volume outside it.
The script also calculates voidLimit as a percentage of Point of Control volume. That creates a relative participation threshold tied to the strongest row in the profile.
17) Comparing Each Row to Its Neighbors
float sumNeighbors = 0.0
int nC = 0
for j = math.max(0, i - 2) to math.min(profile.bins.size() - 1, i + 2)
if j != i
sumNeighbors += profile.bins.get(j).totalVol
nC += 1
float localAvg = nC > 0 ? sumNeighbors / nC : 0.0
bool isGap = b.totalVol < (localAvg * 0.5)
bool isLowVol = b.totalVol < voidLimit
bool isVoid = isLowVol and isGap and isOutsideVA
This is the real filter that defines a liquidity void.
The script looks at nearby bins around the current row and calculates a local neighbor average. Then it applies two separate tests:
the row must be low relative to the Point of Control threshold,
and it must also be weak relative to its nearby neighbors.
Only if both are true, and the row is outside the value area, does the script classify it as a void.
This is important because it prevents the indicator from marking every low volume row as a void. A valid void must look weak both globally and locally.
18) Grouping Consecutive Void Rows Into Zones
if isVoid
if not inVoid
inVoid := true
voidStartPrice := b.price - (profile.binSize / 2)
else
if inVoid
inVoid := false
float voidEndPrice = b.price - (profile.binSize / 2)
float topCoord = math.max(voidStartPrice, voidEndPrice)
float botCoord = math.min(voidStartPrice, voidEndPrice)
box vBox = box.new(bar_index - lookback, topCoord, bar_index, botCoord, border_color=na, bgcolor=col_void)
Once a void row is detected, the script begins tracking a continuous void run. If the next row is also a void, the zone continues. When the run ends, the script closes the zone and draws a box covering the full void area.
This means the indicator does not plot isolated tiny marks for each row. Instead, it groups neighboring weak rows into a cleaner structure that better represents a meaningful liquidity gap.
That box is then labeled as a liquidity void, making the zone easy to identify visually. Indicator

Liquidity Depth [UAlgo]Liquidity Depth is a price distribution and participation map designed to show where market activity has concentrated across a recent trading range. Instead of focusing only on candle by candle direction, the script builds a structured profile of how volume has been allocated across price levels inside a rolling lookback window. The result is a visual depth curve that helps identify areas where buyers or sellers may have shown stronger relative presence.
The indicator works by taking the highest and lowest prices inside the selected lookback, dividing that range into evenly spaced bins, and then assigning bar volume into those bins using one of two distribution models. This transforms raw volume into a spatial map of activity, allowing traders to see where liquidity has accumulated rather than simply when it appeared.
A central strength of the script is that it separates participation into buy side and sell side estimates using candle direction as a practical heuristic. Bullish candles contribute to the buy side profile and bearish candles contribute to the sell side profile. While this is not exchange level bid ask data, it creates a highly usable approximation of directional participation that is often more intuitive for chart based analysis.
The profile is drawn directly on the chart as a right side structure with smoothed depth curves, shaded fills, a Point of Control line, contextual range framing, and automatically detected strong liquidity pockets. This makes the tool especially useful for traders who want to study where activity is clustering, where resistance or support may be forming, and which parts of the recent range are attracting stronger participation.
Because the output is overlay based and visually compact, Liquidity Depth can be used in a wide variety of workflows. It can complement trend analysis, help frame pullback entries, identify acceptance and rejection zones, or simply provide a clearer understanding of where recent market interest has been strongest.
🔹 Features
🔸 Price Range Liquidity Mapping
The script scans a rolling lookback window, identifies the active price range, and divides that space into a configurable number of bins. Each bin becomes a small price segment where participation is accumulated. This produces a clear distribution style view of liquidity across the full recent range.
🔸 Two Distribution Modes
The indicator supports two ways of assigning volume into the profile.
Close Bin places the full bar volume into the single bin that contains the closing price. This creates a sharper and more concentrated structure that emphasizes where bars finished.
Wick Spread distributes the bar volume evenly across all bins touched by the candle from low to high. This produces a broader and more spatially balanced profile that better represents the full path of the bar through price.
These two modes give the user control over whether the profile should be more precise and concentrated or more inclusive and range aware.
🔸 Buy Side and Sell Side Separation
The script maintains separate depth values for buying and selling participation. Bullish candles add volume to the buy side and bearish candles add volume to the sell side. This creates two distinct distribution curves that help reveal whether the lower part of the range is showing stronger buying interest or whether the upper part is attracting stronger selling interest.
🔸 Smoothed Liquidity Curves
Instead of plotting raw bin values only, the script applies curve smoothing to the side distributions. This creates a cleaner, more readable shape that reduces visual noise and highlights the underlying structure of participation. The result is a profile that feels fluid and analytical rather than fragmented.
🔸 Glow Enhanced Curve Rendering
The current build uses a glow style rendering around the main liquidity curves. This improves visual separation on the chart and makes strong participation bulges easier to recognize at a glance, especially when the profile is viewed on darker chart themes.
🔸 Automatic Strong Pocket Detection
One of the most practical parts of the script is its ability to detect strong liquidity pockets. These are clusters of consecutive bins where smoothed participation exceeds a chosen strength threshold. When found, the script highlights the zone and labels it as a strong buy pocket or strong sell pocket. These pockets can be useful for identifying areas of acceptance, defense, or possible future reaction.
🔸 Point of Control Highlighting
The indicator finds the price bin with the highest total participation and marks it as the Point of Control. This is the most active price area inside the profile and often serves as an important reference for equilibrium, attraction, or repeated interaction.
🔸 Range Frame and Midpoint Context
A visual frame is drawn around the active profile range, including the highest level, the lowest level, and the midpoint. This gives the distribution a clear structure and helps the user understand where participation is concentrated relative to the center of the recent range.
🔸 Side Summary Readout
The script prints a compact summary that shows estimated buy side and sell side percentages, along with total side volumes. This provides a quick interpretation layer so the user can understand the current balance of participation without needing to inspect each curve manually.
🔸 Theme Adaptive Colors
Colors are selected dynamically according to the chart background tone. This helps the profile remain readable across both light and dark themes while preserving clear differentiation between buy side, sell side, frame lines, and Point of Control.
🔸 Efficient Object Management
All boxes, lines, fills, and labels are refreshed on the last visible bar so the profile stays clean and up to date. Internal object arrays are actively cleared and rebuilt, which keeps the display organized and avoids uncontrolled accumulation of chart objects.
🔹 Calculations
1) Active Range Construction
The script begins by defining the working range from the highest high and lowest low across the selected lookback window. This creates the vertical space where the full profile will be built.
The total span is then divided into the configured number of bins, which creates evenly spaced price segments from the bottom of the range to the top. Each bin stores its lower boundary, upper boundary, midpoint, buy volume, sell volume, and total volume.
In practical terms, this means the indicator converts the recent market range into a structured ladder of price levels so activity can be measured spatially.
2) Bin Initialization
Once the range is known, every bin is reset and rebuilt. Each bin receives:
its lower boundary,
its upper boundary,
its midpoint,
and empty participation values for buy, sell, and total activity.
This reset process ensures that the profile always reflects only the current rolling window rather than carrying stale values from older bars.
3) Volume Assignment Logic
For every bar inside the lookback, the script reads the volume and determines whether the candle is bullish or bearish. From there, distribution depends on the selected mode.
With Close Bin , the full bar volume is assigned to the bin that contains the close. If the candle is bullish, that volume is counted on the buy side. If the candle is bearish, it is counted on the sell side.
With Wick Spread , the script finds every bin touched between the candle low and candle high. The bar volume is divided evenly across those crossed bins. That distributed share is then assigned entirely to the buy side for bullish candles or entirely to the sell side for bearish candles.
This approach creates a practical estimate of where participation occurred across price, while also preserving directional context.
4) Total Participation and Point of Control
After all bars are processed, each bin contains a buy volume, a sell volume, and a total volume equal to the sum of the two. The script then scans the full array of bins to find the highest total value. The bin with that maximum total becomes the Point of Control.
The Point of Control represents the most concentrated participation zone inside the profile and is drawn as a dedicated horizontal reference line.
5) Midpoint Split and Side Totals
The active range midpoint is calculated as the average of the range high and range low. This midpoint is used as the divider between the lower half and upper half of the profile.
For summary purposes, buy side totals are accumulated from bins at or below the midpoint, while sell side totals are accumulated from bins above the midpoint. The script also records the highest buy side bin value and the highest sell side bin value.
This design gives the profile a simple structural interpretation:
lower range strength is associated with buying participation,
upper range strength is associated with selling participation.
That makes the summary especially useful for understanding whether the range is showing stronger support style accumulation below or stronger supply style pressure above.
6) Smoothing Engine
To reduce jaggedness, the script smooths each side of the profile with a local weighted kernel built from five neighboring bins. The center bin carries the highest influence, adjacent bins carry moderate influence, and outer bins carry smaller influence.
The smoothed result is then blended with the raw bin value according to the user selected smoothing factor. A low smoothing value preserves more of the original structure, while a high smoothing value creates a softer and more continuous curve.
This process helps reveal the true shape of participation without overreacting to isolated bin spikes.
7) Curve Projection and Shape Refinement
Once a side is smoothed, its value is normalized against the maximum strength of that side. The normalized result is converted into horizontal width inside the selected profile width. This is what determines how far the curve extends to the right from its anchor point.
The script also applies an additional running refinement to the horizontal curve position from one bin to the next. This makes the drawn path more fluid and helps eliminate abrupt lateral jumps between neighboring levels.
The final effect is a polished depth curve that communicates intensity clearly while remaining visually smooth.
8) Strong Pocket Detection
Strong liquidity pockets are found by scanning for consecutive bins where normalized smoothed participation exceeds the pocket threshold.
For the upper half of the profile, the script searches for strong sell side runs.
For the lower half of the profile, the script searches for strong buy side runs.
When a qualifying run lasts for at least the minimum required number of bins, a zone is drawn across that price region and labeled accordingly. The horizontal size of the zone is linked to the peak strength found inside that run.
This means the pocket logic is not simply marking a single peak. It is identifying sustained participation clusters, which often carry more analytical value than isolated extremes.
9) Visual Frame and Range Guides
The script adds a top guide at the range high, a bottom guide at the range low, and a midpoint guide through the center of the profile. These references help the user interpret the shape of liquidity in relation to the broader active range.
A curve concentrated near the midpoint suggests balance or repeated acceptance.
A strong bulge in the upper section can imply stronger supply style participation.
A strong bulge in the lower section can imply stronger demand style participation.
10) Summary Metrics
The summary label presents estimated buy side and sell side percentages along with total side volumes. These percentages are derived from the midpoint based side totals described above.
This gives the user a fast read on the internal balance of the profile without needing to inspect the full shape manually. It is especially useful when comparing one instrument or one session structure to another. Indicator

HTF Candle Dynamics [LuxAlgo]The HTF Candle Dynamics indicator provides traders with a comprehensive view of Higher Timeframe (HTF) price action and volume distribution directly on their lower timeframe charts. By projecting the current developing HTF candle and its internal volume characteristics to the right of the price, users can maintain high-level context without switching tabs.
Note: Ensure the chart timeframe is lower than the selected HTF setting for the indicator to function correctly.
🔶 USAGE
This tool is designed to bridge the gap between execution timeframes and higher-level market structures. It is particularly useful for scalpers and day traders who need to stay aware of Daily or Weekly levels while trading on 1-minute or 5-minute charts.
🔹 HTF Candle Projection
Visualizes the current HTF period (e.g., Daily, Weekly) as a dynamic candle on the right side of the chart. It includes projections for the HTF Open, High, Low, and Close levels. These levels often act as significant psychological barriers where price might find support or resistance.
🔹 Intraday Volume Profile
Generates a volume profile specifically for the current HTF period. This allows traders to see where the most volume is being transacted within the developing candle. Identifying "High Volume Nodes" within the current HTF candle can signal where institutional interest is concentrated.
🔹 Dynamic POC Tracking
A polyline tracks the movement of the Point of Control (POC) throughout the HTF period, showing how the most traded price level has shifted over time. If the POC is trending upward alongside price, it confirms a healthy bullish trend; if price moves away from a static POC, it might indicate a potential mean reversion back to that high-volume level.
🔹 How to Use
Traders can utilize this indicator to align their intraday trades with the broader market direction:
Identifying Value : Use the Intraday Volume Profile to spot the Point of Control. If the price is trading above the POC, the market is currently in a premium zone for that HTF. If it is below, it may be considered "discounted" relative to the volume transacted so far.
Breakout Confirmation : When price breaks the High or Low of the projected HTF candle, traders look for volume expansion within the profile to confirm if the breakout has significant participation.
Mean Reversion : The Dynamic POC line acts as a magnet. If price overextends significantly from the POC line, traders often look for signs of exhaustion to play a move back toward the high-volume area.
🔶 DETAILS
The indicator uses security calls to fetch historical HTF data while calculating the current developing period in real-time. A dedicated status table ensures the selected HTF is valid relative to the chart timeframe to prevent calculation errors.
🔹 History Dashboard
The dashboard provides a statistical breakdown of the previous three HTF candles (T-1, T-2, T-3). This is crucial for "Contextual Trading." By seeing the OHLC values and Volume Delta of the previous periods, you can determine if the market is experiencing "Expansion" (increasing volume and candle size) or "Contraction" (decreasing volume and tighter ranges).
🔹 Volume Delta
The Volume Delta shown in the history dashboard is an approximation calculated by summing volume based on the direction of individual intraday candles.
🔶 SETTINGS
HTF Setting : Defines the timeframe for the candle projection and volume profile (default is "D").
Right Offset : Adjusts the horizontal position of the projected candle and labels to avoid overlapping with price.
Visuals : Full control over bullish/bearish colors, POC lines, and projection offsets.
Volume Profile : Toggle the profile visibility and customize the number of rows or the maximum width of the bars.
History Dashboard : Toggle the history dashboard and adjust its position (Top Right, Bottom Right, etc.) or size.
Indicator

KDE Value Clouds [LuxAlgo]The KDE Value Clouds indicator is a quantitative tool that uses Kernel Density Estimation (KDE) to visualize the statistical distribution of price action, identifying high-density "Value Clouds" where the market has spent the most time.
🔶 USAGE
The indicator highlights areas of price " fair value " by calculating the probability density of price across a user-defined lookback period. Traders can use these density clusters to identify significant support and resistance levels that are often invisible to standard trend-following indicators.
🔹 Value Clouds
The " Value Clouds " appear directly on the price chart as gradient boxes. These clouds highlight regions where the density of price action exceeds the 50th percentile of the total distribution.
High Density (Bright Colors): Indicates a "Balance Area" where the market has reached a temporary equilibrium. These often act as magnets for price.
Low Density (Gaps): Indicates "Inefficiency" or fast moves where the market did not spend much time. These areas are often revisited or "filled" later.
🔹 KDE Profile & POC
On the right side of the chart, a smooth horizontal profile represents the continuous density function. The KDE POC (Point of Control) is the single price level with the highest calculated density within the lookback period, serving as the ultimate "anchor" for the current market regime.
🔹 How to use
Traders can look for price to "stall" or range within the bright Value Clouds, as these represent accepted price levels. When price moves into a "Gap" (a low-density area), it often moves quickly until it reaches the next cloud.
The KDE POC can be used as a primary support or resistance level; a breakout above a high-density cloud often signals a shift in market sentiment, while a rejection at the edge of a cloud suggests the market is still in a balanced state.
🔶 DETAILS
🔹 KDE vs. Volume Profile
A standard Volume Profile relies on "bins" (rectangles) to count volume at specific price steps. This can create "jagged" profiles that change drastically depending on the chosen row size.
The KDE Value Clouds approach is different because it uses a continuous probability function. Every price point in the lookback period contributes a small "bell curve" of influence to the total profile. This allows for a much smoother and more mathematically sound representation of where " Value " actually resides, regardless of arbitrary bin sizes.
The core of this indicator relies on two primary mathematical concepts:
Gaussian Kernel Estimation: Instead of simply counting occurrences, the script applies a Gaussian weight to every price point. This results in a "smooth" profile that captures the true shape of the price distribution.
Silverman’s Rule of Thumb: To prevent the clouds from being too noisy or too blurry, the indicator uses Silverman’s rule to calculate an optimal " Bandwidth ." This bandwidth adapts based on the standard deviation of the price data, ensuring the visualization stays relevant across different volatility regimes.
🔶 SETTINGS
🔹 Main Settings
Lookback Period: The number of bars used to calculate the price density. A higher lookback provides a "macro" view of value, while a lower lookback focuses on recent rotations.
Bandwidth Multiplier: Adjusts the "smoothness" of the KDE curve. Increasing this value will make the clouds broader and smoother; decreasing it will make them more granular.
Precision (Steps): Defines the vertical resolution of the density calculation. Higher values result in a more detailed profile.
🔹 Visualization
High/Low Density Colors: Customizes the gradient used for both the side profile and the on-chart clouds.
Profile Width (%): Controls how far the KDE profile extends horizontally across the right side of the chart.
Show Value Cloud on Chart: Toggles the visibility of the background "clouds" that highlight high-density price zones.
Indicator

Anchored Clusters Volume Profile [LuxAlgo]The Anchored Clusters Volume Profile indicator utilizes K-Means clustering to categorize historical price action into distinct groups within a user-defined range and generates individual volume profiles for each detected cluster. This tool provides a unique perspective on volume distribution by isolating price behaviors based on proximity rather than strictly chronological order.
🔶 USAGE
The indicator identifies "clusters" of price activity within a selected range defined by a starting and ending date. Each cluster is assigned a unique color and its own horizontal volume profile, allowing traders to see where liquidity is most concentrated within specific price regimes.
🔹 Identifying Institutional Zones
Traders can use the Point of Control (POC) of high-volume clusters to identify significant institutional interest. Because the K-Means algorithm groups price action by density rather than time, a cluster's POC often represents a "fair value" level where significant exchange occurred. These dashed POC lines frequently act as robust support or resistance levels when price returns to them in the future.
🔹 Market Regime Detection
By observing the vertical distribution and overlap of clusters, traders can identify market phases. Overlapping clusters with high volume often indicate accumulation or distribution phases (sideways markets), whereas distinct, vertically separated clusters with lower volume gaps between them suggest a trending environment. A shift from multiple overlapping clusters to a new, isolated cluster can signal a breakout or the start of a new trend.
🔹 Precision Entry & Exits
Cluster boundaries and POC lines provide concrete levels for trade management. An entry can be sought when price retests a high-volume cluster POC, while stops can be placed outside the total price range of that specific cluster (the area covered by its volume profile). Conversely, targets can be set at the POC of the next major cluster above or below current price action.
🔹 Volume Conviction
The tool provides specific volume metrics that allow traders to gauge conviction. By comparing the "Total" volume label of one cluster against another, a trader can determine which price regime had more participation. A breakout into a price zone with a high-volume cluster suggests stronger conviction and a higher probability of the level holding compared to a zone with low total volume.
🔶 DETAILS
Unlike traditional anchored volume profiles that provide a single histogram, this script employs a K-Means clustering algorithm to segment the range. This process involves:
Identifying the specific range of bars between the user-selected Start Time and End Time .
Initializing "centroids" across the price range of that period.
Iteratively assigning each price bar to the nearest centroid based on the HLC2 (median) price.
Recalculating centroids based on the volume-weighted average price of the assigned bars.
Finalizing assignments after the specified number of iterations to ensure stable clusters.
By separating price action into these clusters, the tool helps identify high-interest zones that might be obscured by a single, traditional Volume Profile.
🔶 SETTINGS
🔹 Anchor Settings
Start Time / End Time : Sets the beginning and end of the analysis range. These use the "Confirm" feature, allowing you to select the range directly on the chart after adding the indicator or changing settings.
Range Highlight : Adjusts the color and transparency of the background shading that identifies the analyzed range.
🔹 Clustering Settings
Number of Clusters : Sets how many distinct price groups the algorithm should attempt to find (2 to 10).
K-Means Iterations : Controls the number of times the algorithm refines the cluster centers. Higher values can lead to more stable results.
🔹 Volume Profile Settings
Rows per Cluster VP : Defines the vertical resolution (number of bins) for each individual cluster's profile.
Max VP Width (Bars) : Sets the maximum horizontal length of the volume profile histograms.
VP Offset : Adjusts the horizontal spacing between the current bar and the start of the volume profiles.
Highlight Price Dots : Toggles the visibility of the colored dots on the price action to identify cluster assignments.
Dot Size : Adjusts the size of the cluster assignment dots on the chart, ranging from tiny to huge.
Indicator

Indicator

Indicator

Volume Profile + Pivot Levels [ChartPrime]⯁ OVERVIEW
Volume Profile + Pivot Levels combines a rolling volume profile with price pivots to surface the most meaningful levels in your selected lookback window. It builds a left-side profile from traded volume, highlights the session’s Point of Control (PoC) , and then filters pivot highs/lows so only those aligned with significant profile volume are promoted to chart levels. Each promoted level extends forward until price retests it—so your chart stays focused on levels that actually matter.
⯁ KEY FEATURES
Rolling Volume Profile (Period & Resolution)
Calculates a profile over the last Period bars (default 200). The profile is discretized into Volume Profile Resolution bins (default 50) between the highest high and lowest low inside the window. Each bin accumulates traded volume and is drawn as a smooth left-side polyline for compact, lightweight rendering.
HL = array.new()
// collect highs/lows over 'start' bars to define profile range
for i = 0 to start - 1
HL.push(high ), HL.push(low )
H = HL.max(), L = HL.min()
bin_size = (H - L) / bins
// accumulate per-bin volume
for i = 0 to bins - 1
for j = 0 to start - 1
if close >= (L + bin_sizei) - bin_size and close < (L + bin_size*(i+1)) + bin_size
Bins += volume
Delta-Aware Coloring
The script tracks up-minus-down volume across all period to compute a net Delta . The profile, PoC line, and PoC label adopt a teal tone when net positive, and maroon when net negative—an immediate read on buyer/seller dominance inside the window.
Point of Control (PoC) + Volume Label
Automatically marks the highest-volume bin as the PoC . A horizontal PoC line extends to the last bar, and a label shows the absolute volume at the PoC. Toggle visibility via PoC input.
Pivot Detection with Volume Filter
Identifies raw pivots using Length (default 10) on both sides of the bar. Each candidate pivot is then validated against the profile: only pivots that land within their bin and meet or exceed the Filter % threshold (percentage of PoC volume) are promoted to chart levels. This removes weak, low-participation pivots.
// pivot promotion when volume% >= pivotFilter
if abs(mid - p.value) <= bin_size and volPercent >= pivotFilter
// draw labeled pivot level
line.new(p.index - pivotLength, p.value, p.index + pivotLength, p.value, width = 2)
Forward-Extending, Self-Stopping Levels
Promoted pivot levels extend forward as dotted rays. As soon as price intersects a level (high/low straddles it), that level stops extending—so your chart doesn’t clutter with stale zones.
Concise Level Labels (Volume + %)
Each promoted pivot prints a compact label at the pivot bar with its bin’s absolute volume and percentage of PoC volume (ordering flips for highs vs. lows for quick read).
Lightweight Visuals
The volume profile is rendered as a smooth polyline rather than dozens of boxes, keeping charts responsive even at higher resolutions.
⯁ SETTINGS
Volume Profile → Period : Lookback window used to compute the profile (max 500).
Volume Profile → Resolution : Number of bins; higher = finer structure.
Volume Profile → PoC : Toggle PoC line and volume label.
Pivots → Display : Show/hide volume-validated pivot levels.
Pivots → Length : Pivot detection left/right bars.
Pivots → Filter % 0–100 : Minimum bin strength (as % of PoC) required to promote a pivot level.
⯁ USAGE
Read PoC direction/color for a quick net-flow bias within your window.
Prioritize promoted pivot levels —they’re backed by meaningful participation.
Watch for first retests of promoted levels; the line will stop extending once tested.
Adjust Period / Resolution to match your timeframe (scalps → higher resolution, shorter period; swings → lower resolution, longer period).
Tighten or loosen Filter % to control how selective the level promotion is.
⯁ WHY IT’S UNIQUE
Instead of plotting every pivot or every profile bar, this tool cross-checks pivots against the profile’s internal volume weighting . You only see levels where price structure and liquidity overlap—clean, data-driven levels that self-retire after interaction, so you can focus on what the market actually defends. Indicator

Indicator

Indicator
