Edgoro
Momentum indicator

Rate of Change (ROC): formula, settings and Pine Script v6 code

How the Rate of Change measures the percentage move over N bars, how traders read zero-line crosses and extremes, settings, and a free ROC script.

What it measures

The Rate of Change is the percentage change in price over a fixed number of bars. A 9-period ROC of +3 means the close is 3% higher than it was nine bars ago. It oscillates around zero: positive when price is higher than N bars ago, negative when it's lower.

It's one of the simplest momentum indicators, and a close relative of the momentum indicator, which shows the same change in price units instead of percent. Because ROC is a percentage, its values can be compared across symbols in a way that MACD or momentum values can't.

The formula in words

  1. Pick a length N.
  2. ROC = 100 × (close − close N bars ago) ÷ close N bars ago.

That's all. Pine Script has ta.roc(source, length), which returns the same value; the script writes it out. The optional signal line is a simple moving average of ROC.

Because only two prices are involved, ROC moves when either of them changes. A large bar dropping out of the window N bars later shifts ROC as much as a new bar does; this is sometimes called the drop-off effect.

How traders read it

  • Zero-line crosses. ROC crossing above zero means price is now higher than N bars ago. It's a slow, simple trend signal; with long lengths (100 to 250 bars) it's used as a trend filter.
  • Acceleration. Rising ROC means the move over the window is speeding up; falling ROC while price still rises means the move is slowing.
  • Relative extremes. ROC has no fixed range, so traders compare it with its own history on the same symbol: a reading near the highest of the past year is stretched for that market.
  • Ranking. Because it's a percentage, ROC over a fixed window is often used to rank symbols by momentum.

Common settings

LengthTypical use
9 to 14Short-term momentum
21 to 25About one month of daily bars
125 to 250Six to twelve months of daily bars, for trend filters and momentum ranking

The optional signal line is usually a 9-period SMA. Short lengths cross zero constantly, so most traders pair them with a longer filter.

Pine Script v6 code

The complete, self-contained script is below. Copy it into a new indicator in TradingView's Pine Editor, or download the .pine file.

Pine Script v6
//@version=6
indicator("Rate of Change (ROC)", shorttitle = "ROC", format = format.percent, precision = 2)

src     = input.source(close, "Source", group = "Calculation")
len     = input.int(9, "Length", minval = 1, group = "Calculation")
showSig = input.bool(true, "Show signal line", group = "Signal line")
sigLen  = input.int(9, "Signal line length (SMA)", minval = 1, group = "Signal line")

// Percentage change of the source over len bars.
roc = src[len] != 0 ? 100 * (src - src[len]) / src[len] : na
sig = ta.sma(roc, sigLen)

zeroUp   = ta.crossover(roc, 0)
zeroDown = ta.crossunder(roc, 0)
sigUp    = ta.crossover(roc, sig)
sigDown  = ta.crossunder(roc, sig)

plot(roc, "ROC", color = roc >= 0 ? color.new(color.teal, 0) : color.new(color.red, 0), linewidth = 2)
plot(showSig ? sig : na, "Signal", color = color.new(color.orange, 0))
hline(0, "Zero", color = color.new(color.gray, 50))

plotshape(zeroUp, "Crosses above zero", shape.triangleup, location.bottom, color.new(color.teal, 0), size = size.tiny)
plotshape(zeroDown, "Crosses below zero", shape.triangledown, location.top, color.new(color.red, 0), size = size.tiny)

alertcondition(zeroUp, "ROC above zero", "ROC crossed above zero on {{ticker}} ({{interval}})")
alertcondition(zeroDown, "ROC below zero", "ROC crossed below zero on {{ticker}} ({{interval}})")
alertcondition(sigUp, "ROC above signal", "ROC crossed above its signal line on {{ticker}} ({{interval}})")
alertcondition(sigDown, "ROC below signal", "ROC crossed below its signal line on {{ticker}} ({{interval}})")

ROC is plotted in its own pane, green above zero and red below, with an optional signal line and triangles on zero-line crosses. Values are formatted as percentages.

Four alert conditions cover zero-line and signal-line crosses in both directions. Set them to Once per bar close.

Add it to your chart

  1. Open any chart on TradingView and open the Pine Editor.
  2. Create a new indicator, delete the template code and paste the script.
  3. Click Save, then Add to chart. Change lengths and levels from the indicator's settings.

Stuck on an error? See how to add a Pine Script indicator to TradingView.

Pitfalls

  • The drop-off effect. A large bar leaving the window moves ROC even if today's price barely changes. Check the bar N periods back before reading a jump.
  • No fixed levels. "ROC above 5" means very different things on a currency pair and a small-cap stock. Compare with the symbol's own history.
  • Noise at short lengths. A 3- or 5-period ROC crosses zero all the time.
  • Live-bar crosses. The close isn't final until the bar closes.

The script is an educational example: test it on your own markets before relying on it. Indicators describe the past; they don't predict the future. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Make it yours with Edgoro

Describe the change in plain English and Edgoro writes the Pine Script v6 for you, ready to paste. For example:

“Plot ROC(12) with a 9-period signal line and alert when ROC crosses above zero while ROC(125) is positive, once per bar close.”

Build your ROC indicator