Indicator · Pine Script v6 · On the chart

Multi-Condition Alert Manager [QuantForge]

by QuantForgeHQ

This overlay indicator unifies three optional alert modules on the price chart.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code89
Settings9inputs
LicenceMIT
Last update3 months ago6 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

89 lines of Pine Script v6 from multi_condition_alert_manager_v1.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

multi_condition_alert_manager_v1.pine
//@version=6
indicator("Multi-Condition Alert Manager [QuantForge]", overlay = true)

// ============================================================
// Multi-Condition Alert Manager - QuantForge portfolio demo
// Three independent, toggleable alert conditions:
//   1. EMA cross (fast over/under slow)
//   2. Price level cross (user-defined line)
//   3. RSI overbought / oversold
// Fires webhook-ready JSON via alert() on confirmed bars only.
// Setup: create ONE alert on this indicator with the condition
// "Any alert() function call". All enabled signals route
// through it with a machine-readable payload.
// Note: JSON is built by string concatenation on purpose.
// str.format treats { and } as placeholder syntax and fails
// at runtime on JSON-shaped strings.
// ============================================================

// ---------- Inputs ----------
useEmaX   = input.bool(true,  "Enable EMA cross alerts",  group = "EMA cross")
emaFastL  = input.int(20,  "Fast EMA", minval = 1, group = "EMA cross")
emaSlowL  = input.int(50,  "Slow EMA", minval = 2, group = "EMA cross")
useLevel  = input.bool(true,  "Enable price level alerts", group = "Price level")
levelPx   = input.float(0.0, "Price level (0 = off)", minval = 0, group = "Price level")
useRsi    = input.bool(true,  "Enable RSI alerts", group = "RSI")
rsiL      = input.int(14, "RSI length", minval = 2, group = "RSI")
rsiOB     = input.float(70, "Overbought", minval = 50, maxval = 99, group = "RSI")
rsiOS     = input.float(30, "Oversold",  minval = 1,  maxval = 50, group = "RSI")

// ---------- Conditions (confirmed bars only) ----------
emaFast = ta.ema(close, emaFastL)
emaSlow = ta.ema(close, emaSlowL)
rsiVal  = ta.rsi(close, rsiL)

emaCrossUp   = useEmaX and ta.crossover(emaFast, emaSlow)
emaCrossDn   = useEmaX and ta.crossunder(emaFast, emaSlow)
levelCrossUp = useLevel and levelPx > 0 and ta.crossover(close, levelPx)
levelCrossDn = useLevel and levelPx > 0 and ta.crossunder(close, levelPx)
rsiOverB     = useRsi and ta.crossover(rsiVal, rsiOB)
rsiOverS     = useRsi and ta.crossunder(rsiVal, rsiOS)

// ---------- Webhook-ready JSON payloads (built by concatenation) ----------
jsonMsg(string signal, string detail) =>
    "{\"ticker\":\"" + syminfo.ticker +
     "\",\"timeframe\":\"" + timeframe.period +
     "\",\"signal\":\"" + signal +
     "\",\"detail\":\"" + detail +
     "\",\"price\":" + str.tostring(close, format.mintick) +
     ",\"time\":\"" + str.format_time(time, "yyyy-MM-dd HH:mm", "UTC") + "\"}"

if barstate.isconfirmed
    if emaCrossUp
        alert(jsonMsg("ema_cross_up",  "Fast EMA crossed above slow EMA"), alert.freq_once_per_bar_close)
    if emaCrossDn
        alert(jsonMsg("ema_cross_down","Fast EMA crossed below slow EMA"), alert.freq_once_per_bar_close)
    if levelCrossUp
        alert(jsonMsg("level_break_up",  "Close crossed above the price level"), alert.freq_once_per_bar_close)
    if levelCrossDn
        alert(jsonMsg("level_break_down","Close crossed below the price level"), alert.freq_once_per_bar_close)
    if rsiOverB
        alert(jsonMsg("rsi_overbought", "RSI crossed above the overbought line"), alert.freq_once_per_bar_close)
    if rsiOverS
        alert(jsonMsg("rsi_oversold",   "RSI crossed below the oversold line"), alert.freq_once_per_bar_close)

// ---------- Visuals ----------
plot(emaFast, "Fast EMA", color = color.new(color.teal, 0))
plot(emaSlow, "Slow EMA", color = color.new(color.orange, 0))
plot(useLevel and levelPx > 0 ? levelPx : na, "Level", color = color.new(color.gray, 30), style = plot.style_linebr, linewidth = 2)

