Indicator · Pine Script v6 · On the chart

Scalping 3-Signal Dashboard v2

by eddiebelaval· code credited to Scalping 3-Signal Dashboard v2 (EMA + RSI + VFI)

This indicator combines a fast and slow exponential moving average crossover, an RSI filter, and a volume flow indicator into a weighted directional score.

View on GitHub

GitHub stars7on the repository
Pine versionv6current
Lines of code245
Settings18inputs
LicenceNone statedfile: MPL-2.0
Last update3 months ago24 Jul 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

245 lines of Pine Script v6 from pinescript/moving_averages/top-score-scalping-3-signal-dashboard-v2.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

top-score-scalping-3-signal-dashboard-v2.pine
// This Pine Script™ v6 indicator source code is subject to the terms of the Mozilla Public License 2.0
// © Scalping 3-Signal Dashboard v2 (EMA + RSI + VFI)
// Designed for XAUUSD / Forex 5-Minute Scalping

//@version=6
indicator("Scalping 3-Signal Dashboard v2", overlay=true, max_labels_count=500)

// ══════════════════════════════════════════════════════════════════════
// ░░░ INPUTS ░░░
// ══════════════════════════════════════════════════════════════════════

// --- EMA Settings ---
grpEMA    = "═══ EMA Crossover ═══"
emaFastL  = input.int(9,   "EMA Fast Length",   minval=1, group=grpEMA)
emaSlowL  = input.int(21,  "EMA Slow Length",   minval=1, group=grpEMA)

// --- RSI Settings ---
grpRSI    = "═══ RSI Filter ═══"
rsiLen    = input.int(14,  "RSI Length",         minval=1,   group=grpRSI)
rsiBuyLv  = input.int(50,  "RSI Buy Level (>)", minval=1,   maxval=99, group=grpRSI)
rsiSellLv = input.int(50,  "RSI Sell Level (<)",minval=1,   maxval=99, group=grpRSI)

// --- VFI (Volume Flow Indicator) Settings ---
grpVFI    = "═══ Volume Flow (VFI) ═══"
vfiLen    = input.int(130, "VFI Length",         minval=1,   group=grpVFI)
vfiCoef   = input.float(0.2, "VFI Coef",        minval=0.01, step=0.01, group=grpVFI)
vfiSmooth = input.int(3,   "VFI Smoothing",     minval=1,   group=grpVFI)

// --- Weight Settings ---
grpW      = "═══ Signal Weights (%) ═══"
wEMA      = input.int(40,  "EMA Weight",        minval=0, maxval=100, group=grpW)
wRSI      = input.int(35,  "RSI Weight",        minval=0, maxval=100, group=grpW)
wVFI      = input.int(25,  "VFI Weight",        minval=0, maxval=100, group=grpW)

