OPEN-SOURCE SCRIPT
Volume Flow Anatomy [Kodexius]

Volume Flow Anatomy is a dynamic, multi-dimensional volume map that reconstructs how buy, sell, and “stealth” activity is distributed across price rather than just across time. Instead of relying on a static, session-based volume profile, it uses an exponentially decaying memory of recent bars to build a constantly evolving “anatomy” of the auction, where each price level carries an adaptive history of order flow.
The script separates buy vs. sell pressure, adds a third “Stealth Flow” dimension for low-volume price movement (ease of movement / divergence), and automatically derives POC, Value Area, imbalances, absorption zones, and classic profile shapes (D, P, b, B). This gives the trader a compact but highly information-dense map on the right side of the chart to read control (buyers vs. sellers), structure (balanced vs. trending vs. double distribution), and key reaction levels (support/resistance born from flow, not just wicks).

🔹 Features
🔸 Dynamic Lookback with Decay
- The script computes an effective lookback N from the Decay Factor and caps it with Max Lookback.
- Higher decay keeps more history; lower decay emphasizes the most recent flow.
- The profile continuously adapts as new bars are printed.
🔸 Price-Bucketed Flow Map
Each bucket accumulates:
- Sell Flow (sell pressure)
- Buy Flow (buy pressure)
- Stealth Flow (low-volume price movement)
- Box width at each bucket is proportional to the relative intensity of that component.

🔸 Stealth Flow (Low-Volume Price Movement)
- Measures close to close movement relative to volume, emphasizing price movement that occurs on comparatively low volume.
- Helps reveal hidden participation, inefficient moves, and areas that may be vulnerable to re-tests or reversions.
🔸 POC & 70% Value Area (VA)
- Identifies the Point of Control (price bucket with the highest total volume) over the effective lookback.
- Builds a 70% Value Area by expanding from POC towards the nearest high volume neighbors until 70% of the total volume is included.
- POC is drawn as a line over the analyzed range; VA is displayed as a shaded band in the profile area.

🔸 Market Profile Shape Detection
Splits the profile vertically into three zones (bottom / middle / top) and compares their volume distribution.
Classifies structure as:
- D-Shape (Balanced)
- P-Shape (Short Covering)
- b-Shape (Long Liquidation)
- B-Shape (Double Distribution)
Displays a shape label with color coded bias for quick auction context interpretation.

🔸 Imbalance Zones & Absorption
Imbalance: detects buckets where Buy Flow or Sell Flow exceeds the opposite side by at least Imbalance Ratio.
Absorption: flags zones with high volume but low price “ease”, where price is not moving much despite significant volume.
Extends these levels into horizontal zones, marking potential support/resistance and trap areas.
Bullish Imbalance Zone :

Bearish Imbalance Zone :

Absorption Zone :

🔸 Range Context & On-Chart Legend
Draws a Range Box covering the dynamically determined lookback (N bars), with a label displaying the effective bar count.
A bottom-right legend summarizes:
- Color keys for Buy / Sell / Stealth
- POC / VA status
- Bullish vs. Bearish dominance percentage
- Profile shape classification
- Imbalance and Absorption conventions

