retail // reset · tool library

Indicator Vault.

Indicators are not the foundation of trading, your mind is. First learn to manage emotion, read sentiment, understand price action, volume spread analysis, Elliott Wave, Wyckoff, on chain data, and market structure. These free tools are here to simplify the early stages, put your mind at ease and give traders using the free version of TradingView a practical place to begin.

starter stack · RSI levels · RSI gradient · divergence · MACD · prism candles
how to read the signals together

Read the transaction story.

Price is the result. Read what had to happen for price to get there: where it sits in structure, whether movement has momentum, whether reported volume is leaning with the move, and whether that effort produced real distance. The indicators are not separate votes; they describe different parts of the same auction.

01 · structure · EMA / SMA

Location, trend control and acceptance.

A moving average shows the average price over a chosen period. It is not a wall that price must obey. When the 20 average is above the 50, the 50 is above the 100, and the 100 is above the 200, recent prices are being accepted higher than older prices. The important read is the retest. Does price find buyers, recover the average and continue, or does it close below, fail to reclaim it and begin accepting lower prices?

A golden cross forms when a faster average crosses above a slower average, most commonly when the 50 crosses above the 200. A death cross is the opposite. These are delayed confirmations, not predictions. A cross on the fifteen minute chart only describes short term structure, while a daily or weekly cross carries more weight but appears much later. Crosses are less reliable when the averages are flat, compressed or repeatedly crossing inside a range.

An EMA gives newer candles more influence, so it reacts faster when behaviour changes. An SMA weights every candle equally, so it moves more slowly and filters more short term noise. A stronger trend usually has price holding on the correct side of the averages, the averages sloping in the same direction and space opening between them. Flattening and compression suggest weakening control or balance.

02 · momentum · RSI

How persistently are closes pushing?

RSI compares recent average gains with recent average losses. It rises when positive closes dominate and falls when negative closes dominate. In a strong advance, RSI can remain elevated and repeatedly return to its upper region. High RSI can mean persistent momentum, not an automatic reversal.

On the four hour chart, RSI can reach the upper region, ease back slightly, then push up again while price completes a three wave or five wave move. The fifteen minute RSI will look much more active because it is showing the smaller swings inside that four hour structure. It can move up and down several times while the higher timeframe remains strong.

Read RSI beside price structure and the timeframe. A breakout with RSI holding above its middle region is different from a tired push beneath major resistance. Price making a new high while RSI fails to match its previous high is a warning that momentum is weakening, not proof that price must reverse. Believing that every high reading means sell is how traders get caught against unfinished trends.

03 · flow · MFI

Is the measured volume leaning with price?

MFI is a 0–100 oscillator built from typical price and the volume reported by the chart feed. When it rises, more of that measured activity is being associated with rising typical price over the selected lookback; when it falls, the balance is shifting toward falling typical price. It is volume-weighted pressure, not a literal record of all money entering or leaving an asset, particularly where crypto volume differs across venues.

A level reclaim has stronger confluence when price regains structure and MFI also turns upward or reclaims its middle area. When price rises while MFI stays weak, or price makes a new high while MFI cannot, the move lacks flow confirmation. That can precede absorption, a pause or a failed breakout, but it needs price confirmation before it becomes a trade decision.

04 · participation · volume

How much activity produced the result?

Volume measures activity, not whether buyers or sellers will win. Compare it with the candle spread, close and the distance price actually travels. A break through a level on expanding volume, wide range and a close beyond the level shows committed activity and possible acceptance. A quiet pullback inside an established uptrend can show that the counter move is not attracting the same participation.

The opposite read matters just as much. Exceptional volume into resistance or support with little net progress, a narrow body or repeated rejection wicks means a lot traded but price could not travel. That can be absorption or defence. The next candles decide whether the level was accepted or rejected. Volume alone does not tell you which side has won.

CONGRUENT READ · evidence stacking

When the story is internally aligned.

