Appearance
Alerts
How do you get told when your script's condition happens? Call alert() where the condition holds, or declare it with alertcondition(), then add a rule for the script in the Alerts pane. The terminal's server runs the script each time a bar closes and fires every alert the script raised on that bar.
pine
//@version=6
indicator("EMA cross alerts", overlay = true)
float fast = ta.ema(close, 9)
float slow = ta.ema(close, 21)
plot(fast, "Fast", color = color.teal)
plot(slow, "Slow", color = color.orange)
if ta.crossover(fast, slow)
// the message is a string you build, so it can hold any value
alert("EMA 9 crossed above EMA 21 at " +
str.tostring(close, format.mintick))
alertcondition(ta.crossunder(fast, slow), "Cross down",
"{{ticker}} crossed down at {{close}}")alert() and alertcondition()
alert(message, freq) fires when the code reaches it, so it fires on a bar only if that bar runs the call. Put it inside an if, as above, and build the message with str.tostring and +. freq says how often one call may fire:
freq | Fires |
|---|---|
alert.freq_once_per_bar (default) | At most once a bar from each call |
alert.freq_once_per_bar_close | The same here, since every run is on a closed bar |
alert.freq_all | Every time the call runs, so a loop can fire it more than once a bar |
alertcondition(condition, title, message) fires on each bar where condition is true. It sits at the top level, and its title names the alert. Its message is a constant string, so it carries the bar's values through placeholders.
Placeholders
A message can hold these placeholders, filled in when the alert fires. Case doesn't matter, and spaces inside the braces are fine.
| Placeholder | Becomes |
|---|---|
{{ticker}} | The rule's symbol |
{{open}}, {{high}}, {{low}}, {{close}}, {{volume}} | The bar's prices and volume, as plain numbers |
{{time}} | The bar's open time, in UTC, as 2026-11-09T14:00:00.000Z |
{{timenow}} | When the alert fired, in the same form |
{{interval}} | The rule's timeframe |
Any other placeholder stays as you typed it, TradingView's {{plot_0}} and {{strategy.order.action}} among them.
Here the placeholders work in alert() messages too. On TradingView they belong to alertcondition(), so a script meant for both builds alert()'s message from values.
A message left empty takes the condition's title, and with no title either, the rule's name.
Where alerts fire
On a chart, alert() and alertcondition() do nothing: a chart's run draws the script and raises no alert. Alerts fire from a rule, which the terminal's server checks every ten seconds, whether or not a page is open.
To make one, open the Alerts pane, add an alert of kind A script's alerts, and pick:
- a saved script that calls
alert()oralertcondition(); - the symbol it runs on;
- a timeframe of a minute or more.
When a new bar has closed and its data has arrived, the rule runs the script on closed bars and fires what the script raised on that newest bar. The first run starts 5,000 bars before you made the rule, and every later run starts from that same bar, so a var and every indicator read as they did. If the run stops on an error, the rule shows the error and fires nothing. If the data is late, it waits.
The rule keeps the script's text as it was when you saved the rule. After you change the script, make the rule again.
The Alerts pane's channels menu shows where a fire goes: a toast on the page, and your system's notifications while the tab is hidden, which the menu's Enable turns on. ntfy, a webhook and Telegram are set up on the terminal's server, and the menu says which of them are sending.
Traps
- No alert on a forming bar. A rule runs on closed bars only, so a condition that holds for a while inside a bar and is gone at its close never fires. That also means an alert never repaints: what fired is what the closed bar says.
alert()in a branch with ata.*call. Work values out before theif. Ata.*call inside the branch runs only on the bars that reach it, so it reads otherwise. See state in branches.alert.freq_allin a loop fires once per pass, which can be many alerts for one bar.- An edited script changes nothing in a rule made before the edit.
See also
- alert and alertcondition in the reference
- Strings and formatting, to build a message
- When a script runs, for closed and forming bars
- Errors and debugging