Indicator · Pine Script v6 · Own pane

ROC MA Slope

by rubbermetal· code credited to claygrace74

ROC MA Slope plots two smoothed rate of change lines, a fast and a slow one, in a separate pane.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code262
Settings17inputs
LicenceMPL-2.0
Last update4 months ago10 Jun 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

262 lines of Pine Script v6 from ROC MA Slope.pine, published under MPL-2.0. Keep the author's credit and licence lines when you reuse it.

ROC MA Slope.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © claygrace74

//@version=6
indicator("ROC MA Slope", shorttitle="ROC Slope", overlay=false, max_labels_count=500)

// ==================================================================================
// Settings
// ==================================================================================
string GRP0        = "General"
string maType      = input.string("SMA", "MA Type", options=["SMA", "EMA"], group=GRP0)
int    maLen       = input.int(5,  "MA Smoothing Length", minval=1,          group=GRP0)
int    slopeLen    = input.int(5,  "Slope Lookback (LinReg)", minval=2,      group=GRP0)

string GRP1        = "Fast"
int    fastRocLen  = input.int(5,  "ROC Length",  minval=1,                  group=GRP1)
color  i_colUp1    = input.color(color.aqua,    "Bull Color",               group=GRP1)
color  i_colDn1    = input.color(color.fuchsia, "Bear Color",               group=GRP1)

string GRP2        = "Slow"
int    slowRocLen  = input.int(14, "ROC Length",  minval=1,                  group=GRP2)
color  i_colUp2    = input.color(color.lime,   "Bull Color",                group=GRP2)
color  i_colDn2    = input.color(color.orange, "Bear Color",                group=GRP2)

string GRP3        = "Display"
bool   i_showHist  = input.bool(true,  "Show Histogram (Fast MA)", group=GRP3)
bool   i_showFills = input.bool(true,  "Show Fills",               group=GRP3)
bool   i_showSlope = input.bool(true,  "Show Slope Lines",         group=GRP3)
bool   i_showDash  = input.bool(true,  "Show Dashboard",           group=GRP3)
bool   i_showZero  = input.bool(true,  "Show Zero-Line Crosses",   group=GRP3)
bool   i_showDiv   = input.bool(false, "Show Divergence Signals",  group=GRP3)
bool   i_showAccel = input.bool(true,  "Show Acceleration Coloring", group=GRP3)
int    i_divLB     = input.int(5, "Divergence Lookback", minval=3, maxval=20, group=GRP3)

// ==================================================================================
// ROC + MA
// ==================================================================================
fastRoc = ta.roc(close, fastRocLen)
slowRoc = ta.roc(close, slowRocLen)

fastMA = maType == "EMA" ? ta.ema(fastRoc, maLen) : ta.sma(fastRoc, maLen)
slowMA = maType == "EMA" ? ta.ema(slowRoc, maLen) : ta.sma(slowRoc, maLen)

// ==================================================================================
// Slope (linear regression derivative)
// ==================================================================================
fastSlope = ta.linreg(fastMA, slopeLen, 0) - ta.linreg(fastMA, slopeLen, 1)
slowSlope = ta.linreg(slowMA, slopeLen, 0) - ta.linreg(slowMA, slopeLen, 1)

// ==================================================================================
// Momentum, Acceleration & Signals
// ==================================================================================
bool fast_rising = fastSlope > 0
bool slow_rising = slowSlope > 0

// Acceleration — slope of slope (curvature)
float fastAccel = ta.change(fastSlope)
float slowAccel = ta.change(slowSlope)
bool  fastAccelUp = fastAccel > 0
bool  slowAccelUp = slowAccel > 0

// Cross signals
bool crossUp     = ta.crossover(fastMA, slowMA)
bool crossDn     = ta.crossunder(fastMA, slowMA)
bool zeroCrossUp = ta.crossover(fastMA, 0)
bool zeroCrossDn = ta.crossunder(fastMA, 0)