For a bullish continuation or reclaim, look for price above or reclaiming a rising average stack, RSI recovering and holding its stronger range, MFI turning with price rather than lagging it, and volume expanding on the directional move while the pullback contracts. This does not guarantee continuation; it means the chart is not asking you to ignore a major disagreement.

NON-CONGRUENT READ · slow down

When price and participation tell different stories.

Be more careful when price reaches a fresh high but the averages flatten, RSI and MFI fail to confirm their prior swings, the breakout has little participation, or very high volume produces almost no progress. That is not a command to fade the move. It is a cue to stop chasing and wait for the next candles to show acceptance, rejection, reclaim or failure.

free indicator · one TradingView slot

R//R Starter Stack.

A compact starting workspace for traders on the free version of TradingView. Four editable averages sit on price while RSI and MFI share one fixed lower pane.

live layout preview
available now

20 / 50 / 100 / 200 EMA or SMA with RSI and MFI

Change every average independently, keep both oscillators on the same 0 to 100 scale and read structure, momentum and measured volume without spending several indicator slots.

4 averages EMA or SMA RSI + MFI fixed scale
View source
//@version=6
indicator(
     "R//R · 4 EMA + SMA · RSI / MFI",
     shorttitle = "R//R MA + RSI/MFI",
     overlay = false,
     precision = 2
)

// ╔══════════════════════════════════════════════════════════════════════════╗
// ║ R//R · 4 EMA + SMA · RSI / MFI                                           ║
// ║                                                                          ║
// ║ PRICE CHART:  Four editable EMAs and one editable SMA.                   ║
// ║ LOWER PANE:   RSI and MFI together on the same 0–100 scale.              ║
// ║                                                                          ║
// ║ R//R principle: moving averages show structure; RSI and MFI show         ║
// ║ momentum and money-flow condition inside that structure.                 ║
// ╚══════════════════════════════════════════════════════════════════════════╝


// ============================================================================
// 01 · MOVING AVERAGES — DISPLAYED ON THE MAIN PRICE CHART
// ============================================================================

groupMA = "01 · Moving averages"

maSource = input.source(close, "MA source", group = groupMA)

// EMA 1
showEMA1  = input.bool(true, "Show EMA 1", group = groupMA, inline = "ema1")
ema1Length = input.int(9, "Length", minval = 1, group = groupMA, inline = "ema1")
ema1Color = input.color(color.aqua, "Colour", group = groupMA, inline = "ema1")

// EMA 2
showEMA2  = input.bool(true, "Show EMA 2", group = groupMA, inline = "ema2")
ema2Length = input.int(21, "Length", minval = 1, group = groupMA, inline = "ema2")
ema2Color = input.color(color.yellow, "Colour", group = groupMA, inline = "ema2")

// EMA 3
showEMA3  = input.bool(true, "Show EMA 3", group = groupMA, inline = "ema3")
ema3Length = input.int(50, "Length", minval = 1, group = groupMA, inline = "ema3")
ema3Color = input.color(color.orange, "Colour", group = groupMA, inline = "ema3")

// EMA 4
showEMA4  = input.bool(true, "Show EMA 4", group = groupMA, inline = "ema4")
ema4Length = input.int(200, "Length", minval = 1, group = groupMA, inline = "ema4")
ema4Color = input.color(color.fuchsia, "Colour", group = groupMA, inline = "ema4")

// SMA
showSMA   = input.bool(true, "Show SMA", group = groupMA, inline = "sma")
smaLength = input.int(200, "Length", minval = 1, group = groupMA, inline = "sma")
smaColor  = input.color(color.white, "Colour", group = groupMA, inline = "sma")

// Average calculations
ema1 = ta.ema(maSource, ema1Length)
ema2 = ta.ema(maSource, ema2Length)
ema3 = ta.ema(maSource, ema3Length)
ema4 = ta.ema(maSource, ema4Length)
sma  = ta.sma(maSource, smaLength)

