What is the Demand Index?
The Demand Index is a complex technical indicator that combines price and volume data to provide insights into the forces of supply and demand driving an asset's price. Unlike simpler volume indicators, the Demand Index attempts to determine whether buying or selling pressure is truly dominant, accounting for various aspects of price movement (open, high, low, close) relative to volume. It was developed by James Sibbet and is known for its ability to sometimes signal price reversals before they become apparent in price action alone.
The Demand Index is plotted as an oscillator that fluctuates above and below a zero line. Generally:
- Positive values suggest accumulation or net buying pressure.
- Negative values suggest distribution or net selling pressure.
- Zero line crossovers can indicate shifts in market sentiment.
This indicator is primarily used to:
- Confirm trends: Strong positive readings confirm uptrends; strong negative readings confirm downtrends.
- Identify divergences: When price and the Demand Index move in opposite directions, it can be a potent signal for an impending trend reversal.
- Spot exhaustion/initiation: Extreme readings or returns to zero can indicate overextended moves or the beginning of new trends.
In Pine Script, implementing the Demand Index requires careful calculation of its various components, offering a sophisticated tool for pine script strategies focused on gauging market pressure.
Components and Calculation
The calculation of the Demand Index is quite intricate, combining multiple elements of price and volume for each period (bar). It typically involves the following steps:
- Midpoint Price Change (MP): Calculates the change in the midpoint of the price range from the previous bar's midpoint.
`MP = ((High + Low) / 2) - ((High[1] + Low[1]) / 2)` - Force Index Component (FIC): This is a daily force multiplier based on the relationship between the current close and the previous close, scaled by volume.
`FIC = (Close - Close[1]) * Volume` - Range Ratio (RR): Measures the ratio of the current bar's high-low range to the previous bar's high-low range.
`RR = (High - Low) / (High[1] - Low[1])` * Handle `High[1] - Low[1] == 0` to avoid division by zero. - Demand Index Raw Value: Combines these components with a moving average of the `FIC` and `Volume` components over a specified `length`. The exact formula can vary slightly across implementations, but generally:
`Demand Index Raw = (MP * RR * FIC) / (Sum of Volume over 'length' periods)` * Some implementations might use a more complex interaction of these values or involve a form of Money Flow Volume similar to Chaikin's indicators. The most common interpretation of the Demand Index is often a smoothed ratio of a form of price-volume accumulation to total volume.
For a common and simplified (but still complex) interpretation based on typical implementations, we approximate it by summing the positive and negative `(Close - Open)` * `Volume` over a period, and then normalizing.
A more standard approach (and what TradingView's built-in likely uses under the hood) often involves a complex mix of price and volume relations, often simplified to: `Demand Index = (Current Close - Previous Close) / Current Close * Current Volume` smoothed by an EMA. However, the true Sibbet Demand Index is more nuanced.
Given the complexity and variations, we will calculate based on a frequently cited formula involving `(Close - Open) * Volume` and smoothing, combined with ranges. Let's use a widely accepted calculation method:
* `UpEffort = math.max(0, Close - Open) * Volume`
* `DownEffort = math.max(0, Open - Close) * Volume`
* `Demand = Sum(UpEffort, length) - Sum(DownEffort, length)`
* `Supply = Sum(UpEffort, length) + Sum(DownEffort, length)`
* `Demand Index = (Demand / Supply)` (if Supply != 0) smoothed.
This is a variation often seen. The original Sibbet Demand Index is quite proprietary and complex. TradingView's built-in `ta.demandindex()` function will use its own internal, optimized version. Since the user asked for "Pine Script Demand Index", the best approach is to use the built-in function `ta.demandindex()` for accuracy and consistency with TradingView's platform, and explain its theoretical basis.
A common `length` for the Demand Index is 5 periods.
Basic Demand Index Implementation in Pine Script
Pine Script v5 provides a built-in function `ta.demandindex()` for calculating the Demand Index. This function handles the complex internal calculations for us.
//@version=5
indicator("My Demand Index", overlay=false) // overlay=false to plot in a separate pane
// Input for Demand Index length (smoothing period)
length = input.int(5, title="DI Length (Smoothing)", minval=1)
// Calculate Demand Index using the built-in function
// ta.demandindex() takes 'close', 'high', 'low', 'open', and 'volume' implicitly or as source.
// The built-in usually takes 'close' as default source and length for smoothing.
demandIndexValue = ta.demandindex(close, length) // Default source is `close`
// Plot the Demand Index line
plot(demandIndexValue, title="Demand Index", color=color.new(color.blue, 0), linewidth=2)
// Plot the Zero Line as a key reference point
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted)
// Optional: Add a signal line (e.g., an EMA of the Demand Index)
signalLength = input.int(9, title="Signal Line Length", minval=1)
demandIndexSignal = ta.ema(demandIndexValue, signalLength)
plot(demandIndexSignal, title="DI Signal Line", color=color.new(color.orange, 0), linewidth=1)
// Highlight zones above/below zero
fill(demandIndexValue, 0, color=color.new(color.lime, 90), title="Positive Demand")
fill(demandIndexValue, 0, color=color.new(color.red, 90), title="Negative Demand")
Practical Demand Index Trading Strategies
1. Zero-Line Crossovers (Bias Shift)
Crossovers of the zero line can indicate a shift in the balance of buying and selling pressure. When combined with price action, these can provide trend confirmation or early reversal signals.
- Bullish Signal: Demand Index crosses above the zero line. This suggests a shift to net buying pressure, often confirming an uptrend or signaling a potential bullish reversal.
- Bearish Signal: Demand Index crosses below the zero line. This suggests a shift to net selling pressure, often confirming a downtrend or signaling a potential bearish reversal.
//@version=5
strategy("DI Zero Line Crossover Strategy", overlay=true)
length = input.int(5, title="DI Length", minval=1)
signalLength = input.int(9, title="Signal Line Length", minval=1)
demandIndexValue = ta.demandindex(close, length)
demandIndexSignal = ta.ema(demandIndexValue, signalLength)
plot(demandIndexValue, "Demand Index", color.blue, display=display.pane_only)
plot(demandIndexSignal, "DI Signal Line", color.orange, display=display.pane_only)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted, display=display.pane_only)
// Long entry: DI crosses above zero (and optionally above its signal line)
longCondition = ta.crossover(demandIndexValue, 0) // or ta.crossover(demandIndexValue, demandIndexSignal)
// Short entry: DI crosses below zero (and optionally below its signal line)
shortCondition = ta.crossunder(demandIndexValue, 0) // or ta.crossunder(demandIndexValue, demandIndexSignal)
if (longCondition)
strategy.entry("Long DI Cross", strategy.long)
if (shortCondition)
strategy.entry("Short DI Cross", strategy.short)
// Basic exit: opposite signal
strategy.close("Long DI Cross", when=shortCondition)
strategy.close("Short DI Cross", when=longCondition)
2. Divergence (Key Reversal Signal)
Divergence between price and the Demand Index is often considered one of its most reliable signals, indicating a weakening trend and potential reversal, as the underlying demand/supply dynamics are not confirming the price action.
- Bullish Divergence: Price makes a lower low, but the Demand Index makes a higher low (or fails to make a significantly lower low). This implies that despite falling prices, underlying buying pressure is increasing, hinting at a potential upward reversal.
- Bearish Divergence: Price makes a higher high, but the Demand Index makes a lower high (or fails to make a significantly higher high). This implies that despite rising prices, underlying selling pressure is increasing, hinting at a potential downward reversal.
//@version=5
strategy("DI Divergence Strategy", overlay=true)
length = input.int(5, title="DI Length", minval=1)
demandIndexValue = ta.demandindex(close, length)
plot(demandIndexValue, "Demand Index", color.blue, display=display.pane_only)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted, display=display.pane_only)
// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This example looks for recent higher/lower swings in price and Demand Index.
// Bullish Divergence: Price lower low, DI higher low
bullishDiv = close < close[1] and close[1] < close[2] and demandIndexValue > demandIndexValue[1] and demandIndexValue[1] > demandIndexValue[2]
// Bearish Divergence: Price higher high, DI lower high
bearishDiv = close > close[1] and close[1] > close[2] and demandIndexValue < demandIndexValue[1] and demandIndexValue[1] < demandIndexValue[2]
// Plot shapes on the chart to indicate divergence
plotshape(bullishDiv, title="Bullish DI Divergence", location=location.belowbar, color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
plotshape(bearishDiv, title="Bearish DI Divergence", location=location.abovebar, color=color.new(color.red, 0), style=shape.triangledown, size=size.small)
if (bullishDiv)
strategy.entry("Long Divergence", strategy.long)
if (bearishDiv)
strategy.entry("Short Divergence", strategy.short)
// Basic exit after a few bars or on opposite signal
strategy.exit("Long Divergence Exit", from_entry="Long Divergence", profit=close*0.02, loss=close*0.01)
strategy.exit("Short Divergence Exit", from_entry="Short Divergence", profit=close*0.02, loss=close*0.01)
3. Extreme Readings and Return to Zero (Exhaustion/Initiation)
Sustained extreme positive or negative readings of the Demand Index can indicate overextended buying or selling pressure, and a return towards the zero line can signal a shift in momentum.
- Overbought/Exhaustion (Long): Demand Index reaches extreme positive levels (e.g., consistently high for the asset) and then starts to turn down towards zero. This might suggest buying pressure is exhausting.
- Oversold/Exhaustion (Short): Demand Index reaches extreme negative levels (e.g., consistently low for the asset) and then starts to turn up towards zero. This might suggest selling pressure is exhausting.
- Initiation: A strong move from zero into either positive or negative territory can signal the beginning of a new period of accumulation or distribution.
//@version=5
indicator("DI Extreme Readings & Return to Zero", overlay=true)
length = input.int(5, title="DI Length", minval=1)
demandIndexValue = ta.demandindex(close, length)
plot(demandIndexValue, "Demand Index", color.blue, display=display.pane_only)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted, display=display.pane_only)
// Define thresholds for "extreme" readings (adjust based on asset)
// These values are often small for Demand Index depending on how it's scaled
upperExtremeThreshold = input.float(0.1, title="Upper Extreme Threshold", minval=0.01, step=0.01)
lowerExtremeThreshold = input.float(-0.1, title="Lower Extreme Threshold", maxval=-0.01, step=0.01)
hline(upperExtremeThreshold, "Upper Extreme", color.new(color.green, 0), linestyle=hline.style_dashed, display=display.pane_only)
hline(lowerExtremeThreshold, "Lower Extreme", color.new(color.red, 0), linestyle=hline.style_dashed, display=display.pane_only)
// Conditions for extremes and return to zero
isExtremePositive = demandIndexValue > upperExtremeThreshold
isExtremeNegative = demandIndexValue < lowerExtremeThreshold
// Return to zero from positive extreme
returnToZeroFromPositive = isExtremePositive[1] and demandIndexValue < upperExtremeThreshold
// Return to zero from negative extreme
returnToZeroFromNegative = isExtremeNegative[1] and demandIndexValue > lowerExtremeThreshold
// Highlight backgrounds for visual clarity
bgcolor(isExtremePositive ? color.new(color.lime, 90) : na, title="Extreme Positive DI")
bgcolor(isExtremeNegative ? color.new(color.maroon, 90) : na, title="Extreme Negative DI")
// Alert conditions
alertcondition(returnToZeroFromPositive, "DI Returning from Positive", "Demand Index returning from extreme positive, potential reversal.")
alertcondition(returnToZeroFromNegative, "DI Returning from Negative", "Demand Index returning from extreme negative, potential reversal.")
Optimizing Demand Index Performance
To get the most from the Demand Index in Pine Script:
- Focus on Divergence: The Demand Index's most robust signals often come from divergences with price. These are reliable indicators of weakening trends.
- Parameter Tuning: The `length` parameter (commonly 5) smooths the indicator. Shorter lengths will make it more responsive but potentially noisy. Longer lengths will smooth it out, but introduce more lag. Experiment to find a balance for your trading style and asset.
- Combine with Price Action: Always confirm Demand Index signals with price action. A bullish divergence is stronger if price also forms a bullish reversal candlestick pattern or breaks a short-term resistance.
- Trend Context: Use the Demand Index in the context of the larger trend. In an uptrend, focus on bullish divergences and zero-line bounces for long entries. In a downtrend, focus on bearish divergences and zero-line rejections for short entries.
- Volume Data Quality: Since the Demand Index relies on volume, its effectiveness is dependent on reliable and consistent volume data.
- Use with Other Indicators: Pair Demand Index with trend-following indicators (e.g., Moving Averages, ADX) to confirm the overall market direction, or with volatility indicators to gauge market conditions.
Common Demand Index Pitfalls
- Complexity and Lag: Despite being a momentum oscillator, its calculation can introduce some lag, and its complexity means its exact behavior might require more study than simpler indicators.
- False Signals: In very choppy or low-volume markets, the Demand Index can generate ambiguous signals or whipsaws around the zero line.
- Subjective Interpretation of Extremes: There are no universally defined "overbought" or "oversold" levels for the Demand Index. What constitutes an "extreme" reading depends on the asset and its historical behavior, requiring manual observation and calibration.
- Volume Dependency: The accuracy and utility of the Demand Index are highly dependent on reliable volume data. Assets with inconsistent or low volume data might not provide useful readings.
- Not a Standalone Indicator: The Demand Index provides crucial insights but should never be used in isolation. It works best as a confirming or filtering indicator within a broader trading strategy.
Conclusion
The Demand Index is a sophisticated and highly insightful momentum oscillator available in Pine Script for TradingView. By uniquely combining price changes with volume to measure underlying buying and selling pressure, it offers traders a deeper understanding of market conviction and potential future price movements. While its greatest strength lies in identifying powerful divergences with price (signaling potential trend reversals), it also excels at confirming existing trends and validating shifts in market sentiment through its zero-line crossovers and extreme readings. By understanding its calculation, thoughtfully tuning its parameters, and integrating it strategically with price action and other technical analysis tools, you can leverage the Demand Index to enhance your pine script strategies and gain a clearer understanding of the forces driving market movement.
Enhance Your Trading
Get a high-performance Pine Script analysis tool for actionable market insights, designed for traders on the move.
This strategy runs in live mode on TradingView, helping you identify potential opportunities.
Subscribe now @ $99/month