// Slope convergence — both slopes pointing same direction = aligned momentum
bool slopesAligned = (fast_rising and slow_rising) or (not fast_rising and not slow_rising)
bool slopesDiverge = (fast_rising and not slow_rising) or (not fast_rising and slow_rising)

// Divergence detection — price vs fast MA slope
bool priceHigher = high > ta.highest(high, i_divLB)[1]
bool slopeNotHigh = fastSlope < ta.highest(fastSlope, i_divLB)[1]
bool bearDiv     = priceHigher and slopeNotHigh and fastMA > 0

bool priceLower  = low < ta.lowest(low, i_divLB)[1]
bool slopeNotLow = fastSlope > ta.lowest(fastSlope, i_divLB)[1]
bool bullDiv     = priceLower and slopeNotLow and fastMA < 0

// ==================================================================================
// Average Distance Statistics
// ==================================================================================
int   avgWindow    = slowRocLen * maLen
float avgDistAbove = na
float avgDistBelow = na
float pctAbove     = na

if not na(fastMA) and not na(slowMA) and avgWindow > 0
    float sumAbove   = 0.0
    int   countAbove = 0
    float sumBelow   = 0.0
    int   countBelow = 0

    for i = 0 to avgWindow - 1
        float f    = nz(fastMA[i])
        float s    = nz(slowMA[i])
        float diff = f - s
        if diff > 0
            sumAbove   += diff
            countAbove += 1
        else if diff < 0
            sumBelow   += math.abs(diff)
            countBelow += 1

    avgDistAbove := countAbove > 0 ? sumAbove / countAbove : 0.0
    avgDistBelow := countBelow > 0 ? sumBelow / countBelow : 0.0
    pctAbove     := (countAbove / avgWindow) * 100.0

// ==================================================================================
// Colors
// ==================================================================================

// Slope-based opacity (steeper = more opaque)
slopeColor(slope, bullCol, bearCol) =>
    slope > 0
         ? color.new(bullCol, math.max(0, 80 - math.abs(slope) * 500))
         : color.new(bearCol, math.max(0, 80 - math.abs(slope) * 500))

color c1line = slopeColor(fastSlope, i_colUp1, i_colDn1)
color c2line = slopeColor(slowSlope, i_colUp2, i_colDn2)

color c1solid = fast_rising ? i_colUp1 : i_colDn1
color c2solid = slow_rising ? i_colUp2 : i_colDn2

// 4-color histogram momentum
bool growBull   = fastMA >= 0 and fastAccelUp
bool shrinkBull = fastMA >= 0 and not fastAccelUp
bool growBear   = fastMA < 0 and not fastAccelUp
bool shrinkBear = fastMA < 0 and fastAccelUp
color histCol = growBull ? i_colUp1 : shrinkBull ? color.new(i_colUp1, 50) : growBear ? i_colDn1 : color.new(i_colDn1, 50)

// Acceleration-aware slope line colors
color fastSlopeClr = i_showAccel ? (fast_rising ? (fastAccelUp ? i_colUp1 : color.new(i_colUp1, 50)) : (fastAccelUp ? color.new(i_colDn1, 50) : i_colDn1)) : c1solid
color slowSlopeClr = i_showAccel ? (slow_rising ? (slowAccelUp ? i_colUp2 : color.new(i_colUp2, 50)) : (slowAccelUp ? color.new(i_colDn2, 50) : i_colDn2)) : c2solid

// ==================================================================================
// Plots
// ==================================================================================
hline(0, "Zero", color.new(color.gray, 60), hline.style_dotted)

// 4-color histogram
plot(i_showHist ? fastMA : na, "Fast Hist", style=plot.style_histogram, color=color.new(histCol, 40), linewidth=2)

// MA lines
p1    = plot(fastMA, "Fast ROC MA", c1line, 2)
p2    = plot(slowMA, "Slow ROC MA", c2line, 2)
pZero = plot(0.0, display=display.none)