// Force these plots onto the main price chart.
plot(
     showEMA1 ? ema1 : na,
     title = "EMA 1",
     color = ema1Color,
     linewidth = 2,
     force_overlay = true
)

plot(
     showEMA2 ? ema2 : na,
     title = "EMA 2",
     color = ema2Color,
     linewidth = 2,
     force_overlay = true
)

plot(
     showEMA3 ? ema3 : na,
     title = "EMA 3",
     color = ema3Color,
     linewidth = 2,
     force_overlay = true
)

plot(
     showEMA4 ? ema4 : na,
     title = "EMA 4",
     color = ema4Color,
     linewidth = 2,
     force_overlay = true
)

plot(
     showSMA ? sma : na,
     title = "SMA",
     color = smaColor,
     linewidth = 2,
     force_overlay = true
)


// ============================================================================
// 02 · RSI + MFI — SHARED 0–100 SCALE IN THIS LOWER PANE
// ============================================================================

groupOsc = "02 · RSI + MFI"

// RSI controls
showRSI  = input.bool(true, "Show RSI", group = groupOsc, inline = "rsi")
rsiSource = input.source(close, "Source", group = groupOsc, inline = "rsi")
rsiLength = input.int(14, "Length", minval = 1, group = groupOsc, inline = "rsi")
rsiColor = input.color(color.aqua, "Colour", group = groupOsc, inline = "rsi")

// MFI controls
showMFI  = input.bool(true, "Show MFI", group = groupOsc, inline = "mfi")
mfiSource = input.source(hlc3, "Source", group = groupOsc, inline = "mfi")
mfiLength = input.int(14, "Length", minval = 1, group = groupOsc, inline = "mfi")
mfiColor = input.color(color.orange, "Colour", group = groupOsc, inline = "mfi")

// Oscillator display controls
showMidline = input.bool(true, "Show 50 midpoint", group = groupOsc)
showZones   = input.bool(true, "Shade 70 / 30 extreme zones", group = groupOsc)

// Calculations
rsi = ta.rsi(rsiSource, rsiLength)
mfi = ta.mfi(mfiSource, mfiLength)

// RSI and MFI occupy the same lower 0–100 pane.
plot(
     showRSI ? rsi : na,
     title = "RSI",
     color = rsiColor,
     linewidth = 2
)

plot(
     showMFI ? mfi : na,
     title = "MFI",
     color = mfiColor,
     linewidth = 2
)


// ============================================================================
// 03 · RSI / MFI REFERENCE LEVELS
// ============================================================================

upperLevel  = hline(
     70,
     "70 · Upper extreme",
     color = color.new(color.red, 35),
     linestyle = hline.style_dashed
)

midLevel = hline(
     50,
     "50 · Midpoint",
     color = showMidline ? color.new(color.gray, 55) : color.new(color.gray, 100),
     linestyle = hline.style_dotted
)

lowerLevel = hline(
     30,
     "30 · Lower extreme",
     color = color.new(color.lime, 35),
     linestyle = hline.style_dashed
)

topBound = hline(
     100,
     "100",
     color = color.new(color.gray, 100)
)

bottomBound = hline(
     0,
     "0",
     color = color.new(color.gray, 100)
)

fill(
     upperLevel,
     topBound,
     color = showZones ? color.new(color.red, 92) : na,
     title = "Upper extreme zone"
)

fill(
     bottomBound,
     lowerLevel,
     color = showZones ? color.new(color.lime, 92) : na,
     title = "Lower extreme zone"
)


// ============================================================================
// 04 · OPTIONAL RSI / MFI RELATIONSHIP SIGNALS
// ============================================================================

groupSignals = "03 · RSI / MFI relationship"

showCrosses   = input.bool(false, "Show RSI / MFI crosses", group = groupSignals)
showAgreement = input.bool(false, "Show RSI / MFI agreement background", group = groupSignals)

rsiCrossUp   = ta.crossover(rsi, mfi)
rsiCrossDown = ta.crossunder(rsi, mfi)

