Skip to content

Free TradingView indicator

Stochastic RSI Zones

Stochastic RSI with upper and lower zone signals, a choice of signal type and an optional EMA trend filter on price.

Momentumv1.0TradingView (Pine Script v6) Non-repainting signals Alerts

What it does

Stochastic RSI Zones applies a stochastic oscillator to RSI rather than to price, producing a fast 0–100 line (%K) and its average (%D). It shades an upper and a lower zone and marks signals when the oscillator turns from those zones.

Because Stochastic RSI is very sensitive, the script adds an optional trend filter on price: with it on, bullish signals only appear while price is above a long EMA and bearish signals only while price is below it.

How it works

  1. RSI is calculated on the source.
  2. Raw StochRSI = (RSI − lowest RSI over n) ÷ (highest RSI over n − lowest RSI over n) × 100.
  3. %K = SMA(raw, %K smoothing). %D = SMA(%K, %D smoothing).
  4. Signal type "K/D cross inside zone": bullish when %K crosses above %D while %K was at or below the lower zone on the previous bar; bearish when %K crosses below %D while it was at or above the upper zone.
  5. Signal type "K leaves zone": bullish when %K crosses up through the lower zone level; bearish when it crosses down through the upper level.
  6. Trend filter: bullish signals need close > EMA(trend length), bearish signals need close < EMA.

Signals are confirmed on bar close. A faint background shows which side of the trend EMA price is on when the filter is active.

How to use it

  • Treat the indicator as a timing tool inside a trend you have already identified, which is exactly what the filter enforces. In an uptrend, a bullish signal from the lower zone marks a possible end of a pullback.
  • "K leaves zone" signals are a little later but filter out some crosses that happen while the oscillator is still pinned at an extreme.
  • Pair it with a price level: a bullish signal near support carries more context than one in open space.
  • It is popular on M5–H4. Its speed makes it noisy on M1. For the RSI foundation, see the RSI lesson.

Settings

InputDefaultWhat it changes
SourceclosePrice used for RSI.
RSI length14Smoothness of the underlying RSI.
Stochastic length14Window for the stochastic of RSI.
%K / %D smoothing3 / 3Line smoothness.
Upper / Lower zone80 / 20Zone levels for signals.
Signal typeK/D cross inside zoneWhich event triggers a signal.
Only signal with the trendOnApplies the EMA trend filter.
Trend EMA length (on price)200Speed of the trend filter.

Limitations

  • Stochastic RSI swings between extremes very quickly and can stay pinned at 0 or 100 during strong moves, producing early counter-signals when the filter is off.
  • The trend filter uses a lagging EMA; around trend changes it will block valid signals and allow late ones.
  • Many signals occur in ranges where the trend filter itself flips often.
  • It measures momentum of RSI, not price, so its swings can look dramatic while price barely moves. Always check the actual price distance against your spread and costs.

Pine Script source

In TradingView open Pine Editor, paste the code, click Save and then Add to chart.

FXP_StochRsiZones.pine

72 lines

// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/stochastic-rsi-zones/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// Stochastic RSI with overbought/oversold zone signals and an optional moving-average trend
// filter on price, so that only signals in the direction of the broader trend are shown.
indicator("FXP Stochastic RSI Zones", shorttitle = "FXP StochRSI", overlay = false)

// ── Inputs ─────────────────────────────────────────────────────────────
grpS     = "Stochastic RSI"
src      = input.source(close, "Source", group = grpS)
rsiLen   = input.int(14, "RSI length", minval = 2, group = grpS)
stochLen = input.int(14, "Stochastic length", minval = 2, group = grpS)
kSmooth  = input.int(3, "%K smoothing", minval = 1, group = grpS)
dSmooth  = input.int(3, "%D smoothing", minval = 1, group = grpS)
obLevel  = input.float(80.0, "Upper zone", minval = 50.0, maxval = 100.0, group = grpS)
osLevel  = input.float(20.0, "Lower zone", minval = 0.0, maxval = 50.0, group = grpS)

