Paste this indicator into Pine Editor and add it to a standard candlestick chart. Select a mode and direction before creating the alert. EMA lines appear in EMA mode; Up and Down markers show confirmed events in every mode. The script reports conditions and does not place orders.
Configurable crossings with confirmed markers and two alert creation optionspinescript
//@version=6
indicator("Crossover alerts [Pineify]", overlay=true)
mode = input.string("EMA", "Mode", options=["EMA", "MACD signal", "MACD zero", "RSI level exits", "RSI signal"])
direction = input.string("Both", "Direction", options=["Both", "Up", "Down"])
fastLength = input.int(9, "Fast EMA length", minval=1)
slowLength = input.int(21, "Slow EMA length", minval=1)
macdFast = input.int(12, "MACD fast length", minval=1)
macdSlow = input.int(26, "MACD slow length", minval=1)
macdSignal = input.int(9, "MACD signal length", minval=1)
rsiLength = input.int(14, "RSI length", minval=1)
rsiSignalLength = input.int(14, "RSI SMA length", minval=1)
lowerLevel = input.float(30, "RSI lower level", minval=0, maxval=49)
upperLevel = input.float(70, "RSI upper level", minval=51, maxval=100)
fast = ta.ema(close, fastLength)
slow = ta.ema(close, slowLength)
[macd, signal, histogram] = ta.macd(close, macdFast, macdSlow, macdSignal)
rsi = ta.rsi(close, rsiLength)
rsiAverage = ta.sma(rsi, rsiSignalLength)
// Calculate each crossing on every bar before selecting a mode.
emaUp = ta.crossover(fast, slow)
emaDown = ta.crossunder(fast, slow)
macdUp = ta.crossover(macd, signal)
macdDown = ta.crossunder(macd, signal)
zeroUp = ta.crossover(macd, 0.0)
zeroDown = ta.crossunder(macd, 0.0)
rsiExitUp = ta.crossover(rsi, lowerLevel)
rsiExitDown = ta.crossunder(rsi, upperLevel)
rsiUp = ta.crossover(rsi, rsiAverage)
rsiDown = ta.crossunder(rsi, rsiAverage)
crossUp = switch mode
"EMA" => emaUp
"MACD signal" => macdUp
"MACD zero" => zeroUp
"RSI level exits" => rsiExitUp
=> rsiUp
crossDown = switch mode
"EMA" => emaDown
"MACD signal" => macdDown
"MACD zero" => zeroDown
"RSI level exits" => rsiExitDown
=> rsiDown
confirmedUp = barstate.isconfirmed and crossUp and direction != "Down"
confirmedDown = barstate.isconfirmed and crossDown and direction != "Up"
plot(mode == "EMA" ? fast : na, "Fast EMA", color.blue)
plot(mode == "EMA" ? slow : na, "Slow EMA", color.orange)
plotshape(confirmedUp, "Confirmed up", shape.triangleup, location.belowbar, color.teal, text="Up")
plotshape(confirmedDown, "Confirmed down", shape.triangledown, location.abovebar, color.red, text="Down")
// Select these named conditions for separate direction alerts.
alertcondition(confirmedUp, "Confirmed up cross", "Up cross on {{ticker}} at {{close}}")
alertcondition(confirmedDown, "Confirmed down cross", "Down cross on {{ticker}} at {{close}}")
// Or select Any alert() function call for a dynamic message.
if confirmedUp or confirmedDown
side = confirmedUp ? "up" : "down"
message = mode + " cross " + side + " | " + syminfo.tickerid + " | " + timeframe.period + " | close=" + str.tostring(close, format.mintick)
alert(message, alert.freq_once_per_bar_close)