Skip to content

How to highlight TradingView alert setups with text and shapes?

How to highlight TradingView alert setups with text and shapes?

Section titled “How to highlight TradingView alert setups with text and shapes?”

TL;DR
Create a boolean that flags the alert, feed it to plotshape() (or labels/backgrounds) for visuals, and pass the same boolean to alertcondition() so the chart and alert stay in sync.

DifficultyBeginner
Time to implement10-15 min
CategoryVisual Effects
//@version=5
indicator("EMA crossover alerts", overlay=true)
fast = ta.ema(close, 10)
slow = ta.ema(close, 30)
longTrigger = ta.crossover(fast, slow)
plotshape(longTrigger, "Long alert", shape=shape.triangleup, color=color.new(color.lime, 0), location=location.belowbar, text="Long alert")
alertcondition(longTrigger, "EMA bull cross", "Fast EMA crossed above slow EMA")
Tip. Reference prior-bar data (`[1]`) when computing highs/lows so the setup does not instantly invalidate itself on the same bar.

Alerts you can see are easier to trust. Visual cues show how often a condition occurs, help tune thresholds, and reveal false positives before you wire alerts to automation. Reusing the same boolean for visuals and alert conditions guarantees consistency.

  • Define alert triggers as reusable booleans.
  • Layer shapes, labels, and background shading from that boolean.
  • Register alert conditions with descriptive titles and messages.
  • Account for the real-time vs historical difference when testing frequency.
CallPurpose
plotshape(condition, ...)Draws icons/text whenever the condition is true.
label.new(x, y, text, ...)Places rich text when you need more than a shape.
bgcolor(color)Tints the chart background to highlight the setup window.
alertcondition(condition, title, message)Registers the alert with TradingView.
ta.crossover(series1, series2)Convenient trigger for crossover-based alerts.
  1. Build a boolean trigger
    Encapsulate your alert logic in a single true/false value.

    fast = ta.ema(close, 21)
    slow = ta.ema(close, 55)
    longBreakout = ta.crossover(fast, slow)
  2. Add visual cues
    Choose shapes, labels, or background fills to communicate the trigger.

    plotshape(longBreakout,
    title="Bull trigger",
    location=location.belowbar,
    shape=shape.arrowup,
    color=color.new(color.green, 0),
    text="Bull")
  3. Register the actual alert
    Feed the same boolean into alertcondition() and craft helpful messages.

    alertcondition(longBreakout,
    title="EMA bull crossover",
    message="Fast EMA crossed above slow EMA")
//@version=5
indicator("Breakout alert highlighter", overlay=true, max_labels_count=500)
lengthPrice = input.int(20, "Price breakout lookback", minval=1)
lengthVolume = input.int(10, "Volume breakout lookback", minval=1)
highestClose = ta.highest(close[1], lengthPrice)
highestVol = ta.highest(volume[1], lengthVolume)
priceBreakout = close > highestClose
volumeBreakout = volume > highestVol
plot(highestClose, "Price ceiling", color=color.new(color.blue, 60))
plot(highestVol, "Volume ceiling", color=color.new(color.orange, 60), display=display.none)
plotshape(priceBreakout,
title="Price breakout",
location=location.abovebar,
shape=shape.flag,
color=color.new(color.green, 0),
textcolor=color.white,
text="Price\nalert")
plotshape(volumeBreakout,
title="Volume breakout",
location=location.belowbar,
shape=shape.diamond,
color=color.new(color.orange, 0),
textcolor=color.white,
text="Volume\nalert")
if priceBreakout
label.new(bar_index, high,
"Price breakout\nClose: " + str.tostring(close, format.mintick),
textcolor=color.white,
bgcolor=color.new(color.green, 70))
bgcolor(priceBreakout ? color.new(color.green, 85) : na)
alertcondition(priceBreakout, "Price breakout", "Close moved above the recent ceiling")
alertcondition(volumeBreakout, "Volume breakout", "Volume exceeded the lookback high")
Why this works.
  • Single-source booleans power both visuals and alerts, keeping them aligned.
  • Shapes, labels, and background tinting offer varying levels of emphasis for the same setup.
  • Delaying the lookback (`series[1]`) ensures the breakout compares against prior bars, avoiding accidental self-confirmation.
  • Historical bars calculate once per close, while real-time bars evaluate every update. Expect more real-time alerts if your logic does not require bar close.
  • Use alert.freq_once_per_bar_close when creating manual alerts to match historical highlights.
  • Combine shapes with hline() or plot() to show thresholds alongside triggers.
  • Remove shapes or labels programmatically (label.delete()) if you need to stay under TradingView’s drawing limits.

Ensure the condition variable is true when the bar closes—plotshape() respects the same boolean each bar. If you use barstate.isconfirmed, the alert may fire earlier than the visual.

Make sure the condition resets to false when criteria are not met. For example, use ta.crossover() instead of close > open if you only want a single-bar trigger.

How do I highlight multi-bar alert windows?

Section titled “How do I highlight multi-bar alert windows?”

Track state with a var bool inZone flag; set it to true when the trigger happens and back to false after your window expires, then feed inZone into bgcolor().

  • Define alerts as reusable booleans so visuals and alertcondition() stay aligned.
  • Layer shapes, labels, and background colours to explain why and where alerts would fire.
  • Expect real-time alerts to trigger more often than historical bars if your condition evaluates intra-bar.
  • Clean visuals accelerate tuning and build confidence before connecting alerts to automation.

Adapted from tradingcode.net, optimised for Algo Trade Analytics users.