Rate of Change (ROC)
I. What is ROC
The Rate of Change (ROC) is a momentum oscillator that measures the percentage change of the current price relative to the price periods ago. It is the normalized version of the Momentum indicator, converting absolute differences into percentage form so that assets with different price levels can be compared horizontally.
Historical Background
Like Momentum, ROC is one of the most original concepts in technical analysis with no single identifiable inventor. The concept of percentage price change (Price Rate of Change) runs throughout the entire history of financial analysis, from the earliest stock market analysis to modern quantitative trading. ROC remains a fundamental tool for measuring the speed of price movement. In academic finance, ROC is essentially the same concept as “simple return.”
Indicator Classification
- Type: Oscillator, displayed in a separate panel
- Category: Momentum
- Default Parameters: Period , data source is Close price
- Value Range: Unbounded, oscillates around zero (unit: %)
ROC(1) is essentially the daily return. ROC(5) is the weekly return, ROC(20) is the monthly return. In quantitative finance, ROC is the most fundamental measure of return.
II. Mathematical Principles and Calculation
Core Formula
Where:
- = current closing price
- = closing price periods ago
- = lookback period (default 10)
Equivalent form:
Relationship to Momentum
That is, ROC = Momentum / base period price x 100.
Step-by-Step Calculation Logic
- Determine lookback period (e.g., 10)
- Get current closing price and closing price periods ago
- Calculate difference:
- Divide by base period price:
- Multiply by 100 to get percentage
Value Interpretation
| ROC Value | Meaning |
|---|---|
| ROC = +5% | Current price is 5% higher than periods ago |
| ROC = 0 | Current price is unchanged from periods ago |
| ROC = -5% | Current price is 5% lower than periods ago |
In some academic applications and high-frequency strategies, logarithmic returns are used: . Logarithmic returns have the additivity property (multi-period returns can be summed directly), which is more convenient for statistical modeling.
III. Python Implementation
import numpy as np
import pandas as pd
def roc(close: pd.Series, period: int = 10) -> pd.Series:
"""
Calculate the Rate of Change (ROC)
Parameters
----------
close : pd.Series
Close price series
period : int
Lookback period, default 10
Returns
-------
pd.Series
ROC values (percentage)
"""
return ((close - close.shift(period)) / close.shift(period)) * 100
def roc_log(close: pd.Series, period: int = 10) -> pd.Series:
"""
Calculate logarithmic ROC (log return)
"""
return np.log(close / close.shift(period)) * 100
# ========== Usage Example ==========
if __name__ == "__main__":
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=120, freq="D")
price = 100 + np.cumsum(np.random.randn(120) * 1.0)
df = pd.DataFrame({
"date": dates,
"open": price + np.random.randn(120) * 0.3,
"high": price + np.abs(np.random.randn(120) * 0.6),
"low": price - np.abs(np.random.randn(120) * 0.6),
"close": price,
"volume": np.random.randint(1000, 10000, size=120),
})
df.set_index("date", inplace=True)
# Calculate ROC with different periods
df["ROC_5"] = roc(df["close"], period=5)
df["ROC_10"] = roc(df["close"], period=10)
df["ROC_20"] = roc(df["close"], period=20)
print("=== ROC Results (last 15 rows) ===")
print(df[["close", "ROC_5", "ROC_10", "ROC_20"]].tail(15).to_string())
# Zero line crossover signals
df["signal"] = np.where(
(df["ROC_10"] > 0) & (df["ROC_10"].shift(1) <= 0), 1,
np.where(
(df["ROC_10"] < 0) & (df["ROC_10"].shift(1) >= 0), -1, 0
)
)
print("\n=== Zero Line Crossover Signals ===")
signals = df[df["signal"] != 0]
print(signals[["close", "ROC_10", "signal"]].to_string())
# ROC extreme value statistics
print(f"\n=== ROC(10) Descriptive Statistics ===")
print(df["ROC_10"].describe().to_string())
# Compare with log ROC
df["ROC_10_log"] = roc_log(df["close"], period=10)
print("\n=== ROC vs Log ROC (last 5 rows) ===")
print(df[["ROC_10", "ROC_10_log"]].tail(5).to_string())
IV. Problems the Indicator Solves
1. Momentum Direction and Strength
- ROC > 0: Price has risen over the past periods, bullish momentum
- ROC < 0: Price has fallen over the past periods, bearish momentum
- Larger |ROC|: Stronger momentum
2. Zero Line Crossover Signals
| Signal | Condition | Meaning |
|---|---|---|
| Buy | ROC crosses above zero | Momentum shifts from bearish to bullish |
| Sell | ROC crosses below zero | Momentum shifts from bullish to bearish |
3. Extreme Value Alerts
By analyzing the historical distribution of ROC, extreme zones can be defined:
- ROC exceeds historical mean + 2 sigma — rising too fast, beware of pullback
- ROC below historical mean - 2 sigma — falling too fast, beware of bounce
4. Cross-Sectional Comparison and Ranking
ROC’s percentage form makes it ideal for horizontal comparison:
- Stocks with different price levels can be ranked by ROC (momentum stock selection)
- Different asset classes can compare ROC (asset rotation strategy)
5. Divergence Analysis
- Bearish Divergence: Price new high + ROC peak declining — upward speed decelerating
- Bullish Divergence: Price new low + ROC trough rising — downward speed decelerating
ROC is very sensitive to the base period price . If the price periods ago happened to be an extreme value (e.g., a flash crash low), the current ROC will be abnormally amplified. Watch out for this “base effect” to avoid being misled by false signals.
V. Advantages, Disadvantages, and Use Cases
Advantages
| Advantage | Description |
|---|---|
| Normalized | Percentage form eliminates the influence of price level |
| Comparable | Direct horizontal comparison across different assets |
| Intuitively clear | ROC = 5% has a meaning everyone can understand |
| Widely applicable | From technical analysis to quant factors, extremely broad usage |
Disadvantages
| Disadvantage | Description |
|---|---|
| Noisy | No built-in smoothing, short-term fluctuations affect signals |
| Base effect | Anomalous base period values cause ROC distortion |
| No boundaries | No fixed overbought/oversold thresholds |
| Simple signals | Relies solely on zero line crossovers, single signal dimension |
Use Cases
- Momentum stock selection: ROC is one of the most commonly used cross-sectional momentum factors
- Asset rotation: Compare ROC across different assets, allocate to the strongest momentum assets
- Trend confirmation: As a filter condition for other strategies
- Component of composite indicators such as the Coppock Curve
Comparison with Related Indicators
| Comparison | ROC | Momentum | RSI | MACD |
|---|---|---|---|---|
| Output Form | Percentage | Absolute value | 0-100 | Absolute value |
| Normalized | Yes | No | Yes | No |
| Cross-comparable | Yes | No | Yes | No |
| Smoothing | None | None | Wilder | EMA |
| Signal Richness | Low | Low | High | High |
- Momentum stock selection formula: Go long on the top 10% of assets by 12-month ROC — this is a classic momentum factor strategy.
- Smoothing: Apply SMA(10) or EMA(10) smoothing to ROC before generating crossover signals.
- Base period check: Before trading, verify whether an abnormal price exists periods ago (ex-dividend, gap, etc.).
- Complement with Momentum: Use ROC for cross-sectional stock selection, and Momentum for single-asset longitudinal analysis.