🔹 Calculations
1. Dynamic Lookback & Price Buckets
Pine Script®
The effective lookback N is derived from the Decay Factor, using the approximation 4 / (1 - decay) to capture roughly 99% of the decayed influence, then capped with maxHistory to control performance. Over that adaptive range, the script finds the highest and lowest prices and divides the band into bucketCount equal slices (bucketSize). Each slice is a price bucket that will accumulate volume-flow information.
2. Exponentially Decayed Volume Allocation
Pine Script®
This function is the core engine of the indicator. For a given price span and intensity, it checks every bucket for overlap, distributes the weight proportionally to the overlapping range, and before adding new value, decays the existing bucket content by decayFactor. This results in an exponentially weighted profile: recent activity dominates, while older levels retain a gradually fading footprint.
3. POC and 70% Value Area
Pine Script®
Pine Script®
First, totalProfile is built as the sum of buy and sell flow per bucket, and eaMax (the maximum total) is tracked for later normalization. The POC bucket (pocIdx) is simply the index with the highest totalProfile value.
To compute the 70% Value Area, the algorithm starts at the POC bucket and expands outward, each step adding either the upper or lower neighbor depending on which has more volume. This continues until the cumulative volume reaches 70% of totalSum. The result is a volume-driven VA, not necessarily symmetric around POC, which more accurately represents where the market has truly traded.
4. Market Profile Shape Classification
Pine Script®
The profile is split into bottom, middle, and top thirds. The script compares how much volume is concentrated in each and combines that with the relative location of POC. If both extremes are heavy and the middle light, it labels a B-Shape (double distribution). If the POC is high and the top dominates the bottom, it’s a P-Shape (short covering). If the POC is low and the bottom dominates, it’s a b-Shape (long liquidation). Otherwise, it defaults to a D-Shape (balanced). This provides a quick, at-a-glance assessment of auction structure.
5. Imbalances, Absorption & Zones
Pine Script®
Pine Script®
Pine Script®
Imbalances are identified where one side’s volume (buy or sell) exceeds the other by at least Imbalance Ratio. These buckets are marked as buy or sell imbalance zones, indicating aggressive participation from one side.
Absorption is detected by combining a high volume ratio (volRatio) with a low normalized stealth ratio (stRatio). High volume with limited price movement suggests that opposing orders are absorbing flow at that level. Both imbalance and absorption buckets are extended into horizontal zones from the start of the lookback to the current bar, visually emphasizing key support/resistance and liquidity areas.
6. Building Buy, Sell & Stealth Profiles
Pine Script®
Three arrays are used to store Sell Flow, Buy Flow, and Stealth Flow. Bars are processed from oldest to newest so that decay is applied in correct chronological order. For each bar, a volume density (volume / range) is calculated and distributed across the candle range. Bull candles feed buyProfile, bear candles feed sellProfile.
Stealth Flow computes the close-to-close move between consecutive bars, scaled by 1 / (1 + volume). Big moves on low volume produce high stealth values, which are then allocated across the move’s price span into stealthProfile. This yields a three-layer profile per price level: directional volume and stealthy price movement.
The script separates buy vs. sell pressure, adds a third “Stealth Flow” dimension for low-volume price movement (ease of movement / divergence), and automatically derives POC, Value Area, imbalances, absorption zones, and classic profile shapes (D, P, b, B). This gives the trader a compact but highly information-dense map on the right side of the chart to read control (buyers vs. sellers), structure (balanced vs. trending vs. double distribution), and key reaction levels (support/resistance born from flow, not just wicks).
🔹 Features
🔸 Dynamic Lookback with Decay
- The script computes an effective lookback N from the Decay Factor and caps it with Max Lookback.
- Higher decay keeps more history; lower decay emphasizes the most recent flow.
- The profile continuously adapts as new bars are printed.
🔸 Price-Bucketed Flow Map
Each bucket accumulates:
- Sell Flow (sell pressure)
- Buy Flow (buy pressure)
- Stealth Flow (low-volume price movement)
- Box width at each bucket is proportional to the relative intensity of that component.
🔸 Stealth Flow (Low-Volume Price Movement)
- Measures close to close movement relative to volume, emphasizing price movement that occurs on comparatively low volume.
- Helps reveal hidden participation, inefficient moves, and areas that may be vulnerable to re-tests or reversions.
🔸 POC & 70% Value Area (VA)
- Identifies the Point of Control (price bucket with the highest total volume) over the effective lookback.
- Builds a 70% Value Area by expanding from POC towards the nearest high volume neighbors until 70% of the total volume is included.
- POC is drawn as a line over the analyzed range; VA is displayed as a shaded band in the profile area.
🔸 Market Profile Shape Detection
Splits the profile vertically into three zones (bottom / middle / top) and compares their volume distribution.
Classifies structure as:
- D-Shape (Balanced)
- P-Shape (Short Covering)
- b-Shape (Long Liquidation)
- B-Shape (Double Distribution)
Displays a shape label with color coded bias for quick auction context interpretation.
🔸 Imbalance Zones & Absorption
Imbalance: detects buckets where Buy Flow or Sell Flow exceeds the opposite side by at least Imbalance Ratio.
Absorption: flags zones with high volume but low price “ease”, where price is not moving much despite significant volume.
Extends these levels into horizontal zones, marking potential support/resistance and trap areas.
Bullish Imbalance Zone :
Bearish Imbalance Zone :
Absorption Zone :
🔸 Range Context & On-Chart Legend
Draws a Range Box covering the dynamically determined lookback (N bars), with a label displaying the effective bar count.
A bottom-right legend summarizes:
- Color keys for Buy / Sell / Stealth
- POC / VA status
- Bullish vs. Bearish dominance percentage
- Profile shape classification
- Imbalance and Absorption conventions
🔹 Calculations
1. Dynamic Lookback & Price Buckets
int N = math.min(int(4 / (1 - decayFactor) - 1), maxHistory)
float priceHigh = ta.highest(high, N)
float priceLow = ta.lowest(low, N)
float bucketSize = (priceHigh - priceLow) / bucketCount
The effective lookback N is derived from the Decay Factor, using the approximation 4 / (1 - decay) to capture roughly 99% of the decayed influence, then capped with maxHistory to control performance. Over that adaptive range, the script finds the highest and lowest prices and divides the band into bucketCount equal slices (bucketSize). Each slice is a price bucket that will accumulate volume-flow information.
2. Exponentially Decayed Volume Allocation
addValue(array<float> profile, float weight, float minPrice, float maxPrice) =>
for j = 0 to bucketCount - 1
float bucketMin = priceLow + j * bucketSize
float bucketMax = bucketMin + bucketSize
float overlapMin = math.max(minPrice, bucketMin)
float overlapMax = math.min(maxPrice, bucketMax)
float overlapRange = overlapMax - overlapMin
if overlapRange > 0
profile.set(j, profile.get(j) * decayFactor + weight * overlapRange)
This function is the core engine of the indicator. For a given price span and intensity, it checks every bucket for overlap, distributes the weight proportionally to the overlapping range, and before adding new value, decays the existing bucket content by decayFactor. This results in an exponentially weighted profile: recent activity dominates, while older levels retain a gradually fading footprint.
3. POC and 70% Value Area
array<float> totalProfile = array.new<float>(bucketCount, 0)
for j = 0 to bucketCount - 1
float total = sellProfile.get(j) + buyProfile.get(j)
totalProfile.set(j, total)
if total > eaMax
eaMax := total
int pocIdx = 0
float pocVal = 0.0
for j = 0 to bucketCount - 1
if totalProfile.get(j) > pocVal
pocVal := totalProfile.get(j)
pocIdx := j
float totalSum = totalProfile.sum()
float targetSum = totalSum * 0.70
int vaLow = pocIdx
int vaHigh = pocIdx
float currentSum = pocVal
while currentSum < targetSum and (vaLow > 0 or vaHigh < bucketCount - 1)
float lowVal = vaLow > 0 ? totalProfile.get(vaLow - 1) : 0.0
float highVal = vaHigh < bucketCount - 1 ? totalProfile.get(vaHigh + 1) : 0.0
First, totalProfile is built as the sum of buy and sell flow per bucket, and eaMax (the maximum total) is tracked for later normalization. The POC bucket (pocIdx) is simply the index with the highest totalProfile value.
To compute the 70% Value Area, the algorithm starts at the POC bucket and expands outward, each step adding either the upper or lower neighbor depending on which has more volume. This continues until the cumulative volume reaches 70% of totalSum. The result is a volume-driven VA, not necessarily symmetric around POC, which more accurately represents where the market has truly traded.
4. Market Profile Shape Classification
float volTopThird = 0.0
float volMidThird = 0.0
float volBotThird = 0.0
int thirdIdx = int(bucketCount / 3)
for j = 0 to bucketCount - 1
float val = totalProfile.get(j)
if j < thirdIdx
volBotThird += val
else if j < thirdIdx * 2
volMidThird += val
else
volTopThird += val
float totalVolShape = totalProfile.sum()
string shapeStr = "D-Shape (Balanced)"
if (volTopThird > totalVolShape * 0.20) and (volBotThird > totalVolShape * 0.20) and (volMidThird < totalVolShape * 0.50)
shapeStr := "B-Shape (Double Dist)"
else
if pocIdx > bucketCount * 0.5 and volTopThird > volBotThird * 1.3
shapeStr := "P-Shape (Short Covering)"
else if pocIdx < bucketCount * 0.5 and volBotThird > volTopThird * 1.3
shapeStr := "b-Shape (Long Liquidation)"
else
shapeStr := "D-Shape (Balanced)"
The profile is split into bottom, middle, and top thirds. The script compares how much volume is concentrated in each and combines that with the relative location of POC. If both extremes are heavy and the middle light, it labels a B-Shape (double distribution). If the POC is high and the top dominates the bottom, it’s a P-Shape (short covering). If the POC is low and the bottom dominates, it’s a b-Shape (long liquidation). Otherwise, it defaults to a D-Shape (balanced). This provides a quick, at-a-glance assessment of auction structure.
5. Imbalances, Absorption & Zones
bool isBuyImb = showImb and sVal > 0 and (bVal / sVal >= imbRatio)
bool isSellImb = showImb and bVal > 0 and (sVal / bVal >= imbRatio)
float volRatio = eaMax > 0 ? tVal / eaMax : 0
float stRatio = esmRange > 0 ? (stVal - esmMin) / esmRange : 1.0
bool isAbsorp = showAbsorp and volRatio > 0.6 and stRatio < 0.25
if showImbZone
if isSellImb
zoneBoxes.push(box.new(bar_index - N + 1, bucketHi, bar_index + 1, bucketLo, ...))
if isBuyImb
zoneBoxes.push(box.new(bar_index - N + 1, bucketHi, bar_index + 1, bucketLo, ...))
if isAbsorp
zoneBoxes.push(box.new(bar_index - N + 1, bucketHi, bar_index + 1, bucketLo, ...))
Imbalances are identified where one side’s volume (buy or sell) exceeds the other by at least Imbalance Ratio. These buckets are marked as buy or sell imbalance zones, indicating aggressive participation from one side.
Absorption is detected by combining a high volume ratio (volRatio) with a low normalized stealth ratio (stRatio). High volume with limited price movement suggests that opposing orders are absorbing flow at that level. Both imbalance and absorption buckets are extended into horizontal zones from the start of the lookback to the current bar, visually emphasizing key support/resistance and liquidity areas.
6. Building Buy, Sell & Stealth Profiles
sellProfile := array.new<float>(bucketCount, 0)
buyProfile := array.new<float>(bucketCount, 0)
stealthProfile := array.new<float>(bucketCount, 0)
Three arrays are used to store Sell Flow, Buy Flow, and Stealth Flow. Bars are processed from oldest to newest so that decay is applied in correct chronological order. For each bar, a volume density (volume / range) is calculated and distributed across the candle range. Bull candles feed buyProfile, bear candles feed sellProfile.
Stealth Flow computes the close-to-close move between consecutive bars, scaled by 1 / (1 + volume). Big moves on low volume produce high stealth values, which are then allocated across the move’s price span into stealthProfile. This yields a three-layer profile per price level: directional volume and stealthy price movement.
Açık kaynak kodlu komut dosyası
Gerçek TradingView ruhuyla, bu komut dosyasının mimarı, yatırımcıların işlevselliğini inceleyip doğrulayabilmesi için onu açık kaynaklı hale getirdi. Yazarı tebrik ederiz! Ücretsiz olarak kullanabilseniz de, kodu yeniden yayınlamanın Topluluk Kurallarımıza tabi olduğunu unutmayın.
Feragatname
Bilgiler ve yayınlar, TradingView tarafından sağlanan veya onaylanan finansal, yatırım, alım satım veya diğer türden tavsiye veya öneriler anlamına gelmez ve teşkil etmez. Kullanım Koşulları bölümünde daha fazlasını okuyun.
Açık kaynak kodlu komut dosyası
Gerçek TradingView ruhuyla, bu komut dosyasının mimarı, yatırımcıların işlevselliğini inceleyip doğrulayabilmesi için onu açık kaynaklı hale getirdi. Yazarı tebrik ederiz! Ücretsiz olarak kullanabilseniz de, kodu yeniden yayınlamanın Topluluk Kurallarımıza tabi olduğunu unutmayın.
Feragatname
Bilgiler ve yayınlar, TradingView tarafından sağlanan veya onaylanan finansal, yatırım, alım satım veya diğer türden tavsiye veya öneriler anlamına gelmez ve teşkil etmez. Kullanım Koşulları bölümünde daha fazlasını okuyun.