// Slope lines (acceleration-colored)
plot(i_showSlope ? fastSlope : na, "Fast Slope", fastSlopeClr, 1)
plot(i_showSlope ? slowSlope : na, "Slow Slope", slowSlopeClr, 1)

// Fills
fill(p1, pZero, color=i_showFills ? color.new(fastMA >= 0 ? i_colUp1 : i_colDn1, 90) : na, title="Fast/Zero Fill")
fill(p1, p2,    color=i_showFills ? color.new(fastMA > slowMA ? i_colUp1 : i_colDn1, 85) : na, title="Fast/Slow Fill")

// Cross markers (fast/slow)
plotshape(crossUp ? fastMA : na, "Cross Up",   shape.triangleup,   location.absolute, i_colUp1, size=size.small)
plotshape(crossDn ? fastMA : na, "Cross Down",  shape.triangledown, location.absolute, i_colDn1, size=size.small)

// Zero-line crosses
plotshape(i_showZero and zeroCrossUp, "Zero Up",   shape.circle, location.absolute, color.new(i_colUp1, 20), size=size.tiny)
plotshape(i_showZero and zeroCrossDn, "Zero Down",  shape.circle, location.absolute, color.new(i_colDn1, 20), size=size.tiny)

// Divergence
bgcolor(i_showDiv and bearDiv ? color.new(color.orange, 88) : na, title="Bearish Divergence")
bgcolor(i_showDiv and bullDiv ? color.new(color.teal, 88)   : na, title="Bullish Divergence")

// Slope alignment background
bgcolor(slopesDiverge ? color.new(color.yellow, 95) : na, title="Slopes Diverging")

