ROC indicator: settings and signals
ROC is the percentage change in price over N bars — the most direct way to measure the speed of a market move.
What the indicator looks like on a real chart
Data: EUR/USD, daily bars, 2025-06-16 — 2026-07-20. The indicator is computed over 400 bars; the chart shows the last 180. Quote source: Binance Spot REST API (api.binance.com/api/v3/klines).
| Regime | Score |
|---|---|
| Trending market | 45 |
| Range | 39 |
| High volatility | 49 |
| Low volatility | 36 |
What the indicator actually measures
Unlike most indicators, ROC smooths nothing and does not normalize by volatility: it simply compares the current price with the price N bars ago. Because it is expressed in percent, the values are comparable between instruments of different price — a rare property among oscillators.
A zero-line cross literally means that price has returned to the level of N bars ago. This makes the indicator convenient for comparing relative strength: if two assets rose 3% and 8% over the same period, the second shows stronger momentum regardless of the absolute prices.
The flip side of no smoothing is sensitivity to the comparison base. If an anomalous spike fell N bars ago, ROC will show a sharp change today even though nothing happened in the market today. The effect is the same as a bar dropping out of the SMA window, but more pronounced.
Formula
The difference between the current price and the price N bars ago, divided by the price N bars ago and multiplied by 100. There is no smoothing in the formula — hence both the high sensitivity and the full transparency of the value.
Standard settings
| Parameter | Value |
|---|---|
| Standard period | 12 |
| Period for swing trading | 9 |
| Equilibrium level | 0% |
Period 12 is common for daily bars as an approximate analogue of two weeks. Longer periods (25, 50) are used to assess medium-term momentum and to compare the relative strength of different assets.
Implementation code (Python)
def roc(close, period=12):return 100 * (close - close.shift(period)) / close.shift(period)
When the indicator stops working
- The value depends entirely on one point in the past — the price N bars ago — which makes the indicator vulnerable to spikes in the comparison base.
- The absence of smoothing produces noticeable noise on low timeframes.
- It does not account for the path of price between the two points: a smooth 5% rise and a 5% rise through a deep drawdown give the same value.
Common mistakes in use
- Not checking what happened N bars ago. A sharp change in ROC is often explained by a spike in the base rather than by today's move.
- Using a zero-line cross as a standalone signal on a noisy instrument — on low timeframes it happens constantly.
- Confusing ROC with the percentage change over a session: the indicator always compares with the point N bars ago, not with the day's open.
- Comparing ROC values computed with different periods as if they measured the same thing.
Who needs this and why
Useful for comparing the relative strength of several instruments and for a quick assessment of whether a move is accelerating or fading. Good as a component of rotation strategies where assets are ranked by momentum.
Frequently asked questions
How does ROC differ from Momentum?
Momentum shows the absolute price difference, ROC shows the same difference in percent. The shape of the curves is identical, but percentages are comparable between instruments of different price, while absolute values are not.
Why did ROC change sharply without a price move?
Because the comparison base changed: the bar that was N periods ago left the calculation. If there was an anomalous spike there, its departure changes the indicator value while the current price is completely static.
Which period should I choose?
The period should match the decision horizon. To assess short-term momentum people take 9–12 bars, for medium-term relative strength 25–50. It is not advisable to mix ROC signals with different periods in one system without clearly separating their roles.