plotshape(emaCrossUp,   "EMA up",    style = shape.triangleup,   location = location.belowbar, color = color.teal,   size = size.small)
plotshape(emaCrossDn,   "EMA down",  style = shape.triangledown, location = location.abovebar, color = color.orange, size = size.small)
plotshape(levelCrossUp or levelCrossDn, "Level cross", style = shape.diamond, location = location.absolute, color = color.gray, size = size.tiny)
plotshape(rsiOverB, "RSI OB", style = shape.xcross, location = location.abovebar, color = color.red,   size = size.tiny)
plotshape(rsiOverS, "RSI OS", style = shape.xcross, location = location.belowbar, color = color.green, size = size.tiny)

// ---------- Status table ----------
var table t = table.new(position.top_right, 2, 4, border_width = 1)
if barstate.islast
    hdrBg = color.new(color.gray, 70)
    onBg  = color.new(color.teal, 80)
    offBg = color.new(color.gray, 90)
    table.cell(t, 0, 0, "Alert module",  bgcolor = hdrBg, text_size = size.small)
    table.cell(t, 1, 0, "State",         bgcolor = hdrBg, text_size = size.small)
    table.cell(t, 0, 1, "EMA cross " + str.tostring(emaFastL) + "/" + str.tostring(emaSlowL), text_size = size.small)
    table.cell(t, 1, 1, useEmaX ? "ON" : "OFF", bgcolor = useEmaX ? onBg : offBg, text_size = size.small)
    table.cell(t, 0, 2, "Level " + (levelPx > 0 ? str.tostring(levelPx, format.mintick) : "unset"), text_size = size.small)
    table.cell(t, 1, 2, useLevel and levelPx > 0 ? "ON" : "OFF", bgcolor = useLevel and levelPx > 0 ? onBg : offBg, text_size = size.small)
    table.cell(t, 0, 3, "RSI " + str.tostring(rsiL) + " " + str.tostring(rsiOS, "#") + "/" + str.tostring(rsiOB, "#"), text_size = size.small)
    table.cell(t, 1, 3, useRsi ? "ON" : "OFF", bgcolor = useRsi ? onBg : offBg, text_size = size.small)

Overview

Multi-Condition Alert Manager [QuantForge] plots a fast and a slow exponential moving average and an optional horizontal price level. On confirmed bars only, it sends webhook-ready JSON when the fast average crosses the slow one, when close crosses the user price level, or when RSI crosses its overbought or oversold thresholds. Toggles and lengths control each module. An on-chart table shows which modules are armed. It does not place trades.

Details

Published by

QuantForgeHQ on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Moving averages, Oscillators & momentum, Support & resistance, Screeners & dashboards

Markets

Any symbol

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.

Settings

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

SettingTypeDefaultVariable
Enable EMA cross alertsbooltrueuseEmaX
Fast EMAint20emaFastL
Slow EMAint50emaSlowL
Enable price level alertsbooltrueuseLevel
Price level (0 = off)float0.0levelPx
Enable RSI alertsbooltrueuseRsi
RSI lengthint14rsiL
Overboughtfloat70rsiOB
Oversoldfloat30rsiOS
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

API Integration Examples

by danielbodnar
2 stars

This indicator demonstrates Pine Script data requests and draws them on the price chart. It plots a four-hour simple moving average plus the daily high and low as step lines, and it plots twenty-bar relative performance versus SPY. It also requests QQQ, VIX, v

Indicator v6 Moving averagesSupport & resistance Repaints
Updated 2 months ago · MIT GitHub repository of API Integration Examples

This overlay indicator plots a Supertrend from an ATR length and factor, four exponential moving averages, and a selectable VWAP or TWAP taken from a chosen timeframe on the price chart. It also shows MACD and stochastic with adjustable lengths, smoothing, ver

Indicator v5 Oscillators & momentumMoving averages
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup: Vijay Thakare Option Buying Scalping Setup

PivotHighLow

by Alorse
330 stars

This indicator calculates pivot high and pivot low points on the price chart based on configurable left and right bar counts. Confirmed pivot highs and lows are plotted with negative bar offsets directly on the price chart using line and cross styles. Addition

Indicator v4 Support & resistanceOscillators & momentum Repaints
Updated 2 months ago · None stated GitHub repository of PivotHighLow
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

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