// ==================================================================================
// Dashboard
// ==================================================================================
if barstate.islast and i_showDash
    var table dash = table.new(position.top_right, 3, 13, bgcolor=color.rgb(20, 20, 30, 10), border_color=color.rgb(60, 60, 80), border_width=1, frame_color=color.rgb(60, 60, 80), frame_width=1)

    color headerClr = color.rgb(200, 200, 220)
    color labelClr  = color.rgb(160, 160, 180)

    // Header
    table.cell(dash, 0, 0, "ROC MA Slope", text_color=headerClr, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 1, 0, "Fast",         text_color=i_colUp1,  text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 0, "Slow",         text_color=i_colUp2,  text_size=size.small, text_halign=text.align_center)

    // ROC Length
    table.cell(dash, 0, 1, "ROC Len",     text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 1, str.tostring(fastRocLen), text_color=headerClr, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 1, str.tostring(slowRocLen), text_color=headerClr, text_size=size.small, text_halign=text.align_center)

    // MA Type + Length
    table.cell(dash, 0, 2, maType + " Len", text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 2, str.tostring(maLen), text_color=headerClr, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 2, str.tostring(maLen), text_color=headerClr, text_size=size.small, text_halign=text.align_center)

    // MA Value
    table.cell(dash, 0, 3, "MA Value",    text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 3, str.tostring(fastMA, "#.####"), text_color=c1solid, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 3, str.tostring(slowMA, "#.####"), text_color=c2solid, text_size=size.small, text_halign=text.align_center)

    // Slope Value
    table.cell(dash, 0, 4, "Slope",       text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 4, str.tostring(fastSlope, "#.####"), text_color=c1solid, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 4, str.tostring(slowSlope, "#.####"), text_color=c2solid, text_size=size.small, text_halign=text.align_center)

    // Momentum
    table.cell(dash, 0, 5, "Momentum",    text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 5, fast_rising ? "Rising" : "Falling", text_color=fast_rising ? i_colUp1 : i_colDn1, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 5, slow_rising ? "Rising" : "Falling", text_color=slow_rising ? i_colUp2 : i_colDn2, text_size=size.small, text_halign=text.align_center)

    // Acceleration
    table.cell(dash, 0, 6, "Accel",       text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 6, fastAccelUp ? "Accelerating" : "Decelerating", text_color=fastAccelUp ? i_colUp1 : i_colDn1, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 6, slowAccelUp ? "Accelerating" : "Decelerating", text_color=slowAccelUp ? i_colUp2 : i_colDn2, text_size=size.small, text_halign=text.align_center)

    // Slope Alignment
    table.cell(dash, 0, 7, "Alignment",   text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    string alignTxt = slopesAligned ? "ALIGNED" : "DIVERGING"
    color alignClr  = slopesAligned ? color.green : color.yellow
    table.cell(dash, 1, 7, alignTxt,       text_color=alignClr, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 7, "",             text_size=size.small)

    // Bias
    string biasText  = fastMA > slowMA and fastMA > 0 ? "Strong Bull" : fastMA > slowMA and fastMA <= 0 ? "Weak Bull" : fastMA <= slowMA and fastMA > 0 ? "Weak Bear" : "Strong Bear"
    color  biasColor = fastMA > slowMA ? i_colUp1 : i_colDn1
    table.cell(dash, 0, 8, "Bias",        text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 8, biasText,       text_color=biasColor, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 8, "",             text_size=size.small)

    // --- Spread Stats ---
    table.cell(dash, 0, 9, "Spread Stats", text_color=headerClr, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 1, 9, "(" + str.tostring(avgWindow) + " bars)", text_color=color.rgb(120, 120, 140), text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 9, "",             text_size=size.small)

    float curSpread = fastMA - slowMA
    bool  isAbove   = curSpread > 0

    table.cell(dash, 0, 10, "Avg Above",  text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 10, str.tostring(avgDistAbove, "#.####") + " %", text_color=i_colUp1, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 10, isAbove ? str.tostring(curSpread, "#.####") + " % now" : "—", text_color=isAbove ? i_colUp1 : color.rgb(120, 120, 140), text_size=size.small, text_halign=text.align_center)

    table.cell(dash, 0, 11, "Avg Below",  text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 11, str.tostring(avgDistBelow, "#.####") + " %", text_color=i_colDn1, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 11, not isAbove ? str.tostring(math.abs(curSpread), "#.####") + " % now" : "—", text_color=not isAbove ? i_colDn1 : color.rgb(120, 120, 140), text_size=size.small, text_halign=text.align_center)

    table.cell(dash, 0, 12, "% Above",    text_color=labelClr, text_size=size.small, text_halign=text.align_left)
    table.cell(dash, 1, 12, str.tostring(pctAbove, "#.#") + " %", text_color=pctAbove >= 50 ? i_colUp1 : i_colDn1, text_size=size.small, text_halign=text.align_center)
    table.cell(dash, 2, 12, str.tostring(100.0 - pctAbove, "#.#") + " % below", text_color=pctAbove < 50 ? i_colUp1 : i_colDn1, text_size=size.small, text_halign=text.align_center)

// ==================================================================================
// Alert Conditions
// ==================================================================================
alertcondition(crossUp,      "Fast Crossed Above Slow",  "Fast ROC MA crossed above slow — bullish momentum shift")
alertcondition(crossDn,      "Fast Crossed Below Slow",  "Fast ROC MA crossed below slow — bearish momentum shift")
alertcondition(zeroCrossUp,  "Fast MA Above Zero",       "Fast ROC MA crossed above zero — positive momentum")
alertcondition(zeroCrossDn,  "Fast MA Below Zero",       "Fast ROC MA crossed below zero — negative momentum")
alertcondition(bullDiv,      "Bullish Divergence",       "Price making new low but slope is not — potential reversal")
alertcondition(bearDiv,      "Bearish Divergence",       "Price making new high but slope is not — potential reversal")
alertcondition(growBull,     "Bull Accelerating",        "Fast MA positive and slope accelerating")
alertcondition(growBear,     "Bear Accelerating",        "Fast MA negative and slope accelerating")
alertcondition(slopesDiverge and not slopesDiverge[1], "Slopes Diverging", "Fast and slow slopes pointing opposite directions")

Overview

Smoothing can be SMA or EMA, and each line has its own slope measured with linear regression. Optional layers include a histogram, fills, acceleration coloring, a dashboard, zero line crosses and a simple divergence check against price. Lengths, lookbacks and colors are adjustable.

Details

Published by

rubbermetal on GitHub

Code credit

claygrace74, as written in the script's header

Draws

Separate pane below the chart

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
MA TypestringSMAmaType
MA Smoothing Lengthint5maLen
Slope Lookback (LinReg)int5slopeLen
ROC Lengthint5fastRocLen
Bull Colorcolorcolor.aquai_colUp1
Bear Colorcolorcolor.fuchsiai_colDn1
ROC Lengthint14slowRocLen
Bull Colorcolorcolor.limei_colUp2
Bear Colorcolorcolor.orangei_colDn2
Show Histogram (Fast MA)booltruei_showHist
Show Fillsbooltruei_showFills
Show Slope Linesbooltruei_showSlope
Show all 17 settings
SettingTypeDefaultVariable
Show Dashboardbooltruei_showDash
Show Zero-Line Crossesbooltruei_showZero
Show Divergence Signalsboolfalsei_showDiv
Show Acceleration Coloringbooltruei_showAccel
Divergence Lookbackint5i_divLB
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This indicator scans a pasted list of symbols for RSI directional momentum and shows matching long and short signals in a table in a separate pane. The user chooses continuous break, continuous retracement, flip break, flip retracement, divergence, or hidden d

Indicator v6 Oscillators & momentumDivergence
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup - RSI Directional Momentum Scanner
228 stars

This indicator calculates the Relative Strength Index (RSI) across four user-selected timeframes and plots the results in a separate pane. It identifies regular bullish and bearish divergences between price pivot points and the primary timeframe RSI value. Add

Indicator v6 Oscillators & momentumDivergence
Updated 3 months ago · None stated GitHub repository of Multi-Timeframe RSI with Divergence

Oscillator Suite

by TamaraKGreen
46 stars

Oscillator Suite plots a normalised price oscillator in a separate pane and overlays a signal line that can use SMA, EMA, WMA, HMA, RMA, VWMA, T3, ZEMA, KAMA, or GKEMA. It marks bullish and bearish divergences, a smoothed money-flow series, confluence areas an

Indicator v5 Oscillators & momentumDivergence
Updated 7 weeks ago · None stated GitHub repository of Oscillator Suite
11 stars

This indicator plots a smoothed Z-score of cumulative volume delta in a separate pane, showing whether buying or selling pressure is dominant and when the reading enters extreme zones. It marks spot accumulation, climax or exhaustion, and pivot-based price-vol

Indicator v6 Oscillators & momentumVolume Repaints
Updated 7 weeks ago · MIT GitHub repository of CVD Z-Score [NeuNue]
9 stars

This indicator plots a heuristic volume-balance oscillator in a separate pane. It estimates signed volume from the close location inside each bar, multiplies that by volume, and sums the proxy over a rolling window. The sum is scaled between minus one and plus

Indicator v6 VolumeOscillators & momentum
Updated 2 days ago · MIT GitHub repository of CVD Bias [WavesUnchained]

KARPUZLU-RSI

by Kalumur
4 stars

Calculates a custom-period Relative Strength Index alongside an Exponential Moving Average of the RSI in a separate pane. It identifies pivot highs and lows directly on the RSI plot to highlight trendlines and potential divergence patterns. The area between th

Indicator v5 Oscillators & momentumMoving averages
Updated 2 years ago · None stated GitHub repository of KARPUZLU-RSI

More Oscillators & momentum scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers