Credits
Created by https://x.com/SargonDinkha1
Links: GitHub · YouTube · Trading View
A modular, volume-weighted RSI indicator built for clarity and control.
✅ Profile-based auto modes (Scalping → Macro)
✅ Toggleable Buy/Sell signals with strict mode
✅ RSI MA overlays for smoother entries
Buy Signal
- RSI crosses above RSI MA
- RSI > 50 (or > 55 in strict mode)
Sell Signal
- RSI crosses below RSI MA
- RSI < 50 (or < 45 in strict mode)
Strict mode filters out weak signals for higher conviction entries.
Volatility-Adaptive RSI Thresholds:
Traditional RSI uses static levels (70/30).
VWRSI Pro replaces these with dynamic bands:
🔹dynHigh = mean + mult × deviation
🔹 dynLow = mean − mult × deviation
Technical write-up can be found here: https://github.com/HeyItsSamir/Volume-Weighted-RSI
//@version=6
indicator("Volume-Weighted RSI [VWRSI 2D Pro]", shorttitle="VWRSI Pro", format=format.price, precision=2)
// ----------------- Profile Selector -----------------
profile = input.string("Intraday", "Configuration Profile",
options=["Custom", "Scalping (≤30m)", "Intraday", "Swing / Weekly", "Macro (Monthly+)"], group="Profiles")
// ----------------- Manual Inputs -----------------
rsiLengthInput = input.int(14, "RSI Length", minval=1, group="RSI Settings")
rsiSource = input.source(close, "RSI Source", group="RSI Settings")
useDynamicBands = input.bool(false, "Use Dynamic Thresholds", group="RSI Settings")
bandMult = input.float(1.0, "Band Multiplier", step=0.1, group="RSI Settings")
bandLengthInput = input.int(50, "Band Length", minval=1, group="RSI Settings")
maEnabled = input.bool(true, "Show RSI MA", group="RSI MA Settings")
maLengthInput = input.int(14, "RSI MA Length", minval=1, group="RSI MA Settings")
maType = input.string("EMA", "MA Type", ["EMA","SMA","RMA","WMA"], group="RSI MA Settings")
maColor = input.color(#cccccc, "RSI MA Color", group="RSI MA Settings")
colorUp = input.color(#00ffbb, "Bullish Color")
colorDown = input.color(#ff1100, "Bearish Color")
// ----------------- Profile Logic -----------------
rsiLength = switch profile
"Scalping (≤30m)" => 21
"Intraday (1h–D)" => 14
"Swing / Weekly" => 9
"Macro (Monthly+)" => 6
"Custom" => rsiLengthInput
=> 14
maLength = switch profile
"Scalping (≤30m)" => 28
"Intraday (1h–D)" => 14
"Swing / Weekly" => 9
"Macro (Monthly+)" => 6
"Custom" => maLengthInput
=> 14
bandLength = switch profile
"Scalping (≤30m)" => 20
"Intraday (1h–D)" => 50
"Swing / Weekly" => 100
"Macro (Monthly+)" => 200
"Custom" => bandLengthInput
=> 50
// ----------------- Functions -----------------
ma(src, len, type) =>
switch type
"SMA" => ta.sma(src, len)
"EMA" => ta.ema(src, len)
"RMA" => ta.rma(src, len)
"WMA" => ta.wma(src, len)
pine_vwrma(x, y) =>
ta.rma(x * volume, y) / ta.rma(volume, y)
// ----------------- RSI Calculation -----------------
up = pine_vwrma(math.max(ta.change(rsiSource), 0), rsiLength)
down = pine_vwrma(-math.min(ta.change(rsiSource), 0), rsiLength)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiMA = ma(rsi, maLength, maType)
// ----------------- Plot RSI -----------------
plot(rsi, "VWRSI", color=rsi >= 50 ? colorUp : colorDown, linewidth=2)
plot(maEnabled ? rsiMA : na, "RSI MA", color=maColor, linewidth=2, style=plot.style_line)
// Dynamic Bands Calculation
rsiMean = ta.sma(rsi, bandLength)
rsiDev = ta.stdev(rsi, bandLength)
dynHigh = rsiMean + bandMult * rsiDev
dynLow = rsiMean - bandMult * rsiDev
// ----------------- Plot Bands -----------------
h70 = plot(useDynamicBands ? dynHigh : 70, "Overbought", color=color.new(colorDown, 40))
h30 = plot(useDynamicBands ? dynLow : 30, "Oversold", color=color.new(colorUp, 40))
h50 = hline(50, "Midline", color=color.new(#888888, 70))
fill(h70, plot(100), color=color.new(colorDown, 90))
fill(plot(0), h30, color=color.new(colorUp, 90))