// --- Dashboard Settings ---
grpDash   = "═══ Dashboard ═══"
dashPos   = input.string("Top Right", "Dashboard Position", options=["Top Left","Top Right","Bottom Left","Bottom Right","Middle Left","Middle Right"], group=grpDash)
dashSize  = input.string("normal", "Text Size", options=["tiny","small","normal","large","huge"], group=grpDash)
showArrow = input.bool(true, "Show Buy/Sell Arrows", group=grpDash)
minProb   = input.int(60,  "Min Probability for Arrow (%)", minval=0, maxval=100, group=grpDash)
bgColor   = input.color(color.new(#0D1117, 0), "Background Color", group=grpDash)
txtColor  = input.color(color.new(#C9D1D9, 0), "Text Color", group=grpDash)

// --- Alert Settings ---
grpAlert  = "═══ Alerts ═══"
alertOn   = input.bool(true, "Enable Alerts", group=grpAlert)

// ══════════════════════════════════════════════════════════════════════
// ░░░ CALCULATIONS ░░░
// ══════════════════════════════════════════════════════════════════════

// --- EMA ---
emaFast = ta.ema(close, emaFastL)
emaSlow = ta.ema(close, emaSlowL)

emaBullish = emaFast > emaSlow
emaBearish = emaFast < emaSlow

// --- RSI ---
rsiVal = ta.rsi(close, rsiLen)

rsiBullish = rsiVal > rsiBuyLv
rsiBearish = rsiVal < rsiSellLv

// --- VFI (Volume Flow Indicator) ---
typ      = hlc3
inter    = math.log(typ) - math.log(typ[1])
vInter   = ta.stdev(inter, 30)
cutOff   = vfiCoef * vInter * close
vave     = ta.sma(volume, vfiLen)[1]
vMax     = vave * 2.5
vc       = math.min(volume, vMax)
mf       = typ - typ[1]
vcp      = mf > cutOff ? vc : mf < -cutOff ? -vc : 0.0

rawVFI   = math.sum(vcp, vfiLen) / vave
vfiVal   = ta.ema(rawVFI, vfiSmooth)

vfiBullish = vfiVal > 0
vfiBearish = vfiVal < 0

// ══════════════════════════════════════════════════════════════════════
// ░░░ PROBABILITY CALCULATION ░░░
// ══════════════════════════════════════════════════════════════════════

totalW  = wEMA + wRSI + wVFI
fTotalW = totalW * 1.0
normEMA = fTotalW > 0 ? (wEMA * 1.0) / fTotalW * 100.0 : 33.33
normRSI = fTotalW > 0 ? (wRSI * 1.0) / fTotalW * 100.0 : 33.33
normVFI = fTotalW > 0 ? (wVFI * 1.0) / fTotalW * 100.0 : 33.33

buyScore  = (emaBullish ? normEMA : 0.0) + (rsiBullish ? normRSI : 0.0) + (vfiBullish ? normVFI : 0.0)
sellScore = (emaBearish ? normEMA : 0.0) + (rsiBearish ? normRSI : 0.0) + (vfiBearish ? normVFI : 0.0)

// ══════════════════════════════════════════════════════════════════════
// ░░░ COLORS ░░░
// ══════════════════════════════════════════════════════════════════════

colBuy     = #00E676
colSell    = #FF1744
colNeutral = #FFC107
colGray    = #555555

getClr(bull, bear) =>
    bull ? colBuy : bear ? colSell : colGray

emaClr = getClr(emaBullish, emaBearish)
rsiClr = getClr(rsiBullish, rsiBearish)
vfiClr = getClr(vfiBullish, vfiBearish)

// ══════════════════════════════════════════════════════════════════════
// ░░░ PLOT EMA LINES ░░░
// ══════════════════════════════════════════════════════════════════════

plot(emaFast, "EMA Fast", color=color.new(#00BCD4, 20), linewidth=2)
plot(emaSlow, "EMA Slow", color=color.new(#FF9800, 20), linewidth=2)

fillClr = emaBullish ? color.new(colBuy, 88) : color.new(colSell, 88)
p1 = plot(emaFast, display=display.none)
p2 = plot(emaSlow, display=display.none)
fill(p1, p2, color=fillClr)

// ══════════════════════════════════════════════════════════════════════
// ░░░ ARROWS ░░░
// ══════════════════════════════════════════════════════════════════════

buySignal  = buyScore >= minProb and buyScore > sellScore
sellSignal = sellScore >= minProb and sellScore > buyScore

buyTrigger  = buySignal and not buySignal[1]
sellTrigger = sellSignal and not sellSignal[1]

plotshape(showArrow and buyTrigger  ? low  : na, "BUY",  shape.labelup,   location.belowbar, colBuy,  size=size.small, text="BUY",  textcolor=color.white)
plotshape(showArrow and sellTrigger ? high : na, "SELL", shape.labeldown, location.abovebar, colSell, size=size.small, text="SELL", textcolor=color.white)

// ══════════════════════════════════════════════════════════════════════
// ░░░ DASHBOARD TABLE ░░░
// ══════════════════════════════════════════════════════════════════════

// --- Position mapping ---
tblPos = switch dashPos
    "Top Left"      => position.top_left
    "Top Right"     => position.top_right
    "Bottom Left"   => position.bottom_left
    "Bottom Right"  => position.bottom_right
    "Middle Left"   => position.middle_left
    "Middle Right"  => position.middle_right
    => position.top_right

txtSz = switch dashSize
    "tiny"   => size.tiny
    "small"  => size.small
    "normal" => size.normal
    "large"  => size.large
    "huge"   => size.huge
    => size.normal

// --- Border color based on signal ---
borderClr = buyScore >= minProb and buyScore > sellScore ? colBuy : sellScore >= minProb and sellScore > buyScore ? colSell : color.new(#30363D, 0)

// --- Table: 2 columns x 9 rows ---
var tbl = table.new(tblPos, 2, 9, bgcolor=bgColor, border_width=2, border_color=borderClr, frame_width=2, frame_color=borderClr)

// --- Build bar function ---
buildBar(pct) =>
    (pct >= 20 ? "█" : "░") + (pct >= 40 ? "█" : "░") + (pct >= 60 ? "█" : "░") + (pct >= 80 ? "█" : "░") + (pct >= 95 ? "█" : "░")

if barstate.islast

    // ── Row 0: Title ──
    table.cell(tbl, 0, 0, "⚡ SCALP DASHBOARD", text_color=color.white, text_size=txtSz, bgcolor=color.new(#161B22, 0), text_halign=text.align_left)
    table.cell(tbl, 1, 0, syminfo.ticker + " " + timeframe.period, text_color=color.new(#8B949E, 0), text_size=txtSz, bgcolor=color.new(#161B22, 0), text_halign=text.align_right)

    // ── Row 1: Column Headers ──
    headerBg = color.new(#21262D, 0)
    table.cell(tbl, 0, 1, "SIGNAL",  text_color=color.new(#8B949E, 0), text_size=txtSz, bgcolor=headerBg, text_halign=text.align_left)
    table.cell(tbl, 1, 1, "STATUS",  text_color=color.new(#8B949E, 0), text_size=txtSz, bgcolor=headerBg, text_halign=text.align_right)

    // ── Row 2: EMA ──
    emaStatusTxt = emaBullish ? "● BUY" : emaBearish ? "● SELL" : "● --"
    table.cell(tbl, 0, 2, "EMA " + str.tostring(emaFastL) + "/" + str.tostring(emaSlowL), text_color=txtColor, text_size=txtSz, text_halign=text.align_left)
    table.cell(tbl, 1, 2, emaStatusTxt, text_color=emaClr, text_size=txtSz, text_halign=text.align_right)

    // ── Row 3: RSI ──
    rsiStatusTxt = rsiBullish ? "● BUY" : rsiBearish ? "● SELL" : "● --"
    table.cell(tbl, 0, 3, "RSI(" + str.tostring(rsiLen) + ") " + str.tostring(rsiVal, "#.#"), text_color=txtColor, text_size=txtSz, text_halign=text.align_left)
    table.cell(tbl, 1, 3, rsiStatusTxt, text_color=rsiClr, text_size=txtSz, text_halign=text.align_right)

    // ── Row 4: VFI ──
    vfiStatusTxt = vfiBullish ? "● BUY" : vfiBearish ? "● SELL" : "● --"
    table.cell(tbl, 0, 4, "VFI(" + str.tostring(vfiLen) + ") " + str.tostring(vfiVal, "#.#"), text_color=txtColor, text_size=txtSz, text_halign=text.align_left)
    table.cell(tbl, 1, 4, vfiStatusTxt, text_color=vfiClr, text_size=txtSz, text_halign=text.align_right)

    // ── Row 5: Separator ──
    sepBg = color.new(#21262D, 0)
    table.cell(tbl, 0, 5, "", bgcolor=sepBg, text_size=size.tiny)
    table.cell(tbl, 1, 5, "", bgcolor=sepBg, text_size=size.tiny)

    // ── Row 6: Buy Probability ──
    buyPct    = str.tostring(buyScore, "#.#") + "%"
    buyBarTxt = buildBar(buyScore)
    buyBgClr  = buyScore >= minProb ? color.new(colBuy, 80) : bgColor
    table.cell(tbl, 0, 6, "BUY   " + buyPct, text_color=colBuy, text_size=txtSz, bgcolor=buyBgClr, text_halign=text.align_left)
    table.cell(tbl, 1, 6, buyBarTxt, text_color=colBuy, text_size=txtSz, bgcolor=buyBgClr, text_halign=text.align_right)

    // ── Row 7: Sell Probability ──
    sellPct    = str.tostring(sellScore, "#.#") + "%"
    sellBarTxt = buildBar(sellScore)
    sellBgClr  = sellScore >= minProb ? color.new(colSell, 80) : bgColor
    table.cell(tbl, 0, 7, "SELL  " + sellPct, text_color=colSell, text_size=txtSz, bgcolor=sellBgClr, text_halign=text.align_left)
    table.cell(tbl, 1, 7, sellBarTxt, text_color=colSell, text_size=txtSz, bgcolor=sellBgClr, text_halign=text.align_right)

    // ── Row 8: Verdict ──
    verdictTxt = ""
    verdictClr = colNeutral
    verdictBg  = bgColor
    if buyScore >= minProb and buyScore > sellScore
        verdictTxt := "▲ BUY ZONE " + str.tostring(buyScore, "#") + "%"
        verdictClr := color.white
        verdictBg  := color.new(colBuy, 40)
    else if sellScore >= minProb and sellScore > buyScore
        verdictTxt := "▼ SELL ZONE " + str.tostring(sellScore, "#") + "%"
        verdictClr := color.white
        verdictBg  := color.new(colSell, 40)
    else
        verdictTxt := "⏸ WAIT"
        verdictClr := colNeutral
        verdictBg  := color.new(#21262D, 0)

    table.cell(tbl, 0, 8, verdictTxt, text_color=verdictClr, text_size=txtSz, bgcolor=verdictBg, text_halign=text.align_center)
    table.cell(tbl, 1, 8, "", text_color=verdictClr, text_size=txtSz, bgcolor=verdictBg)
    table.merge_cells(tbl, 0, 8, 1, 8)

// ══════════════════════════════════════════════════════════════════════
// ░░░ ALERTS ░░░
// ══════════════════════════════════════════════════════════════════════

alertcondition(alertOn and buyTrigger,  title="Scalp BUY Signal",  message="SCALP BUY | Prob: {{plot_0}}% | EMA+RSI+VFI bullish on {{ticker}} {{interval}}")
alertcondition(alertOn and sellTrigger, title="Scalp SELL Signal", message="SCALP SELL | Prob: {{plot_0}}% | EMA+RSI+VFI bearish on {{ticker}} {{interval}}")

// ══════════════════════════════════════════════════════════════════════
// ░░░ BARCOLOR ░░░
// ══════════════════════════════════════════════════════════════════════

barcolor(buyScore >= minProb ? color.new(colBuy, 50) : sellScore >= minProb ? color.new(colSell, 50) : na)

Overview

Scalping 3-Signal Dashboard v2 draws an on-chart dashboard for those components and can plot buy or sell arrows when the score meets a user-set minimum. Lengths, RSI levels, component weights, dashboard position and size, colors, and alerts are adjustable. It is intended for five-minute gold and forex charts and does not define entries, exits, or stops.

Details

Published by

eddiebelaval on GitHub

Code credit

Scalping 3-Signal Dashboard v2 (EMA + RSI + VFI), as written in the script's header

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Screeners & dashboards, Moving averages, Oscillators & momentum, Volume

Markets

Forex, Gold

Timeframes

M1-M5

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
EMA Fast Lengthint9emaFastL
EMA Slow Lengthint21emaSlowL
RSI Lengthint14rsiLen
RSI Buy Level (>)int50rsiBuyLv
RSI Sell Level (<)int50rsiSellLv
VFI Lengthint130vfiLen
VFI Coeffloat0.2vfiCoef
VFI Smoothingint3vfiSmooth
EMA Weightint40wEMA
RSI Weightint35wRSI
VFI Weightint25wVFI
Dashboard PositionstringTop RightdashPos
Show all 18 settings
SettingTypeDefaultVariable
Text SizestringnormaldashSize
Show Buy/Sell ArrowsbooltrueshowArrow
Min Probability for Arrow (%)int60minProb
Background Colorcolorcolor.new(#0D1117, 0)bgColor
Text Colorcolorcolor.new(#C9D1D9, 0)txtColor
Enable AlertsbooltruealertOn
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 overlay indicator screens a pasted list of up to forty symbols and draws a table on the price chart. It classifies bullish or bearish setups from the percent change between the current candle and the candle 250 bars back, then shows RSI with a simple movi

Indicator v5 Oscillators & momentumVolume
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup - Ankush Bajaj Momentum Investing Setup
218 stars

TradersPost Trading Checklist is an overlay indicator that evaluates a suite of popular technical conditions for long and short trade setups. It checks session-anchored VWAP, fast and slow EMA alignments and crosses, 200 SMA, RSI overbought or oversold conditi

Indicator v6 Screeners & dashboardsTrend
Updated 3 months ago · None stated GitHub repository of TradersPost Trading Checklist

LiqSpikeBounceLong Feb2026

by agutinbaigo28
147 stars

LiqSpikeBounceLong Feb2026 is an indicator designed to identify long bounce entries following high-volume liquidation cascades in bearish market contexts. It checks if price is below an exponential moving average, then detects large single-bar drops exceeding

Indicator v5 Volatility & bandsVolume
Updated 6 weeks ago · MIT GitHub repository of LiqSpikeBounceLong Feb2026

8zz反指標v2

by hansai-art
121 stars

The 8zz Contrarian Indicator plots reverse sentiment trading signals directly on the price chart based on tracked retail post activity. It generates bullish signals during retail panic and bearish signals during market euphoria. The indicator features adjustab

Indicator v6 Moving averagesOscillators & momentum
Updated 3 months ago · None stated GitHub repository of 8zz反指標v2

Signal Strategy 15m

by tripolskypetr
72 stars

This indicator generates trend-following trade signals on the price chart by combining moving average crossovers with multi-factor filters. It triggers entry alerts when fast and slow EMAs cross in the direction of a baseline trend EMA, confirmed by non-extrem

Indicator v5 TrendMoving averages
Updated 3 days ago · MIT GitHub repository of Signal Strategy 15m

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