grpSig  = "Signals"
sigMode = input.string("K/D cross inside zone", "Signal type", options = ["K/D cross inside zone", "K leaves zone"], group = grpSig)

grpT     = "Trend filter"
useTrend = input.bool(true, "Only signal with the trend", group = grpT)
trendLen = input.int(200, "Trend EMA length (on price)", minval = 2, group = grpT)

grpV    = "Display"
colK    = input.color(#2962ff, "%K line", group = grpV)
colD    = input.color(#ff6d00, "%D line", group = grpV)
colBull = input.color(#26a69a, "Bullish signal", group = grpV)
colBear = input.color(#ef5350, "Bearish signal", group = grpV)

// ── Calculation ────────────────────────────────────────────────────────
rsiVal = ta.rsi(src, rsiLen)
k      = ta.sma(ta.stoch(rsiVal, rsiVal, rsiVal, stochLen), kSmooth)
d      = ta.sma(k, dSmooth)

trendMa   = ta.ema(close, trendLen)
upTrend   = close > trendMa
downTrend = close < trendMa

kdUp   = ta.crossover(k, d)
kdDown = ta.crossunder(k, d)
exitOs = ta.crossover(k, osLevel)
exitOb = ta.crossunder(k, obLevel)

zoneUp   = kdUp and k[1] <= osLevel
zoneDown = kdDown and k[1] >= obLevel

rawBull = sigMode == "K leaves zone" ? exitOs : zoneUp
rawBear = sigMode == "K leaves zone" ? exitOb : zoneDown

bullSignal = rawBull and (not useTrend or upTrend) and barstate.isconfirmed
bearSignal = rawBear and (not useTrend or downTrend) and barstate.isconfirmed

// ── Plots ──────────────────────────────────────────────────────────────
plot(k, "%K", color = colK, linewidth = 2)
plot(d, "%D", color = colD)
hUp  = hline(obLevel, "Upper zone", color = color.new(colBear, 40), linestyle = hline.style_dashed)
hMid = hline(50, "Midline", color = color.new(color.gray, 60), linestyle = hline.style_dotted)
hLow = hline(osLevel, "Lower zone", color = color.new(colBull, 40), linestyle = hline.style_dashed)
hTop = hline(100, "Top", color = color.new(color.gray, 100))
hBot = hline(0, "Bottom", color = color.new(color.gray, 100))
fill(hUp, hTop, color = color.new(colBear, 90), title = "Upper zone fill")
fill(hLow, hBot, color = color.new(colBull, 90), title = "Lower zone fill")

plotshape(bullSignal, "Bullish zone signal", style = shape.triangleup, location = location.bottom, color = colBull, size = size.small)
plotshape(bearSignal, "Bearish zone signal", style = shape.triangledown, location = location.top, color = colBear, size = size.small)
bgcolor(useTrend ? (upTrend ? color.new(colBull, 96) : color.new(colBear, 96)) : na, title = "Trend filter background")

// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(bullSignal, "StochRSI bullish zone signal", "Stochastic RSI bullish signal from the lower zone on {{ticker}} ({{interval}})")
alertcondition(bearSignal, "StochRSI bearish zone signal", "Stochastic RSI bearish signal from the upper zone on {{ticker}} ({{interval}})")

Key inputs

Key inputs of Stochastic RSI Zones
InputDefaultDescription
RSI length14Length of the RSI that feeds the stochastic.
Stochastic length14Lookback for the stochastic of RSI.
%K smoothing3SMA applied to the raw stochastic to form %K.
%D smoothing3SMA of %K that forms %D.
Upper / lower zone80 / 20Zone boundaries used for signals.
Signal typeK/D cross inside zoneSignal on a %K/%D cross inside a zone, or when %K leaves a zone.
Only signal with the trendOnKeep bullish signals above the trend EMA and bearish signals below it.
Trend EMA length (on price)200EMA of price used by the trend filter.

Educational tools, not advice. Indicators and Expert Advisors describe price; they do not predict it, and past behaviour does not guarantee future results. Test everything on a demo account first and never risk money you cannot afford to lose. See our disclaimer.

Keep exploring

Related tradingview indicators