On-Balance Volume (OBV)
I. What is OBV
On-Balance Volume (OBV) is a technical analysis indicator first introduced by American investment analyst Joseph Granville in 1963 in his book Granville’s New Key to Stock Market Profits. OBV was one of the earliest indicators to systematically incorporate volume into technical analysis and holds landmark significance in the history of technical analysis.
OBV belongs to the Cumulative Volume category of indicators and has no parameters to configure. Its core philosophy originates from Granville’s classic assertion:
“Volume precedes price” — changes in volume often appear before changes in price.
The calculation logic of OBV is extremely simple: each day, based on whether the closing price is higher or lower than the previous day’s close, the current day’s volume is added to or subtracted from a running cumulative total. Volume on up days is treated as “buying power,” and volume on down days is treated as “selling power.” By observing the trend of the OBV curve and its relationship with price, traders can determine the direction of capital inflows and outflows.
The absolute value of OBV itself is meaningless — what matters is the direction and trend pattern of OBV changes, and whether divergence exists between OBV and price movements.
II. Mathematical Principles and Calculation
2.1 Core Formula
Let be the closing price and be the volume on day . The recursive formula for OBV is:
The initial value is typically set to or .
2.2 Intuitive Understanding
The essence of OBV is a signed cumulative volume:
- When price rises, the entire day’s volume is considered buying power and added to OBV
- When price falls, the entire day’s volume is considered selling power and subtracted from OBV
- When price is unchanged, OBV remains the same
The assumption of “all volume attributed to one side” is a simplification. In reality, every trade has both a buyer and a seller. The value of OBV lies in its ability to capture the core logic of the price-volume relationship in the simplest possible way.
2.3 Calculation Steps
- Set the initial OBV value (usually 0)
- Starting from day 2, compare each day’s closing price with the previous day’s closing price
- If up: add the day’s volume to OBV; if down: subtract the day’s volume from OBV; if unchanged: OBV stays the same
- This produces a continuous OBV curve
III. Python Implementation
import numpy as np
import pandas as pd
def on_balance_volume(close: pd.Series, volume: pd.Series) -> pd.Series:
"""
Calculate On-Balance Volume (OBV).
Parameters:
close : Series of close prices
volume : Series of volume
Returns:
Series of OBV values (cumulative volume)
"""
# Calculate price change direction: up +1, down -1, unchanged 0
direction = np.sign(close.diff())
# Set the first value to 0 (no comparison possible)
direction.iloc[0] = 0
# OBV = cumulative sum of directional volume
obv = (direction * volume).cumsum()
return obv
def obv_with_ema(close: pd.Series, volume: pd.Series,
signal_period: int = 20) -> pd.DataFrame:
"""
Calculate OBV and its EMA signal line.
Parameters:
close : Series of close prices
volume : Series of volume
signal_period : EMA period for the signal line, default 20
Returns:
DataFrame containing obv and obv_ema columns
"""
obv = on_balance_volume(close, volume)
obv_ema = obv.ewm(span=signal_period, adjust=False).mean()
return pd.DataFrame({
'obv': obv,
'obv_ema': obv_ema
})
# ============ Usage Example ============
if __name__ == '__main__':
np.random.seed(42)
n_days = 100
# Generate simulated OHLCV data
base_price = 100 + np.cumsum(np.random.randn(n_days) * 0.5)
df = pd.DataFrame({
'open': base_price + np.random.randn(n_days) * 0.3,
'high': base_price + np.abs(np.random.randn(n_days) * 0.8),
'low': base_price - np.abs(np.random.randn(n_days) * 0.8),
'close': base_price,
'volume': np.random.randint(100000, 1000000, n_days).astype(float)
})
# Calculate OBV and signal line
obv_df = obv_with_ema(df['close'], df['volume'], signal_period=20)
result = pd.concat([df[['close', 'volume']], obv_df], axis=1)
print("=== OBV Calculation Results (last 15 rows) ===")
print(result.tail(15).to_string())
# Determine OBV trend
result['obv_trend'] = np.where(result['obv'] > result['obv_ema'], 'Bullish', 'Bearish')
print("\n=== OBV Trend Statistics ===")
print(result['obv_trend'].value_counts())
# Detect OBV-price divergence (simple example)
price_higher = df['close'].iloc[-1] > df['close'].iloc[-20]
obv_higher = obv_df['obv'].iloc[-1] > obv_df['obv'].iloc[-20]
if price_higher and not obv_higher:
print("\nWarning: Bearish divergence detected -- price rising but OBV falling")
elif not price_higher and obv_higher:
print("\nWarning: Bullish divergence detected -- price falling but OBV rising")
else:
print("\nPrice and OBV are moving in the same direction, no divergence")
IV. Problems the Indicator Solves
4.1 Trend Confirmation
The most important use of OBV is confirming the validity of price trends:
- Price rising + OBV rising: The uptrend is supported by volume, the trend is reliable
- Price falling + OBV falling: The downtrend is confirmed by volume, the trend is reliable
- Price rising + OBV flat/falling: The rally lacks volume support, the trend may reverse
- Price falling + OBV flat/rising: Selling pressure is weakening, a rebound may be brewing
4.2 Divergence Signals — “Volume Precedes Price”
OBV divergence is the core application of Granville’s theory:
- Bearish Divergence: Price makes a new high but OBV does not — buying power is exhausted, warning of a decline
- Bullish Divergence: Price makes a new low but OBV does not — selling power is exhausted, warning of a rally
OBV divergences may persist for a considerable time before finally being “confirmed.” After a divergence appears, it is unwise to enter immediately. Wait for confirmation from price patterns (such as breakouts of support/resistance levels).
4.3 Breakout Confirmation
When price breaks through a key support or resistance level, observe whether OBV simultaneously breaks through its corresponding support or resistance level. If it does, the breakout is more reliable; if OBV fails to confirm, it may be a false breakout.
4.4 Typical Trading Strategies
- OBV Trend Following: Draw trendlines on OBV and use OBV trendline breakouts as trading signals
- OBV + Moving Average: Go long when OBV crosses above its EMA; go short when it crosses below
- Divergence Strategy: Take contrarian positions when divergences appear
- OBV Breakout Strategy: When OBV makes a new high/low, expect price to follow
V. Advantages, Disadvantages, and Use Cases
Advantages
| Advantage | Description |
|---|---|
| Extremely simple | No parameters required, calculation logic is concise and intuitive |
| Leading nature | ”Volume precedes price” — OBV changes typically appear before price changes |
| Effective trend confirmation | Price and volume moving in the same direction is an important sign of trend health |
| Long history, well-validated | Has undergone over half a century of market testing since 1963 |
Disadvantages
| Disadvantage | Description |
|---|---|
| All volume attributed to one side | Simplistically assigns the entire day’s volume to buyers or sellers, overly crude |
| Sensitive to gaps | Large gaps can cause misleading jumps in OBV |
| Absolute value meaningless | OBV values depend on the starting point, making cross-instrument or cross-period comparisons impossible |
| Noisy in range-bound markets | In trendless markets, OBV fluctuates frequently, reducing signal readability |
Use Cases
- Best suited for: Confirming trend strength and sustainability in trending markets
- Moderately suited for: Breakout confirmation alongside price pattern analysis
- Not suited for: Narrow range-bound markets (OBV will flip frequently); markets lacking reliable volume data
Comparison with Similar Indicators
| Indicator | Calculation Method | Characteristics |
|---|---|---|
| OBV | Full volume add/subtract | Simplest, intuitive signals, but crude |
| A/D Line | Weighted by close position | Considers intraday price position, more refined |
| CMF | Weighted period average | Bounded indicator, suitable for short-term buying/selling pressure |
| MFI | Volume-weighted oscillator | Bounded 0-100, similar to volume-weighted RSI |
Practical Advice: OBV works best when combined with price pattern analysis and moving averages. An effective combination is: when price breaks through a key resistance level, check whether OBV also breaks through its corresponding resistance — this dual confirmation can significantly improve the success rate of breakout trades.