OPEN-SOURCE SCRIPT
CVD Divergence & Absorption [UAlgo]

CVD Divergence & Absorption is a dual context indicator that combines a cumulative volume delta (CVD) oscillator with price pivot structure to detect three important signal classes: Regular Divergence, Hidden Divergence, and Absorption. The script is designed to help traders compare price movement against directional volume participation and identify moments where price and CVD disagree, or where price stalls at similar levels while CVD continues to expand or contract.
The indicator runs in a separate pane (overlay=false) and plots a continuous CVD line, while signal labels and price side connecting lines are projected onto the main chart using force_overlay=true. This gives a clean workflow where you can monitor the CVD series in its own panel and still see exact divergence locations directly on price.
A key strength of this script is its lower timeframe volume decomposition. Instead of assigning the full chart bar volume to a single direction, it samples lower timeframe candles through request.security_lower_tf(), classifies each sub candle as up volume or down volume based on its close versus open, and aggregates the result into a bar level delta. That delta is then accumulated into the running CVD value. This approach is practical, efficient, and more granular than a simple chart timeframe approximation.
The script also includes quality controls for signal validation:
Pivot based comparisons for both price and CVD
Minimum and maximum bar distance filters between pivot comparisons
Equal price tolerance for absorption detection
A line of sight filter that rejects visually obstructed divergences where intervening candles violate the connecting path
The result is a professional divergence framework focused on cleaner, more interpretable signals rather than high frequency marking of every pivot mismatch.
Educational tool only. Not financial advice.
🔹 Features
🔸 1) Lower Timeframe CVD Construction (LTF Volume Decomposition)
The script builds CVD using lower timeframe candles selected by the user through the Lower Timeframe (LTF) input. For each chart bar, it retrieves arrays of lower timeframe open, close, and volume values and computes a signed delta:
Up LTF candle (close > open) adds volume
Down LTF candle (close < open) subtracts volume
Neutral LTF candle contributes zero
This produces a more refined bar delta than a single bar directional assumption and makes the CVD line more responsive to intrabar rotation.
🔸 2) Pivot Based Signal Engine for Price and CVD
Signal generation is anchored to confirmed price pivots using user defined left and right pivot bars. A signal candidate is considered only when:
A price pivot high/low is confirmed by ta.pivothigh or ta.pivotlow
The CVD value at that pivot location also behaves like a local high/low (simple local extremum check)
This means the script does not compare arbitrary points. It compares structurally meaningful swing locations.
🔸 3) Regular Divergence Detection (Bullish and Bearish)
The indicator supports classic regular divergence logic:
Bullish Regular Divergence: price makes a lower low while CVD makes a higher low
Bearish Regular Divergence: price makes a higher high while CVD makes a lower high
These signals can indicate weakening trend continuation pressure and potential reversal behavior, depending on context.
🔸 4) Hidden Divergence Detection (Bullish and Bearish)
The script also detects hidden divergence, which many traders use as continuation style confirmation:
Bullish Hidden Divergence: price makes a higher low while CVD makes a lower low
Bearish Hidden Divergence: price makes a lower high while CVD makes a higher high
Hidden divergence is optional and can be toggled independently from regular divergence.
🔸 5) Absorption Detection with Equal Price Tolerance
Absorption logic is included to capture situations where price prints near equal pivots, but CVD continues moving in a direction that suggests aggressive participation is being absorbed at the level:
Bearish Absorption (at highs): price is approximately equal high, but CVD is higher
Bullish Absorption (at lows): price is approximately equal low, but CVD is lower
The Equal Price Tolerance % input allows the script to treat two pivots as "equal" within a configurable percentage band. This makes absorption detection adaptable across instruments with different volatility profiles.
🔸 6) Minimum / Maximum Pivot Distance Filters
To avoid weak or overly stale comparisons, the script enforces:
A minimum number of bars between pivots
A maximum lookback distance for valid pivot pairing
This helps reduce noisy signals from pivots that are too close together and prevents pairing pivots that are too far apart to be contextually useful.
🔸 7) Line of Sight Validation (Signal Quality Filter)
Before accepting a pivot comparison, the script checks whether the straight line connecting the two price pivots is "clear" from intervening candle violations:
For bearish (high based) comparisons, intervening highs must not cross above the connecting line
For bullish (low based) comparisons, intervening lows must not cross below the connecting line
This is a strong visual integrity filter. It avoids many cluttered or ambiguous divergence lines that would look invalid once drawn on the chart.
🔸 8) Dual Visualization on Price and CVD
When a signal is detected, the script draws:
A label on price ("Reg", "Hid", or "Abs")
A line connecting the two relevant price pivots on the main chart
A line connecting the corresponding CVD pivot values in the CVD pane
Line styles are used to distinguish signal types:
Solid for Regular Divergence
Dashed for Hidden Divergence
Dotted for Absorption
This synchronized plotting makes it easy to verify the signal logic visually.
🔸 9) Conflict Handling for Cleaner Labels
Absorption labels are intentionally suppressed when a Hidden Divergence signal is already active on the same side in the same event block:
bullAbs and not bullHidDiv
bearAbs and not bearHidDiv
This prevents duplicate labels on the same pivot and improves chart readability.
🔸 10) Lightweight Pivot Memory Management
The script stores historical pivot comparison points in separate arrays for highs and lows and caps them using a helper method (maxSize = 15). This keeps the logic efficient while preserving enough recent history for valid comparisons.
🔹 Calculations
1) Lower Timeframe Delta Aggregation
The script retrieves lower timeframe OHLCV arrays and computes bar delta by summing signed volume from each LTF candle:
Pine Script®
Pine Script®
Interpretation:
The script uses candle direction as a proxy for buying/selling pressure inside each chart bar.
This is an estimated delta model based on candle body direction, not true bid/ask tape delta.
2) CVD Accumulation
Bar delta is added into a running cumulative value stored inside a custom tracker object:
Pine Script®
The tracker persists across bars using:
Pine Script®
This design keeps both the CVD value and pivot histories in one structured container.
3) Price Pivot Detection
Price pivots are confirmed using standard left/right pivot logic:
Pine Script®
Because pivot confirmation occurs after i_right bars, signal labels and lines are placed at:
Pine Script®
This aligns the plotted signal with the actual pivot bar, not the confirmation bar.
4) CVD Pivot Confirmation at the Same Pivot Location
The script requires CVD to form a local extremum at the price pivot location using a simple 3-point comparison around currentCVD[i_right]:
Pine Script®
Then:
Pine Script®
This ensures price and CVD are compared on synchronized pivot events rather than unrelated timestamps.
5) Pivot Pair Selection with Distance Constraints
When a new pivot is confirmed, the script scans prior pivots of the same type (highs with highs, lows with lows) and applies:
i_min_bars as the minimum spacing
i_max_bars as the maximum valid distance
Pine Script®
This keeps comparisons within a user defined structural window.
6) Line of Sight Filter (Price Geometry Validation)
Before checking divergence conditions, the script verifies that the connecting price line is not invalidated by intervening candles.
For highs:
Pine Script®
For lows:
Pine Script®
Interpretation:
Bearish comparisons require a clean descending/ascending line between highs without intermediate highs breaking above it.
Bullish comparisons require a clean line between lows without intermediate lows breaking below it.
This is one of the script’s strongest anti-noise mechanisms.
7) Equal Price Tolerance for Absorption
The script calculates percentage difference between pivot prices and treats them as equal if the difference is within the tolerance:
Pine Script®
This enables absorption logic to work with approximate equal highs/lows instead of requiring perfect price matches, which are rare in live markets.
8) Bearish Signal Logic (Regular, Hidden, Absorption)
For pivot highs, the script compares a new pivot high against a historical pivot high after passing distance and line of sight checks.
Bearish Regular Divergence
Pine Script®
Meaning:
Price makes a higher high
CVD makes a lower high
Bearish Hidden Divergence
Pine Script®
Meaning:
Price makes a lower high
CVD makes a higher high
Bearish Absorption
Pine Script®
Meaning:
Price prints an approximately equal high
CVD pushes higher, suggesting buying effort is absorbed near the same price zone
9) Bullish Signal Logic (Regular, Hidden, Absorption)
For pivot lows, the script compares a new pivot low against a historical pivot low after passing distance and line of sight checks.
Bullish Regular Divergence
Pine Script®
Meaning:
Price makes a lower low
CVD makes a higher low
Bullish Hidden Divergence
Pine Script®
Meaning:
Price makes a higher low
CVD makes a lower low
Bullish Absorption
Pine Script®
Meaning:
Price prints an approximately equal low
CVD pushes lower, suggesting selling effort is absorbed near the same price zone
10) Signal Plotting and Visual Encoding
When a condition is confirmed, the script plots both price side and CVD side lines between the historical pivot and the new pivot, plus a compact label at the new pivot location.
Examples:
Pine Script®
Style mapping:
line.style_solid for Regular Divergence
line.style_dashed for Hidden Divergence
line.style_dotted for Absorption
11) Pivot History Storage and Capacity Control
Each confirmed pivot is stored in a side specific array (highs or lows) using a helper method:
Pine Script®
This preserves recent structural history for future comparisons while keeping memory usage controlled.
The indicator runs in a separate pane (overlay=false) and plots a continuous CVD line, while signal labels and price side connecting lines are projected onto the main chart using force_overlay=true. This gives a clean workflow where you can monitor the CVD series in its own panel and still see exact divergence locations directly on price.
A key strength of this script is its lower timeframe volume decomposition. Instead of assigning the full chart bar volume to a single direction, it samples lower timeframe candles through request.security_lower_tf(), classifies each sub candle as up volume or down volume based on its close versus open, and aggregates the result into a bar level delta. That delta is then accumulated into the running CVD value. This approach is practical, efficient, and more granular than a simple chart timeframe approximation.
The script also includes quality controls for signal validation:
Pivot based comparisons for both price and CVD
Minimum and maximum bar distance filters between pivot comparisons
Equal price tolerance for absorption detection
A line of sight filter that rejects visually obstructed divergences where intervening candles violate the connecting path
The result is a professional divergence framework focused on cleaner, more interpretable signals rather than high frequency marking of every pivot mismatch.
Educational tool only. Not financial advice.
🔹 Features
🔸 1) Lower Timeframe CVD Construction (LTF Volume Decomposition)
The script builds CVD using lower timeframe candles selected by the user through the Lower Timeframe (LTF) input. For each chart bar, it retrieves arrays of lower timeframe open, close, and volume values and computes a signed delta:
Up LTF candle (close > open) adds volume
Down LTF candle (close < open) subtracts volume
Neutral LTF candle contributes zero
This produces a more refined bar delta than a single bar directional assumption and makes the CVD line more responsive to intrabar rotation.
🔸 2) Pivot Based Signal Engine for Price and CVD
Signal generation is anchored to confirmed price pivots using user defined left and right pivot bars. A signal candidate is considered only when:
A price pivot high/low is confirmed by ta.pivothigh or ta.pivotlow
The CVD value at that pivot location also behaves like a local high/low (simple local extremum check)
This means the script does not compare arbitrary points. It compares structurally meaningful swing locations.
🔸 3) Regular Divergence Detection (Bullish and Bearish)
The indicator supports classic regular divergence logic:
Bullish Regular Divergence: price makes a lower low while CVD makes a higher low
Bearish Regular Divergence: price makes a higher high while CVD makes a lower high
These signals can indicate weakening trend continuation pressure and potential reversal behavior, depending on context.
🔸 4) Hidden Divergence Detection (Bullish and Bearish)
The script also detects hidden divergence, which many traders use as continuation style confirmation:
Bullish Hidden Divergence: price makes a higher low while CVD makes a lower low
Bearish Hidden Divergence: price makes a lower high while CVD makes a higher high
Hidden divergence is optional and can be toggled independently from regular divergence.
🔸 5) Absorption Detection with Equal Price Tolerance
Absorption logic is included to capture situations where price prints near equal pivots, but CVD continues moving in a direction that suggests aggressive participation is being absorbed at the level:
Bearish Absorption (at highs): price is approximately equal high, but CVD is higher
Bullish Absorption (at lows): price is approximately equal low, but CVD is lower
The Equal Price Tolerance % input allows the script to treat two pivots as "equal" within a configurable percentage band. This makes absorption detection adaptable across instruments with different volatility profiles.
🔸 6) Minimum / Maximum Pivot Distance Filters
To avoid weak or overly stale comparisons, the script enforces:
A minimum number of bars between pivots
A maximum lookback distance for valid pivot pairing
This helps reduce noisy signals from pivots that are too close together and prevents pairing pivots that are too far apart to be contextually useful.
🔸 7) Line of Sight Validation (Signal Quality Filter)
Before accepting a pivot comparison, the script checks whether the straight line connecting the two price pivots is "clear" from intervening candle violations:
For bearish (high based) comparisons, intervening highs must not cross above the connecting line
For bullish (low based) comparisons, intervening lows must not cross below the connecting line
This is a strong visual integrity filter. It avoids many cluttered or ambiguous divergence lines that would look invalid once drawn on the chart.
🔸 8) Dual Visualization on Price and CVD
When a signal is detected, the script draws:
A label on price ("Reg", "Hid", or "Abs")
A line connecting the two relevant price pivots on the main chart
A line connecting the corresponding CVD pivot values in the CVD pane
Line styles are used to distinguish signal types:
Solid for Regular Divergence
Dashed for Hidden Divergence
Dotted for Absorption
This synchronized plotting makes it easy to verify the signal logic visually.
🔸 9) Conflict Handling for Cleaner Labels
Absorption labels are intentionally suppressed when a Hidden Divergence signal is already active on the same side in the same event block:
bullAbs and not bullHidDiv
bearAbs and not bearHidDiv
This prevents duplicate labels on the same pivot and improves chart readability.
🔸 10) Lightweight Pivot Memory Management
The script stores historical pivot comparison points in separate arrays for highs and lows and caps them using a helper method (maxSize = 15). This keeps the logic efficient while preserving enough recent history for valid comparisons.
🔹 Calculations
1) Lower Timeframe Delta Aggregation
The script retrieves lower timeframe OHLCV arrays and computes bar delta by summing signed volume from each LTF candle:
array<float> ltf_open = request.security_lower_tf(syminfo.tickerid, i_ltf, open)
array<float> ltf_close = request.security_lower_tf(syminfo.tickerid, i_ltf, close)
array<float> ltf_volume = request.security_lower_tf(syminfo.tickerid, i_ltf, volume)
if ltf_c > ltf_o
totalDelta += ltf_v
else if ltf_c < ltf_o
totalDelta -= ltf_v
Interpretation:
The script uses candle direction as a proxy for buying/selling pressure inside each chart bar.
This is an estimated delta model based on candle body direction, not true bid/ask tape delta.
2) CVD Accumulation
Bar delta is added into a running cumulative value stored inside a custom tracker object:
method update_cvd(CVD_Tracker this, float delta) =>
this.currentCVD += delta
this.currentCVD
The tracker persists across bars using:
var CVD_Tracker tracker = CVD_Tracker.new(0.0, array.new<Pivot>(), array.new<Pivot>())
This design keeps both the CVD value and pivot histories in one structured container.
3) Price Pivot Detection
Price pivots are confirmed using standard left/right pivot logic:
float ph = ta.pivothigh(high, i_left, i_right)
float pl = ta.pivotlow(low, i_left, i_right)
Because pivot confirmation occurs after i_right bars, signal labels and lines are placed at:
bar_index - i_right
This aligns the plotted signal with the actual pivot bar, not the confirmation bar.
4) CVD Pivot Confirmation at the Same Pivot Location
The script requires CVD to form a local extremum at the price pivot location using a simple 3-point comparison around currentCVD[i_right]:
bool cvdIsPh = currentCVD[i_right] > currentCVD[i_right + 1] and currentCVD[i_right] > currentCVD[i_right - 1]
bool cvdIsPl = currentCVD[i_right] < currentCVD[i_right + 1] and currentCVD[i_right] < currentCVD[i_right - 1]
Then:
bool isPh = not na(ph) and cvdIsPh
bool isPl = not na(pl) and cvdIsPl
This ensures price and CVD are compared on synchronized pivot events rather than unrelated timestamps.
5) Pivot Pair Selection with Distance Constraints
When a new pivot is confirmed, the script scans prior pivots of the same type (highs with highs, lows with lows) and applies:
i_min_bars as the minimum spacing
i_max_bars as the maximum valid distance
if barsBetween < minBars
continue
if barsBetween > maxBars
break
This keeps comparisons within a user defined structural window.
6) Line of Sight Filter (Price Geometry Validation)
Before checking divergence conditions, the script verifies that the connecting price line is not invalidated by intervening candles.
For highs:
if barsBack >= 0 and high[barsBack] >= lineY
clear := false
For lows:
if barsBack >= 0 and low[barsBack] <= lineY
clear := false
Interpretation:
Bearish comparisons require a clean descending/ascending line between highs without intermediate highs breaking above it.
Bullish comparisons require a clean line between lows without intermediate lows breaking below it.
This is one of the script’s strongest anti-noise mechanisms.
7) Equal Price Tolerance for Absorption
The script calculates percentage difference between pivot prices and treats them as equal if the difference is within the tolerance:
float priceDiffPct = math.abs(newPivot.priceVal - histPivot.priceVal) / histPivot.priceVal * 100
bool isEqual = priceDiffPct <= eqTol
This enables absorption logic to work with approximate equal highs/lows instead of requiring perfect price matches, which are rare in live markets.
8) Bearish Signal Logic (Regular, Hidden, Absorption)
For pivot highs, the script compares a new pivot high against a historical pivot high after passing distance and line of sight checks.
Bearish Regular Divergence
newPivot.priceVal > histPivot.priceVal and not isEqual and newPivot.cvdVal < histPivot.cvdVal
Meaning:
Price makes a higher high
CVD makes a lower high
Bearish Hidden Divergence
newPivot.priceVal < histPivot.priceVal and not isEqual and newPivot.cvdVal > histPivot.cvdVal
Meaning:
Price makes a lower high
CVD makes a higher high
Bearish Absorption
isEqual and newPivot.cvdVal > histPivot.cvdVal
Meaning:
Price prints an approximately equal high
CVD pushes higher, suggesting buying effort is absorbed near the same price zone
9) Bullish Signal Logic (Regular, Hidden, Absorption)
For pivot lows, the script compares a new pivot low against a historical pivot low after passing distance and line of sight checks.
Bullish Regular Divergence
newPivot.priceVal < histPivot.priceVal and not isEqual and newPivot.cvdVal > histPivot.cvdVal
Meaning:
Price makes a lower low
CVD makes a higher low
Bullish Hidden Divergence
newPivot.priceVal > histPivot.priceVal and not isEqual and newPivot.cvdVal < histPivot.cvdVal
Meaning:
Price makes a higher low
CVD makes a lower low
Bullish Absorption
isEqual and newPivot.cvdVal < histPivot.cvdVal
Meaning:
Price prints an approximately equal low
CVD pushes lower, suggesting selling effort is absorbed near the same price zone
10) Signal Plotting and Visual Encoding
When a condition is confirmed, the script plots both price side and CVD side lines between the historical pivot and the new pivot, plus a compact label at the new pivot location.
Examples:
label.new(bar_index - i_right, low[i_right], text="Reg", ...)
line.new(bullLastPivot.loc, bullLastPivot.priceVal, bullNewPivot.loc, bullNewPivot.priceVal, ..., force_overlay=true)
line.new(bullLastPivot.loc, bullLastPivot.cvdVal, bullNewPivot.loc, bullNewPivot.cvdVal, ..., force_overlay=false)
Style mapping:
line.style_solid for Regular Divergence
line.style_dashed for Hidden Divergence
line.style_dotted for Absorption
11) Pivot History Storage and Capacity Control
Each confirmed pivot is stored in a side specific array (highs or lows) using a helper method:
method add_pivot(array<Pivot> this, Pivot p, int maxSize = 15) =>
this.push(p)
if this.size() > maxSize
this.shift()
This preserves recent structural history for future comparisons while keeping memory usage controlled.
오픈 소스 스크립트
트레이딩뷰의 진정한 정신에 따라, 이 스크립트의 작성자는 이를 오픈소스로 공개하여 트레이더들이 기능을 검토하고 검증할 수 있도록 했습니다. 작성자에게 찬사를 보냅니다! 이 코드는 무료로 사용할 수 있지만, 코드를 재게시하는 경우 하우스 룰이 적용된다는 점을 기억하세요.
Get exclusive indicators: pinescriptmarket.com
All content provided by UAlgo is for informational & educational purposes only. Past performance does not guarantee future results.
All content provided by UAlgo is for informational & educational purposes only. Past performance does not guarantee future results.
면책사항
해당 정보와 게시물은 금융, 투자, 트레이딩 또는 기타 유형의 조언이나 권장 사항으로 간주되지 않으며, 트레이딩뷰에서 제공하거나 보증하는 것이 아닙니다. 자세한 내용은 이용 약관을 참조하세요.
오픈 소스 스크립트
트레이딩뷰의 진정한 정신에 따라, 이 스크립트의 작성자는 이를 오픈소스로 공개하여 트레이더들이 기능을 검토하고 검증할 수 있도록 했습니다. 작성자에게 찬사를 보냅니다! 이 코드는 무료로 사용할 수 있지만, 코드를 재게시하는 경우 하우스 룰이 적용된다는 점을 기억하세요.
Get exclusive indicators: pinescriptmarket.com
All content provided by UAlgo is for informational & educational purposes only. Past performance does not guarantee future results.
All content provided by UAlgo is for informational & educational purposes only. Past performance does not guarantee future results.
면책사항
해당 정보와 게시물은 금융, 투자, 트레이딩 또는 기타 유형의 조언이나 권장 사항으로 간주되지 않으며, 트레이딩뷰에서 제공하거나 보증하는 것이 아닙니다. 자세한 내용은 이용 약관을 참조하세요.