bothBullish = rsi > 50 and mfi > 50
bothBearish = rsi < 50 and mfi < 50

plotshape(
     showCrosses and rsiCrossUp,
     title = "RSI crosses above MFI",
     style = shape.triangleup,
     location = location.bottom,
     color = color.aqua,
     size = size.tiny,
     text = "R↑"
)

plotshape(
     showCrosses and rsiCrossDown,
     title = "RSI crosses below MFI",
     style = shape.triangledown,
     location = location.top,
     color = color.orange,
     size = size.tiny,
     text = "R↓"
)

bgcolor(
     showAgreement
         ? bothBullish
             ? color.new(color.lime, 92)
             : bothBearish
                 ? color.new(color.red, 92)
                 : na
         : na,
     title = "RSI / MFI agreement"
)


// ============================================================================
// 05 · ALERT CONDITIONS
// ============================================================================

alertcondition(
     rsiCrossUp,
     title = "R//R · RSI crosses above MFI",
     message = "R//R: RSI has crossed above MFI."
)

alertcondition(
     rsiCrossDown,
     title = "R//R · RSI crosses below MFI",
     message = "R//R: RSI has crossed below MFI."
)

alertcondition(
     ta.crossover(rsi, 50),
     title = "R//R · RSI crosses above 50",
     message = "R//R: RSI has crossed above the 50 midpoint."
)

alertcondition(
     ta.crossunder(rsi, 50),
     title = "R//R · RSI crosses below 50",
     message = "R//R: RSI has crossed below the 50 midpoint."
)

alertcondition(
     ta.crossover(mfi, 50),
     title = "R//R · MFI crosses above 50",
     message = "R//R: MFI has crossed above the 50 midpoint."
)

alertcondition(
     ta.crossunder(mfi, 50),
     title = "R//R · MFI crosses below 50",
     message = "R//R: MFI has crossed below the 50 midpoint."
)
free collection · source slots added

Useful, visual and easy to copy.

This page now separates the access ladder. The first RSI readers are free with live copy buttons. The gradient heatline is marked as a module-unlock candidate. The last three advanced relationship/divergence tools are presented as support-tier cards, with their source kept out of the public page until the support flow is built.

30 · 50 · 70 levels
free · source ready

RSI Zone Rails

Clean 30, 50 and 70 rails with optional 20 and 80 exhaustion rails and light region shading. Built to show where RSI is holding, not to issue automatic buy and sell commands.

