TradingView alerts run 24x7 on our servers and do not require users to be logged in to execute. Alerts are created from the charts user interface (UI). You will find all the information necessary to understand how alerts work and how to create them from the charts UI in the Help Center’s About TradingView alerts page.
Some of the alert types available on TradingView (generic alerts, drawing alerts and script alerts on order fill events) are created from symbols or scripts loaded on the chart and do not require specific coding. Any user can create these types of alerts from the charts UI.
Other types of alerts (script alerts triggering on alert() function calls, and alertcondition() alerts) require specific Pine Script™ code to be present in a script to create an alert event before script users can create alerts from them using the charts UI. Additionally, while script users can create script alerts triggering on order fill events from the charts UI on any strategy loaded on their chart, Pine Script™ programmers can specify explicit order fill alert messages in their script for each type of order filled by the broker emulator.
This page covers the different ways Pine Script™ programmers can code their scripts to create alert events from which script users will in turn be able to create alerts from the charts UI. We will cover:
Keep in mind that:
The different methods Pine Script™ programmers can use today to create alert events in their script are the result of successive enhancements deployed throughout Pine Script™’s evolution.
The alertcondition() function, which works in indicators only,
was the first feature allowing Pine Script™ programmers to create alert events.
Then came order fill alerts for strategies, which trigger when the broker emulator creates order fill events.
Order fill events require no special code for script users to create alerts on them,
but by way of the alert_message
parameter for order-generating strategy.*()
functions,
programmers can customize the message of alerts triggering on order fill events by defining a distinct alert message for any number of order fulfillment events.
The alert() function is the most recent addition to Pine Script™. It more or less supersedes alertcondition(), and when used in strategies, provides a useful complement to alerts on order fill events.
For Pine Script™ programmers, the alert() function will generally be easier and more flexible to work with. Contrary to alertcondition(), it allows for dynamic alert messages, works in both indicators and strategies and the programmer decides on the frequency of alert() events.
While alert() calls can be generated on any logic programmable in Pine Script™, including when orders are sent to the broker emulator in strategies, they cannot be coded to trigger when orders are executed (or filled) because after orders are sent to the broker emulator, the emulator controls their execution and does not report fill events back to the script directly.
When a script user wants to generate an alert on a strategy’s order fill events,
he must include those events when creating a script alert on the strategy in the “Create Alert” dialog box.
No special code is required in scripts for users to be able to do this.
The message sent with order fill events can,
however, be customized by programmers through use of the alert_message
parameter in order-generating strategy.*()
function calls.
A combination of alert() calls and the use of custom
alert_message
arguments in order-generating strategy.*()
calls should allow Pine Script™ programmers to generate
alert events on most conditions occurring in their script’s execution.
The alertcondition() function remains in Pine Script™ for backward compatibility, but it can also be used advantageously to generate distinct alerts available for selection as individual items in the “Create Alert” dialog box’s “Condition” field.
When a script user creates a script alert using the “Create Alert” dialog box, the events able to trigger the alert will vary depending on whether the alert is created from an indicator or a strategy.
A script alert created from an indicator will trigger when:
A script alert created from a strategy can trigger on alert() function calls, on order fill events, or both. The script user creating an alert on a strategy decides which type of events he wishes to include in his script alert. While users can create a script alert on order fill events without the need for a strategy to include special code, it must contain alert() calls for users to include alert() function calls in their script alert.
The alert() function has the following signature:
alert(message, freq)
message
freq
An “input string” specifying the triggering frequency of the alert. Valid arguments are:
alert.freq_once_per_bar
: Only the first call per realtime bar triggers the alert (default value).alert.freq_once_per_bar_close
: An alert is only triggered when the realtime bar closes and an alert() call is executed during that script iteration.alert.freq_all
: All calls during the realtime bar trigger the alert.The alert() function can be used in both indicators and strategies.
For an alert()
call to trigger a script alert configured on alert() function calls,
the script’s logic must allow the alert() call to execute,
and the frequency determined by the freq
parameter must allow the alert to trigger.
Note that by default, strategies are recalculated at the bar’s close, so if the
alert()
function with the frequency alert.freq_all
or alert.freq_once_per_bar
is used in a strategy,
then it will be called no more often than once at the bar’s close.
In order to enable the alert()
function to be called during the bar construction process, you need to enable the calc_on_every_tick
option.
Let’s look at an example where we detect crosses of the RSI centerline:
//@version=5
indicator("All `alert()` calls")
r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Trigger an alert on crosses.
if xUp
alert("Go long (RSI is " + str.tostring(r, "#.00)"))
else if xDn
alert("Go short (RSI is " + str.tostring(r, "#.00)"))
plotchar(xUp, "Go Long", "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Go Short", "▼", location.top, color.red, size = size.tiny)
hline(50)
plot(r)
If a script alert is created from this script:
freq
parameter in the alert() call,
the default value of alert.freq_once_per_bar
will be used, so the alert will only trigger the first time each of the
alert() calls is executed during the realtime bar.Note that:
Lastly, because alert() messages can be constructed dynamically at runtime, we could have used the following code to generate our alert events:
// Trigger an alert on crosses.
if xUp or xDn
firstPart = (xUp ? "Go long" : "Go short") + " (RSI is "
alert(firstPart + str.tostring(r, "#.00)"))
When users create a script alert on alert() function calls, the alert will trigger on any call the script makes to the alert() function, provided its frequency constraints are met. If you want to allow your script’s users to select which alert() function call in your script will trigger a script alert, you will need to provide them with the means to indicate their preference in your script’s inputs, and code the appropriate logic in your script. This way, script users will be able to create multiple script alerts from a single script, each behaving differently as per the choices made in the script’s inputs prior to creating the alert in the charts UI.
Suppose, for our next example, that we want to provide the option of triggering alerts on only longs, only shorts, or both. You could code your script like this:
//@version=5
indicator("Selective `alert()` calls")
detectLongsInput = input.bool(true, "Detect Longs")
detectShortsInput = input.bool(true, "Detect Shorts")
repaintInput = input.bool(false, "Allow Repainting")
r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Only generate entries when the trade's direction is allowed in inputs.
enterLong = detectLongsInput and xUp and (repaintInput or barstate.isconfirmed)
enterShort = detectShortsInput and xDn and (repaintInput or barstate.isconfirmed)
// Trigger the alerts only when the compound condition is met.
if enterLong
alert("Go long (RSI is " + str.tostring(r, "#.00)"))
else if enterShort
alert("Go short (RSI is " + str.tostring(r, "#.00)"))
plotchar(enterLong, "Go Long", "▲", location.bottom, color.lime, size = size.tiny)
plotchar(enterShort, "Go Short", "▼", location.top, color.red, size = size.tiny)
hline(50)
plot(r)
Note how:
alert()
function calls can be used in strategies also, with the provision that strategies, by default,
only execute on the close of realtime bars.
Unless calc_on_every_tick = true
is used in the strategy()
declaration statement, all alert() calls
will use the alert.freq_once_per_bar_close
frequency, regardless of the argument used for freq
.
While script alerts on strategies will use order fill events to trigger alerts when the broker emulator fills orders, alert() can be used advantageously to generate other alert events in strategies.
This strategy creates alert() function calls when RSI moves against the trade for three consecutive bars:
//@version=5
strategy("Strategy with selective `alert()` calls")
r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Place orders on crosses.
if xUp
strategy.entry("Long", strategy.long)
else if xDn
strategy.entry("Short", strategy.short)
// Trigger an alert when RSI diverges from our trade's direction.
divInLongTrade = strategy.position_size > 0 and ta.falling(r, 3)
divInShortTrade = strategy.position_size < 0 and ta.rising( r, 3)
if divInLongTrade
alert("WARNING: Falling RSI", alert.freq_once_per_bar_close)
if divInShortTrade
alert("WARNING: Rising RSI", alert.freq_once_per_bar_close)
plotchar(xUp, "Go Long", "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Go Short", "▼", location.top, color.red, size = size.tiny)
plotchar(divInLongTrade, "WARNING: Falling RSI", "•", location.top, color.red, size = size.tiny)
plotchar(divInShortTrade, "WARNING: Rising RSI", "•", location.bottom, color.lime, size = size.tiny)
hline(50)
plot(r)
If a user created a script alert from this strategy and included both order fill events and alert() function calls in his alert,
the alert would trigger whenever an order is executed,
or when one of the alert() calls
was executed by the script on the realtime bar’s closing iteration, i.e., when
barstate.isrealtime and
barstate.isconfirmed are both true.
The alert() function events in the script would only trigger the alert when the realtime bar closes because alert.freq_once_per_bar_close
is the argument used for the freq
parameter in the alert() calls.
When a script alert is created from an indicator, it can only trigger on alert() function calls. However, when a script alert is created from a strategy, the user can specify that order fill events also trigger the script alert. An order fill event is any event generated by the broker emulator which causes a simulated order to be executed. It is the equivalent of a trade order being filled by a broker/exchange. Orders are not necessarily executed when they are placed. In a strategy, the execution of orders can only be detected indirectly and after the fact, by analyzing changes in built-in variables such as strategy.opentrades or strategy.position_size. Script alerts configured on order fill events are thus useful in that they allow the triggering of alerts at the precise moment of an order’s execution, before a script’s logic can detect it.
Pine Script™ programmers can customize the alert message sent when specific orders are executed. While this is not a pre-requisite for order fill events to trigger,
custom alert messages can be useful because they allow custom syntax to be included with alerts in order to route actual orders to a third-party execution engine, for example.
Specifying custom alert messages for specific order fill events is done by means of the alert_message
parameter in functions which can generate orders:
strategy.close(),
strategy.entry(),
strategy.exit() and
strategy.order().
The argument used for the alert_message
parameter is a “series string”, so it can be constructed dynamically using any variable available to the script,
as long as it is converted to string format.
Let’s look at a strategy where we use the alert_message
parameter in both our
strategy.entry() calls:
//@version=5
strategy("Strategy using `alert_message`")
r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Place order on crosses using a custom alert message for each.
if xUp
strategy.entry("Long", strategy.long, stop = high, alert_message = "Stop-buy executed (stop was " + str.tostring(high) + ")")
else if xDn
strategy.entry("Short", strategy.short, stop = low, alert_message = "Stop-sell executed (stop was " + str.tostring(low) + ")")
plotchar(xUp, "Go Long", "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Go Short", "▼", location.top, color.red, size = size.tiny)
hline(50)
plot(r)
Note that:
stop
parameter in our strategy.entry() calls,
which creates stop-buy and stop-sell orders. This entails that buy orders will only execute once price is higher than the high on the bar where the order is placed,
and sell orders will only execute once price is lower than the low on the bar where the order is placed.id
argument for all buy orders, any new buy order placed before a previous order’s condition is met will replace that order.
The same applies to sell orders.alert_message
argument are evaluated when the order is executed, so when the alert triggers.When the alert_message
parameter is used in a strategy’s order-generating strategy.*()
function calls,
script users must include the {{strategy.order.alert_message}}
placeholder in the “Create Alert” dialog box’s “Message” field
when creating script alerts on order fill events. This is required so the alert_message
argument used in the order-generating strategy.*()
function calls
is used in the message of alerts triggering on each order fill event. When only using the {{strategy.order.alert_message}}
placeholder in the “Message” field and the
alert_message
parameter is present in only some of the order-generating strategy.*()
function calls in your strategy,
an empty string will replace the placeholder in the message of alerts triggered by any order-generating strategy.*()
function call not using the alert_message
parameter.
While other placeholders can be used in the “Create Alert” dialog box’s “Message” field by users creating alerts on order fill events,
they cannot be used in the argument of alert_message
.
The alertcondition() function allows programmers to create individual alertcondition events in Pine Script™ indicators. One indicator may contain more than one alertcondition() call. Each call to alertcondition() in a script will create a corresponding alert selectable in the “Condition” dropdown menu of the “Create Alert” dialog box.
While the presence of alertcondition() calls in a Pine Script™ strategy script will not cause a compilation error, alerts cannot be created from them.
The alertcondition() function has the following signature:
alertcondition(condition, title, message)
condition
true
or false
) which determines when the alert will trigger. It is a required argument.
When the value is true
the alert will trigger. When the value is false
the alert will not trigger.
Contrary to alert() function calls,
alertcondition() calls
must start at column zero of a line, so cannot be placed in conditional blocks.title
message
The alertcondition() function does not include a
freq
parameter. The frequency of alertcondition() alerts is determined by users in the “Create Alert” dialog box.
Here is an example of code creating alertcondition() events:
//@version=5
indicator("`alertcondition()` on single condition")
r = ta.rsi(close, 20)
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
plot(r, "RSI")
hline(50)
plotchar(xUp, "Long", "▲", location.bottom, color.lime, size = size.tiny)
plotchar(xDn, "Short", "▼", location.top, color.red, size = size.tiny)
alertcondition(xUp, "Long Alert", "Go long")
alertcondition(xDn, "Short Alert", "Go short ")
Because we have two alertcondition() calls in our script, two different alerts will be available in the “Create Alert” dialog box’s “Condition” field: “Long Alert” and “Short Alert”.
If we wanted to include the value of RSI when the cross occurs, we could not simply add its value to the message
string using str.tostring(r)
,
as we could in an alert() call or in an alert_message
argument in a strategy.
We can, however, include it using a placeholder. This shows two alternatives:
alertcondition(xUp, "Long Alert", "Go long. RSI is {{plot_0}}")
alertcondition(xDn, "Short Alert", 'Go short. RSI is {{plot("RSI")}}')
Note that:
{{plot_0}}
placeholder, where the plot number corresponds to the order of the plot in the script.{{plot("[plot_title]")}}
type of placeholder,
which must include the title
of the plot() call used in our script to plot RSI.
Double quotes are used to wrap the plot’s title inside the {{plot("RSI")}}
placeholder. This requires that we use single quotes to wrap the message
string.If we want to offer script users the possiblity of creating a single alert from an indicator using multiple alertcondition() calls, we will need to provide options in the script’s inputs through which users will indicate the conditions they want to trigger their alert before creating it.
This script demonstrates one way to do it:
//@version=5
indicator("`alertcondition()` on multiple conditions")
detectLongsInput = input.bool(true, "Detect Longs")
detectShortsInput = input.bool(true, "Detect Shorts")
r = ta.rsi(close, 20)
// Detect crosses.
xUp = ta.crossover( r, 50)
xDn = ta.crossunder(r, 50)
// Only generate entries when the trade's direction is allowed in inputs.
enterLong = detectLongsInput and xUp
enterShort = detectShortsInput and xDn
plot(r)
plotchar(enterLong, "Go Long", "▲", location.bottom, color.lime, size = size.tiny)
plotchar(enterShort, "Go Short", "▼", location.top, color.red, size = size.tiny)
hline(50)
// Trigger the alert when one of the conditions is met.
alertcondition(enterLong or enterShort, "Compound alert", "Entry")
Note how the alertcondition() call is allowed to trigger on one of two conditions. Each condition can only trigger the alert if the user enables it in the script’s inputs before creating the alert.
These placeholders can be used in the message
argument of alertcondition() calls.
They will be replaced with dynamic values when the alert triggers. They are the only way to include dynamic values (values that can vary bar to bar) in
alertcondition() messages.
Note that users creating alertcondition() alerts from the “Create Alert” dialog box in the charts UI are also able to use these placeholders in the dialog box’s “Message” field.
{{exchange}}
{{interval}}
{{open}}
, {{high}}
, {{low}}
, {{close}}
, {{volume}}
{{plot_0}}
, {{plot_1}}
, […], {{plot_19}}
alertcondition(volume > sma(volume,20), "Volume alert", "Volume ({{plot_0}}) > average ({{plot_1}})")
{{plot("[plot_title]")}}
This placeholder can be used when one needs to refer to a plot using the title
argument used in a
plot() call.
Note that double quotation marks ("
) must be used inside the placeholder to wrap the title
argument.
This requires that a single quotation mark ('
) be used to wrap the message
string:
//@version=5
indicator("")
r = ta.rsi(close, 14)
xUp = ta.crossover(r, 50)
plot(r, "RSI", display = display.none)
alertcondition(xUp, "xUp alert", message = 'RSI is bullish at: {{plot("RSI")}}')
{{ticker}}
{{time}}
yyyy-MM-ddTHH:mm:ssZ
, so for example: 2019-08-27T09:56:00Z
.{{timenow}}
{{time}}
. The precision is to the nearest second, regardless of the chart’s timeframe.The most common instances of repainting traders want to avoid with alerts are ones where they must prevent an alert from triggering at some point during the realtime bar when it would not have triggered at its close. This can happen when these conditions are met:
high
, low
or close
, for example, which includes almost all built-in indicators.
It will also be the case with the result of any request.security() call using
a higher timeframe than the chart’s, when the higher timeframe’s current bar has not closed yet.The simplest way to avoid this type of repainting is to configure the triggering frequency of alerts so they only trigger on the close of the realtime bar. There is no panacea; avoiding this type of repainting always entails waiting for confirmed information, which means the trader must sacrifice immediacy to achieve reliability.
Note that other types of repainting such as those documented in our Repainting section may not be preventable by simply triggering alerts on the close of realtime bars.