Indicators/probuilder · probacktest · proorder · proscreener

ROC

ROC in ProBuilder returns the Rate of Change, the percentage difference between the current price and the price N bars ago. Syntax, formula, examples.

Syntax

probuilder
ROC[N](price)

Parameters

NameTypeDefaultDescription
NintegernoneLookback distance in bars. Common values are 12 and 25. Short values track fast momentum swings, long values track the broader cycle.
priceprice sourcecloseThe series measured, usually close, also open, high, low, or a custom variable.

Formula

code
ROC = ((price - price[N]) * 100) / price[N]

The current value minus the value N bars ago, divided by that past value, times 100. A reading of 5 means price is 5 percent above where it stood N bars earlier.

How it works

ROC is one of the simplest momentum oscillators. Each bar it answers a single question: by what percentage has price moved over the last N bars. Because the change is expressed as a percentage rather than in points, readings are comparable across instruments with different price levels, which is the main practical difference from Momentum, its point-based sibling.

The line oscillates around zero with no fixed upper or lower bound. Sustained positive readings characterise uptrends, sustained negative readings characterise downtrends, and the zero cross itself is a basic trend-change signal. Since ROC compares exactly two points, a large bar dropping out of the back of the window can move the indicator as much as a large bar arriving at the front, an effect worth remembering when a reading jumps without an obvious price move on the current bar.

Divergence analysis is the other standard use. When price prints a higher high but ROC prints a lower high, the advance is decelerating, and the mirror case applies at lows.

Examples

Example 1, Measuring acceleration between consecutive changes (Indicator)

probuilder
// One-bar rate of change on this bar and on the previous bar
i1 = ROC[1](close)
i2 = ROC[1](close[1])
// Ratio above 1 means the latest change is larger than the previous one
majorchange = i1 / i2
RETURN majorchange

Compares the latest one-bar percentage change with the one before it. The ratio gauges acceleration in price changes. Note that i2 equal to zero, a flat previous bar, produces a division by zero, so production code should guard the denominator.

Example 2, Momentum-filtered trend entry (ProOrder)

probuilder
DEFPARAM CumulateOrders = false

mom   = ROC[12](close)
trend = Average[100](close)

// Long when the 12-bar momentum turns positive above the trend average
IF NOT LongOnMarket AND close > trend AND mom CROSSES OVER 0 THEN
  BUY 1 CONTRACT AT MARKET
ENDIF

// Exit when momentum decays back through zero
IF LongOnMarket AND mom CROSSES UNDER 0 THEN
  SELL AT MARKET
ENDIF

The zero cross of a 12-bar ROC times entries and exits, while the 100-bar average restricts trading to the uptrend side.

Example 3, Screening for strong 20-bar movers (ProScreener)

probuilder
perf = ROC[20](close)
SCREENER[perf > 10](perf AS "ROC 20 %")

Returns instruments that have gained more than 10 percent over the last 20 bars, with the ROC value shown as a sortable column, a minimal momentum ranking screen.

Interpretation

ReadingMeaning
ROC > 0Price is above its level of N bars ago, upward momentum.
ROC < 0Price is below its level of N bars ago, downward momentum.
Extreme high readingPotentially overbought, price stretched relative to its recent past.
Extreme low readingPotentially oversold.
Bullish divergencePrice makes lower lows while ROC makes higher lows, downside momentum fading.
Bearish divergencePrice makes higher highs while ROC makes lower highs, upside momentum fading.

What counts as extreme depends on the instrument and N, since the indicator is unbounded. Volatile instruments routinely reach ROC levels that would be exceptional elsewhere, so thresholds need per-market calibration.

Common errors and gotchas

  • Division by zero in derived ratios. Expressions like ROC[1](close) / ROC[1](close[1]) fail whenever the earlier change is exactly zero. Guard denominators with a test against 0 before dividing.
  • Unbounded scale. Unlike RSI, ROC has no 0 to 100 range. Overbought and oversold thresholds copied from RSI logic, such as 30 and 70, are meaningless here.
  • Drop-off effect. The reading changes when an old extreme bar leaves the N-bar window even if the current price barely moves. Sudden ROC jumps do not always reflect fresh buying or selling.
  • Zero-cross whipsaw with small N. ROC[1] or ROC[2] flips sign constantly in quiet markets. Zero-cross systems need either a longer N or an additional trend filter.
  • RocnRoll, signal generator built on rate of change and exponential averages.
  • Momentum, the point-based equivalent, price minus price N bars ago.
  • RSI, bounded momentum oscillator with fixed thresholds.
  • Variation, percentage change between the previous close and the current close.
  • VolumeROC, the same rate-of-change calculation applied to volume.
  • MACD, momentum from the spread of two exponential averages.
  • CCI, deviation-based oscillator, another momentum alternative.
  • Stochastic, position of the close within the recent high-low range.