levels · regimes · clean context
//@version=6 indicator("R//R RSI · Zone Rails", shorttitle = "R//R RSI Rails", overlay = false, precision = 2) // ============================================================================ // R//R · RSI REGION 01 // Zone Rails // Fixed boundaries · clean reading // ============================================================================ groupRSI = "01 · RSI" rsiSource = input.source(close, "Source", group = groupRSI) rsiLength = input.int(14, "Length", minval = 1, group = groupRSI) rsiColor = input.color(color.aqua, "RSI colour", group = groupRSI) groupRails = "02 · Rails" lowerRail = input.float(30.0, "Lower rail", minval = 0, maxval = 49, group = groupRails) upperRail = input.float(70.0, "Upper rail", minval = 51, maxval = 100, group = groupRails) showExhaustion = input.bool(true, "Show exhaustion rails", group = groupRails) lowerExhaustion = input.float(20.0, "Lower exhaustion", minval = 0, maxval = 29, group = groupRails) upperExhaustion = input.float(80.0, "Upper exhaustion", minval = 71, maxval = 100, group = groupRails) groupStyle = "03 · Style" showZoneFills = input.bool(true, "Shade regions", group = groupStyle) lowZoneColor = input.color(color.lime, "Low zone colour", group = groupStyle) midZoneColor = input.color(color.gray, "Neutral zone colour", group = groupStyle) highZoneColor = input.color(color.red, "High zone colour", group = groupStyle) rsi = ta.rsi(rsiSource, rsiLength) plot(rsi, title = "RSI", color = rsiColor, linewidth = 2) rail0 = hline(0, "0", color = color.new(color.gray, 100)) rail100 = hline(100, "100", color = color.new(color.gray, 100)) rail20 = hline( showExhaustion ? lowerExhaustion : na, "Lower exhaustion", color = color.new(lowZoneColor, 25), linestyle = hline.style_dotted ) rail30 = hline( lowerRail, "Lower rail", color = color.new(lowZoneColor, 10), linestyle = hline.style_dashed ) rail50 = hline( 50, "Midpoint", color = color.new(color.gray, 40), linestyle = hline.style_dotted ) rail70 = hline( upperRail, "Upper rail", color = color.new(highZoneColor, 10), linestyle = hline.style_dashed ) rail80 = hline( showExhaustion ? upperExhaustion : na, "Upper exhaustion", color = color.new(highZoneColor, 25), linestyle = hline.style_dotted ) fill( rail0, rail30, color = showZoneFills ? color.new(lowZoneColor, 92) : na, title = "Lower pressure zone" ) fill( rail30, rail70, color = showZoneFills ? color.new(midZoneColor, 95) : na, title = "Neutral pressure zone" ) fill( rail70, rail100, color = showZoneFills ? color.new(highZoneColor, 92) : na, title = "Upper pressure zone" )
range behaviour
free · source ready

RSI Regime Bands

Range blocks for bear pressure, neutral rotation and bull pressure. The point is to watch where RSI keeps accepting, not to worship a universal 70 / 30 rule.

range behaviour · context first
//@version=6 indicator("R//R RSI · Regime Bands", shorttitle = "R//R RSI Regime", overlay = false, precision = 2) // ============================================================================ // R//R · RSI REGION 02 // Regime Bands // Range behaviour · context first // ============================================================================ groupRSI = "01 · RSI" rsiSource = input.source(close, "Source", group = groupRSI) rsiLength = input.int(14, "Length", minval = 1, group = groupRSI) rsiColor = input.color(color.white, "RSI colour", group = groupRSI) groupBands = "02 · Regime bands" bearBoundary = input.float(45.0, "Bear pressure ceiling", minval = 1, maxval = 49, group = groupBands) bullBoundary = input.float(55.0, "Bull pressure floor", minval = 51, maxval = 99, group = groupBands) showBorders = input.bool(true, "Show regime borders", group = groupBands) groupColours = "03 · Colours" bearColor = input.color(color.red, "Bear pressure", group = groupColours) neutralColor = input.color(color.gray, "Neutral range", group = groupColours) bullColor = input.color(color.lime, "Bull pressure", group = groupColours) rsi = ta.rsi(rsiSource, rsiLength) plot(rsi, title = "RSI", color = rsiColor, linewidth = 2) rail0 = hline(0, "0", color = color.new(color.gray, 100)) rail100 = hline(100, "100", color = color.new(color.gray, 100)) bearRail = hline( bearBoundary, "Bear regime boundary", color = showBorders ? color.new(bearColor, 20) : color.new(bearColor, 100), linestyle = hline.style_dashed ) midRail = hline( 50, "Midpoint", color = showBorders ? color.new(neutralColor, 40) : color.new(neutralColor, 100), linestyle = hline.style_dotted ) bullRail = hline( bullBoundary, "Bull regime boundary", color = showBorders ? color.new(bullColor, 20) : color.new(bullColor, 100), linestyle = hline.style_dashed ) fill( rail0, bearRail, color = color.new(bearColor, 88), title = "Bear pressure band" ) fill( bearRail, bullRail, color = color.new(neutralColor, 94), title = "Neutral regime band" ) fill( bullRail, rail100, color = color.new(bullColor, 88), title = "Bull pressure band" )
continuous colour pressure
module unlock · source ready

RSI Pressure Heatline

