Indicator · Pine Script v6 · Own pane

Relative Strength Line [WavesUnchained]

by casoon

This indicator measures the relative strength of a chart symbol compared to a benchmark symbol, such as SPY or QQQ.

View on GitHub

GitHub stars9on the repository
Pine versionv6current
Lines of code174
Settings12inputs
LicenceMIT
Last updateyesterday27 Oct 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

174 lines of Pine Script v6 from indicators/relative_strength/relative_strength_line/relative_strength_line.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

relative_strength_line.pine
//@version=6
// ============================================================================
// Relative Strength Line [WavesUnchained]
// Version: 2.0.2
// Author: WavesUnchained
// Build: 2026-06-30 00:00:00
// ============================================================================
// Relative strength of the chart symbol vs. a benchmark (SPY / QQQ / any),
// turned into an ACTIONABLE signal: a long/short mark fires only when relative
// strength AND the stock's own price trend agree (confluence) — so a signal can
// never contradict the chart (no "green while price falls").
//
// Features:
//   ✓ RS line (price ÷ benchmark) or Mansfield RS oscillator (around zero)
//   ✓ Mansfield RS: % distance of RS from its own moving average
//   ✓ Confluence signal: LONG = outperforming benchmark AND price above its
//     trend EMA; SHORT = underperforming AND price below it
//   ✓ Markers follow trading convention: long below the line, short above
//   ✓ Dashboard: relative strength, price trend, and the confluence verdict
//   ✓ Right-edge tag with the live setup (LONG / SHORT / Neutral)
//   ✓ Alerts: long/short confluence, Mansfield zero cross up/down
//
// ============================================================================

indicator("Relative Strength Line [WavesUnchained]", shorttitle="RS Line", overlay=false, max_labels_count=200)

// ─── Inputs ──────────────────────────────────────────────────────────────────
grpRS = "Relative Strength"
benchSym  = input.symbol("AMEX:SPY", "Benchmark", group=grpRS,
     tooltip="Symbol the chart is measured against. SPY = broad market (S&P 500), QQQ = Nasdaq 100 (better for tech/momentum names like TSLA, NET, MSFT).")
displayMode = input.string("Mansfield RS", "Display", options=["Mansfield RS", "Raw RS Line"], group=grpRS,
     tooltip="Mansfield RS = normalized oscillator around zero (above 0 = outperforming the benchmark). Raw RS Line = the price/benchmark ratio itself; its slope is what matters, not the absolute level.")
mrsLen    = input.int(50, "Mansfield MA Length", minval=5, group=grpRS,
     tooltip="Moving-average length the Mansfield RS measures distance from. Weinstein's original uses ~52 weeks on weekly charts; 50 is a sensible all-timeframe default.")

grpSig = "Confluence Signal"
trendLen = input.int(50, "Price Trend EMA", minval=5, group=grpSig,
     tooltip="EMA of the stock's own price that defines its absolute trend. A long signal needs price ABOVE this EMA (real uptrend) on top of relative strength — so signals never contradict the chart.")
showLead = input.bool(true, "Show Confluence Markers", group=grpSig)
minGap   = input.int(5, "Min Bars Between Markers", minval=0, group=grpSig)
markerGap = input.float(0.4, "Marker Distance from Line", minval=0.0, maxval=2.0, step=0.1, group=grpSig, tooltip="Vertical gap between a marker and the line, in units of the RS line's standard deviation. 0 = right on the line.")

grpDisp = "Display"
showDash = input.bool(true, "Show Dashboard", group=grpDisp)
dashPos  = input.string("Top Right", "Dashboard Position", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group=grpDisp)
bullC    = input.color(#00c853, "Outperforming", group=grpDisp)
bearC    = input.color(#d50000, "Underperforming", group=grpDisp)

// ─── Helpers ─────────────────────────────────────────────────────────────────
safeDiv(a, b) =>
    b == 0.0 or na(b) ? na : a / b

// ─── Core: relative strength ─────────────────────────────────────────────────
benchClose = request.security(benchSym, timeframe.period, close, lookahead=barmerge.lookahead_off)

rs = safeDiv(close, benchClose)

// Mansfield RS: percentage distance of RS from its own moving average.
// Positive = RS above its mean → outperforming and accelerating; negative = lagging.
rsMa = ta.sma(rs, mrsLen)
mrs  = safeDiv(rs - rsMa, rsMa) * 100.0

// ─── Confluence: relative strength AND absolute price direction agree ─────────
// A signal only fires when the stock is BOTH outperforming the benchmark
// (Mansfield > 0) AND in its own uptrend (price above its trend EMA). This is
// the actionable case — a relative leader that is also rising — and structurally
// rules out the contradictory "RS green while price falls".
priceEma = ta.ema(close, trendLen)
bool priceBull = close > priceEma
bool priceBear = close < priceEma
bool rsBull    = not na(mrs) and mrs > 0
bool rsBear    = not na(mrs) and mrs < 0

bool longRegime  = priceBull and rsBull
bool shortRegime = priceBear and rsBear

// Fire on entry into the regime (not every bar), throttled by minGap
bool longEntry  = longRegime  and not longRegime[1]
bool shortEntry = shortRegime and not shortRegime[1]

var int lastUpBar = na
var int lastDownBar = na
bool fireUp   = longEntry  and (na(lastUpBar)   or bar_index - lastUpBar   >= minGap)
bool fireDown = shortEntry and (na(lastDownBar) or bar_index - lastDownBar >= minGap)
if fireUp
    lastUpBar := bar_index
if fireDown
    lastDownBar := bar_index

// ─── Plots ───────────────────────────────────────────────────────────────────
bool isMansfield = displayMode == "Mansfield RS"

plotSeries = isMansfield ? mrs : rs
plotColor  = na(mrs) ? color.new(color.gray, 20) : (isMansfield ? (mrs >= 0 ? bullC : bearC) : (rs >= rsMa ? bullC : bearC))

plot(plotSeries, "RS", color=plotColor, linewidth=2)
plot(isMansfield ? na : rsMa, "RS MA", color=color.new(color.gray, 40), linewidth=1)
plot(isMansfield ? 0.0 : na, "Zero", color=color.new(color.gray, 55), linewidth=1)

// Mansfield fill for quick read of regime
mrsPlot  = isMansfield ? mrs : na
zeroPlot = isMansfield ? 0.0 : na
p1 = plot(mrsPlot, display=display.none)
p2 = plot(zeroPlot, display=display.none)
fill(p1, p2, color=na(mrs) ? na : color.new(mrs >= 0 ? bullC : bearC, 88))

// Confluence markers are actionable long/short signals, so they follow the
// standard convention: green up-triangle BELOW the line (long), red down-triangle
// ABOVE (short). Offset uses the line's standard deviation for a steady gap.
markOff = ta.stdev(plotSeries, 50) * markerGap
upMark  = showLead and fireUp   ? plotSeries - markOff : na
dnMark  = showLead and fireDown ? plotSeries + markOff : na
plotshape(upMark, "Long Confluence",  shape.triangleup,   location.absolute, color=color.new(bullC, 15), size=size.tiny)
plotshape(dnMark, "Short Confluence", shape.triangledown, location.absolute, color=color.new(bearC, 15), size=size.tiny)

// Live setup state (relative strength + price trend confluence)
string setupTxt = longRegime ? "LONG" : shortRegime ? "SHORT" : "Neutral"
color  setupCol = longRegime ? bullC : shortRegime ? bearC : color.new(color.gray, 20)

// Single tidy tag at the right edge showing the live setup
var label rsTag = na
if barstate.islast
    string tagTxt = longRegime ? "LONG ▲" : shortRegime ? "SHORT ▼" : "Neutral"
    if na(rsTag)
        rsTag := label.new(bar_index, plotSeries, tagTxt, xloc=xloc.bar_index, yloc=yloc.price,
             style=label.style_label_left, textcolor=color.white, color=setupCol, size=size.small)
    else
        label.set_xy(rsTag, bar_index, plotSeries)
        label.set_text(rsTag, tagTxt)
        label.set_color(rsTag, setupCol)

// ─── Dashboard (light theme) ─────────────────────────────────────────────────
color tc = color.new(color.gray, 20)
color hd = color.new(color.gray, 90)

var table t = table.new(
     dashPos == "Top Right" ? position.top_right : dashPos == "Top Left" ? position.top_left : dashPos == "Bottom Right" ? position.bottom_right : position.bottom_left,
     2, 5,
     bgcolor=color.new(color.white, 5),
     border_color=color.new(color.gray, 60), border_width=1,
     frame_color=color.new(color.gray, 40), frame_width=1)

if showDash and barstate.islast
    string ptTxt = priceBull ? "Up ▲" : priceBear ? "Down ▼" : "Flat"
    color  ptCol = priceBull ? bullC : priceBear ? bearC : tc

    benchName = str.replace_all(benchSym, "AMEX:", "")
    benchName := str.replace_all(benchName, "NASDAQ:", "")

    table.cell(t, 0, 0, "RS Line", text_color=tc, bgcolor=hd, text_size=size.small)
    table.cell(t, 1, 0, "vs " + benchName, text_color=tc, bgcolor=hd, text_size=size.small)
    // Relative strength (vs benchmark)
    table.cell(t, 0, 1, "Rel. Strength", text_color=tc, text_size=size.small)
    table.cell(t, 1, 1, na(mrs) ? "—" : (rsBull ? "Leads " : "Lags ") + str.tostring(mrs, "#.#") + "%", text_color=color.white, bgcolor=na(mrs) ? color.new(color.gray, 20) : (rsBull ? bullC : bearC), text_size=size.small)
    // Absolute price trend
    table.cell(t, 0, 2, "Price Trend", text_color=tc, text_size=size.small)
    table.cell(t, 1, 2, ptTxt, text_color=ptCol, text_size=size.small)
    // Confluence verdict — the actionable line
    table.cell(t, 0, 3, "Setup", text_color=tc, text_size=size.small)
    table.cell(t, 1, 3, setupTxt, text_color=color.white, bgcolor=setupCol, text_size=size.small)
    // Reminder of what "Setup" needs
    table.cell(t, 0, 4, "Needs", text_color=tc, text_size=size.small)
    table.cell(t, 1, 4, "RS + trend agree", text_color=tc, text_size=size.small)

// ─── Alerts ──────────────────────────────────────────────────────────────────
mrsCrossUp   = ta.crossover(mrs, 0)
mrsCrossDown = ta.crossunder(mrs, 0)

bool alertsOnBarClose = input.bool(true, "Alerts only on bar close (confirmed)", group="Alerts")
bool alertOk = not alertsOnBarClose or barstate.isconfirmed
alertcondition(alertOk and (fireUp),       "RS Long Confluence",   "RSL · Long Confluence · {{ticker}} {{interval}}")
alertcondition(alertOk and (fireDown),     "RS Short Confluence",  "RSL · Short Confluence · {{ticker}} {{interval}}")
alertcondition(alertOk and (mrsCrossUp),   "Mansfield Cross Up",   "RSL · Mansfield Cross Up · {{ticker}} {{interval}}")
alertcondition(alertOk and (mrsCrossDown), "Mansfield Cross Down", "RSL · Mansfield Cross Down · {{ticker}} {{interval}}")

Overview

Relative Strength Line [WavesUnchained] plots either a raw relative strength ratio or a Mansfield RS oscillator in a separate pane. Confluence signals trigger when relative strength performance aligns with the price trend relative to an exponential moving average. Configurable settings include the benchmark symbol, Mansfield moving average length, price trend EMA length, signal marker spacing, and dashboard display options.

Details

Published by

casoon on GitHub

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Trend, Oscillators & momentum, Screeners & dashboards

Markets

Stocks

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.

Topics

pine-scriptpinescripttechnical-analysistrading-indicatorstrading-strategiestradingview

Settings

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

SettingTypeDefaultVariable
BenchmarksymbolAMEX:SPYbenchSym
DisplaystringMansfield RSdisplayMode
Mansfield MA Lengthint50mrsLen
Price Trend EMAint50trendLen
Show Confluence MarkersbooltrueshowLead
Min Bars Between Markersint5minGap
Marker Distance from Linefloat0.4markerGap
Show DashboardbooltrueshowDash
Dashboard PositionstringTop RightdashPos
Outperformingcolor#00c853bullC
Underperformingcolor#d50000bearC
Alerts only on bar close (confirmed)booltruealertsOnBarClose
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

218 stars

Multi-Timeframe Analysis Suite calculates trend direction and momentum conditions across five user-selected timeframes using moving averages, RSI, and Stochastic oscillators. It evaluates moving average slope and oscillator levels to compute trend alignment, m

Indicator v6 Screeners & dashboardsTrend
Updated 3 months ago · None stated GitHub repository of Multi-Timeframe Analysis Suite

KamaFama

by Mastaaa1987
141 stars

KamaFama is an indicator that translates a Freqtrade trading strategy into Pine Script for visualization. It combines Kaufman Adaptive Moving Average (KAMA), MAMA/FAMA calculations derived via Hilbert Transform, Williams %R, and correlation trend filters to ev

Indicator v6 Moving averagesOscillators & momentum
Updated 6 weeks ago · MIT GitHub repository of KamaFama

Manias, Panics and Crashes

by MeridianAlgo
9 stars

Manias, Panics and Crashes is a separate-pane market regime indicator that quantifies market sentiment and systemic risk. It processes technical metrics including RSI, moving averages, and volume alongside optional intermarket data such as VIX volatility and c

Indicator v6 Oscillators & momentumVolatility & bands
Updated 4 months ago · MIT GitHub repository of Manias, Panics and Crashes

Nexural Pressure Pro

by JasonTeixeira
9 stars

Nexural Pressure Pro is a composite pressure indicator that measures directional market momentum using volume-weighted directional movement, order flow delta, aggression, and efficiency ratio metrics. It filters out low-activity bars using configurable volume

Indicator v6 Oscillators & momentumVolume
Updated 12 days ago · Custom licence GitHub repository of Nexural Pressure Pro

The Asset Rotation System evaluates relative trend strength and rotational performance across up to six selectable assets. It calculates trend classification based on user-selected technical indicators including RSI, CCI, SuperTrend, DMI, and Parabolic SAR. Th

Indicator v6 Oscillators & momentumTrend
Updated 8 months ago · None stated GitHub repository of Asset Rotation System [InvestorUnknown]
53 stars

This indicator analyzes historical candle direction and price range over a configurable lookback window to gauge market trend. It categorizes trend direction using candle count, price range sum, or both. Signals are filtered using a Simple Moving Average to en

Indicator v6 TrendOscillators & momentum
Updated 2 months ago · MPL-2.0 GitHub repository of Candle Counter + MA + RSI + Mode

More indicators

Trade Your Charts With a Regulated Broker

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

Compare brokers