A restrained continuous colour line that makes RSI pressure easier to read without adding arrows. This is the strongest candidate for a “complete the RSI module” unlock because it teaches pressure rather than obedience.

gradient · direction · intensity
//@version=6 indicator("R//R RSI · Pressure Heatline", shorttitle = "R//R RSI Heatline", overlay = false, precision = 2) // ============================================================================ // R//R · RSI GRADIENT 01 // Pressure Heatline // Continuous pressure colour // ============================================================================ groupRSI = "01 · RSI" rsiSource = input.source(close, "Source", group = groupRSI) rsiLength = input.int(14, "Length", minval = 1, group = groupRSI) groupGradient = "02 · Gradient anchors" lowAnchor = input.float(30.0, "Low anchor", minval = 0, maxval = 49, group = groupGradient) midAnchor = input.float(50.0, "Calm midpoint", minval = 45, maxval = 55, group = groupGradient) highAnchor = input.float(70.0, "High anchor", minval = 51, maxval = 100, group = groupGradient) groupColours = "03 · Colours" lowColor = input.color(color.red, "Low pressure colour", group = groupColours) midColor = input.color(color.silver, "Midpoint colour", group = groupColours) highColor = input.color(color.lime, "High pressure colour", group = groupColours) groupStyle = "04 · Style" showGuides = input.bool(true, "Show anchor guides", group = groupStyle) lineWidth = input.int(2, "Line width", minval = 1, maxval = 5, group = groupStyle) rsi = ta.rsi(rsiSource, rsiLength) clampedRSI = math.max(lowAnchor, math.min(highAnchor, rsi)) heatColor = clampedRSI >= midAnchor ? color.from_gradient(clampedRSI, midAnchor, highAnchor, midColor, highColor) : color.from_gradient(clampedRSI, lowAnchor, midAnchor, lowColor, midColor) plot(rsi, title = "RSI heatline", color = heatColor, linewidth = lineWidth) hline( showGuides ? lowAnchor : na, "Low anchor", color = color.new(lowColor, 55), linestyle = hline.style_dashed ) hline( showGuides ? midAnchor : na, "Midpoint", color = color.new(midColor, 65), linestyle = hline.style_dotted ) hline( showGuides ? highAnchor : na, "High anchor", color = color.new(highColor, 55), linestyle = hline.style_dashed )
RSI − MFI spread
support tier · source banked

RSI–MFI Spread Meter

Subtracts MFI from RSI and plots the gap around a zero line. It shows whether price momentum is running ahead of volume-weighted flow or whether flow is leading price.

momentum vs flow · widening gaps
Source is preserved in the private source-bank file for the future support page.
confirmed pivot lines
support tier · source banked

RSI Pivot Divergence

Connects confirmed swing pivots and marks regular bullish or bearish RSI divergence without flagging every minor wobble. Confirmation arrives late by design because the pivots must first exist.

pivots · divergence · less clutter
Source is preserved in the private source-bank file for the future support page.
RSI + MFI agreement
support tier · source banked

RSI + MFI Confluence Divergence

Shows divergence only when price disagrees with both RSI and MFI at the confirmed pivot. It should fire less often, because it asks two oscillators to agree on the warning.

RSI + MFI agreement · fewer warnings
Source is preserved in the private source-bank file for the future support page.
support the build · paid access

Keep the free vault free.

The free tools exist to teach the language of the chart. Crypto donations support the research, writing, testing and maintenance behind them. Paid access supports the heavier BTC systems and their ongoing updates.

crypto support

Donate to the free layer.

Use the exact wallet and network displayed below. A crypto address is not interchangeable across chains; send only the stated asset on the stated network.

DONATION WALLET · ADD NETWORK + ADDRESS
REPLACE_WITH_YOUR_CRYPTO_WALLET_ADDRESS
Network: REPLACE WITH NETWORK · Verify the first and last characters before sending. Do not send until this field has been replaced with a live wallet and exact chain.