Alerts
How do I make an alert available from my script?
In indicator scripts, there are two ways to define triggers for alerts:
- Using the alertcondition() function
- Using the alert() function
In strategy scripts, there are also two ways to define alert triggers:
- Using the alert() function
- Using order fill events
These methods make alert triggers available but do not create alerts directly. Users must create alerts using a script’s alert triggers by selecting the appropriate trigger in the “Condition” dropdown of the “Create Alert” dialog box.
Programmers can define multiple alert triggers of one or more types in a script.
How are the types of alerts different?
Usability
Any script can include calls to the alertcondition() and alert() functions within their code. However, alertcondition() calls have no effect unless the script is an indicator. Libraries can export functions containing alert() calls, but they cannot issue alert triggers directly.
Order fill alert triggers are available only from strategies.
Options for creating alerts
Each alertcondition() call in an indicator script defines one distinct trigger and one corresponding option in the “Condition” dropdown menu of the “Create Alert” dialog box. If the user wants multiple alerts, they must create each one separately.
By contrast, if a script includes one or more alert() function calls, only one option appears in the “Condition” dropdown menu, titled “Any alert() function call”. Selecting this option creates a single alert that activates based on the occurrences of any executed alert() call.
Similarly, for strategy scripts, the “Order fills and and alert() function calls” or “Order fills only” option in the “Condition” dropdown menu creates an alert that fires when any order fill event occurs.
How alerts activate
The alertcondition() function operates exclusively in an indicator’s global scope. Scripts cannot include calls to this function within any local block, such as the indented code within an if structure. The function triggers an alert when its specified condition
is true
. Users can set the allowed frequency of the alert trigger using the “Frequency” field in the “Create Alert” dialog box.
The alert() function has no condition
parameter. Scripts trigger the alerts on any alert() call based on each call’s freq
argument. Therefore, programmers typically include such calls within the local scopes of conditional structures to control when they execute.
Order fill alert triggers are available from strategies automatically without requiring extra code. However, programmers can customize the default alert messages. These alerts fire on order fill events, which occur when the broker emulator fills a strategy’s orders.
Messages
The message
parameter of the alertcondition() function populates the “Message” field of the “Create Alert” dialog box with a default message, which script users can customize to suit their alert needs. It accepts a “const string” argument, meaning its value cannot change after compilation. However, the argument can include placeholders to make the message’s information dynamic.
The message
parameter of the alert() function accepts a “series string” argument, allowing programmers to create dynamic messages that can include “string” representations of a script’s calculated values. Unlike alertcondition(), this function does not populate a “Message” field in the “Create Alert” dialog box, and it does not process placeholders. Programmers can allow users to customize alert() messages by creating inputs in the script’s settings.
Order fill alerts have a default message that describes a strategy’s order fill event. This default message contains strategy-specific placeholders, which the alert replaces with current strategy information each time it fires. Programmers can override the default message using the //@strategy_alert_message
compiler annotation, which allows text and strategy placeholders, but not script variables. Script users can edit the default message from the “Message” field in the “Create Alert” dialog.
The alert_message
parameter in a strategy’s order placement commands allows programmers to define distinct messages for each order fill event. The parameter accepts “series string” values that can change on each event. To use the values from this parameter in a strategy’s order fill alerts, include the {{strategy.order.alert_message}}
placeholder in the //@strategy_alert_message
annotation, or include it in the “Message” field when creating an alert.
Limitations
The alertcondition() function has some limitations:
- Each active alert condition counts toward the total number of alerts the user’s plan allows.
- Every alertcondition() call contributes to the script’s plot count.
- Only indicators can issue alert triggers with this function. Other script types do not raise a compilation error when they include calls to this function in their code, but each call has no effect.
By contrast, all calls to the alert() function count as one alert, regardless of the number of calls in the code. In addition, alert() calls do not contribute to a script’s plot count.
Similarly, if a user creates a strategy alert based on order fill events, it counts as one alert, even though it can fire multiple times with distinct messages from different order executions.
Example `alertcondition()` alert
The script below demonstrates a simple alertcondition() call that triggers alerts when the current bar’s close is above the value from the previous chart bar. It also uses a plotshape() call to indicate each bar where the triggerCondition
occurred:
See this section of the Alerts page to learn more.
Example `alert()` alert
This example uses the vstop()
function from our ta library to calculate a volatility stop value and trend information based on the Average True Range (ATR). The stopValue
trails behind the chart’s close to form a trend-following system.
The script triggers an alert with an alert() call each time the trend direction changes. The alert’s message is a “series string” that shows the trend’s new direction and the current stop value. An additional alert occurs whenever the stopValue
moves in the current trend direction, with a message containing the updated value:
See this section of the Alerts page for more information.
Example strategy alert
This example strategy places a market order with strategy.entry() and a stop-loss and take-profit (bracket) order with strategy.exit() when a 5-bar moving average crosses over a 10-bar moving average. The stop-loss price is 1% below the current close and the take-profit price is 2% above the close. Order fill alerts occur when the broker emulator fills an entry or exit order. Both order placement commands include unique alert_message
arguments that combine placeholders and “string” representations of the limit
and stop
values to output details like the trade action, position size, chart symbol, and order prices:
For more information about order fill events, see this section of the Alerts page. To learn more about how strategy scripts work, see the Strategies page.
If I change my script, does my alert change?
No, not without creating a new alert.
When a user creates an alert using the “Create Alert” dialog box, that action saves a “snapshot” of the script, its inputs, and the current chart’s context on TradingView’s servers. This snapshot acts as an independent copy of the script instance and chart. Therefore, any changes to the script, its inputs, or the user’s chart do not affect that created alert. To update an alert after making changes, delete the existing alert and create a new one.
Why aren’t my alerts working?
Here are some common reasons why alerts might not work as expected, and how to solve them:
Make sure the alert is active and has not expired
Check the alert logs
Check for repainting
Limit the frequency of alerts
Debug script errors
- Attempting to store more than 100,000 elements within a collection
- Trying to access an item from a collection at an out-of-bounds index
- Referencing historical values of a time series outside its allocated memory buffer
- Using loops that take longer than 500 ms to complete their iterations
Why is my alert firing at the wrong time?
Sometimes, alerts may fire when users do not expect according to what their script displays on the chart. Repainting is the typical cause of such issues.
A chart’s realtime and historical bars often rely on different data feeds. Data providers may retroactively adjust the reported values on realtime bars, which the displayed data reflects after users refresh their charts or restart their scripts. Such adjustments can cause discrepancies where a triggered alert’s timing may not align with the script’s output after reloading it.
Scripts may also behave differently on historical and realtime bars, which can lead to repainting. On historical bars, scripts execute once per bar close, whereas on realtime bars, where alerts fire, scripts execute once for each new tick from the data feed. Therefore, if a script behaves differently on those bars, users may see differences between its signals and triggered alerts after reloading the chart.
Below are some common repainting issues that can affect a script’s alerts:
Alerts firing before bar close
Using `calc_on_every_tick` in strategies
calc_on_every_tick = true
in its declaration statement or the user selects the “On every tick” option in the “Recalculate” section of the strategy’s properties, it recalculates on every price update in the realtime data. This behavior can cause strategies to repaint because historical bars do not contain the same information as realtime bars. See this section of the Strategies page to learn more.
Incorrect usage of `request.security()` calls
Can I use variable messages with alertcondition()?
The message
parameter of the alertcondition() function requires a “const string” argument, which cannot change after compilation. However, the “string” can include placeholders, which an alert substitutes with corresponding dynamic values from a script each time it fires.
The script below demonstrates two alertcondition() calls whose message
arguments include placeholders for dynamic values. Each time alerts from these triggers occur, the message displays information about the current chart’s exchange, symbol, price, and volume:
How can I include values that change in my alerts?
The method for including dynamic values in alert messages varies with the type of alert trigger:
- The alertcondition() function accepts a “const string”
message
argument that can contain placeholders for dynamic values. See Can I use variable messages with `alertcondition()`? for more information. - The alert() function accepts “series string”
message
arguments, which allows the convenient creation of dynamic messages that use a script’s calculated values. See this section for an example. - Order fill alerts can use “series string” values and placeholders. Refer to the example here.
How can I get custom alerts on many symbols?
To manage alerts across multiple symbols using a custom script, one option is to set an individual alert on each symbol. There is no automated method to set the same alert across many symbols simultaneously in a single action. It’s also important to note that the TradingView screener uses built-in filters and does not support custom Pine Script™ code.
Scripts can retrieve data from other contexts (symbols, timeframes, and modifiers such as non-standard chart calculations and extended sessions) using the functions in the request.*()
namespace. With these functions, programmers can design scripts that retrieve data from up to 40 unique contexts. Search for “screener” in the Community scripts for in-depth examples.
Here is an example incorporating three symbols. The checkForAlert()
function calls request.security() to fetch data from a specified context and evaluate the user-defined checkForRsiConditions()
function using that data. Then, the function calls alert() using the result to create an alert trigger. The script calls this function three times, creating distinct alert triggers for each specified symbol:
Note that:
- A script can execute up to 40 unique
request.*()
calls. Arequest.*()
call is not unique if a script already calls the same function with the same arguments. See this section of the Limitations page for more information. - This script uses the alert() function because alertcondition() is not allowed within local scopes.
How can I trigger an alert for only the first instance of a condition?
Firing an alert only on its first occurrence can help avoid redundant notifications and isolate specific conditions or state changes, which is beneficial in several use cases. For instance, if a user relies on alerts to automate order placement, restricting redundant alerts to their first occurrence can help avoid accidentally placing excessive orders.
For alerts with alertcondition() triggers, setting them to fire once using the “Only Once” option in the “Create Alert” dialog box is not an optimal solution because it requires manual reactivation each time an alert occurs. Alerts from the alert() function do not have an “Only Once” frequency option. The programmer must use conditional logic to ensure the call executes at the appropriate time.
There are two primary ways to code repeating alerts that fire on only the first instance of a condition:
Using more strict criteria
close > ma
, which may remain true
for multiple consecutive bars, try using a more strict condition like ta.crossover(close, ma). For simple cases, this is the easiest method.
Using state control
The example script below manages separate bullish and bearish states, and it colors the background to represent each state. When a bullish or bearish state first occurs, an alert() call executes and the script plots a triangle on the chart. It also plots smaller triangles to show where other signals occur within a state, which do not trigger additional alerts:
//
How can I run my alert on a timer or delay?
It is possible to program logic to delay alert triggers so that they occur after the initial condition. However, because Pine scripts execute on realtime bars only after new price updates, and an alert only fires when a script executes, it is difficult to predict the exact time of a delayed alert.
There are no price updates in a closed market, meaning an alert with a delay will not fire until the market opens again. Similarly, thinly traded securities may have very infrequent price updates in unpredictable intervals, which can cause a larger delay than intended.
The Pine script below implements a time-delayed alert, which is subject to the limitations above. When the current close is higher than a moving average, a delay counter starts. After the delay passes, the alert fires once, and another alert cannot fire until the timer resets. Users can specify whether the timer resets on each bar using the script’s resetInput
:
Note that:
- The
secondsSince()
function from the PineCoders’ time library determines the duration, in seconds, for which a certain condition remains continuouslytrue
. The duration can be tracked within bars because it uses the varip keyword. - The timing starts when the condition first becomes
true
. If the condition becomesfalse
or an optional resetting condition occurs, the timer restarts. If “Reset timing on new bar” is enabled in the “Settings/Inputs” tab, the function restarts its timing at the start of a new bar. - A colored label shows what state the script is in:
- Red - The condition has not occurred yet.
- Orange - The condition occurred and the delay timer is active.
- Green - The timer has surpassed the set duration, simulating a delayed alert.
This script relies on variables declared with the varip keyword, which do not revert to their last committed states during realtime bar calculations. See this section of the User Manual to learn more about using this keyword. To learn about how rollback works, see the Execution model page.
How can I create JSON messages in my alerts?
Alerts can send messages containing JavaScript Object Notation (JSON) to webhooks. Pine Script™ does not include any built-in functions to produce JSON, but programmers can create JSON messages in Pine by constructing “string” representations.
When constructing JSON representations, ensure the keys and values intended as strings in the JSON-formatted text use double quotes, not single quotes.
The following example shows three ways to construct JSON strings in Pine Script™:
-
Static JSON Strings
Define separate alerts with predefined JSON-formatted strings. This method is the simplest.
-
Placeholders
Use placeholders in the alert message, such as
{{close}}
and{{volume}}
, to add dynamic values to the JSON. The alert instance replaces the placeholders with corresponding values when it fires. This method can create richer alerts, especially for strategies, which have extra placeholders for their calculated values. See this section above for an example. -
Dynamic strings
Use the functions in the
str.*()
namespace and “string” concatenation to create dynamic JSON-formatted text. This method is the most customizable and advanced. Our script below shows a simple, straightforward example of this approach. When using dynamic string formatting to construct JSON strings, ensure the resulting JSON is valid for all the combined values.
Before using the JSON-formatted string in alerts for real-world applications, such as sending messages to place orders, test and validate the JSON message to ensure it works as intended:
- Send alerts to an email address to see how the JSON message appears.
- Copy the alert message from the email into an online JSON validation tool.
- Use an API client application to check the server response to the request.
Refer to this Wikipedia page to learn more about JSON format. To learn more about how alerts send information using webhooks, see the Help Center article on webhooks.
How can I send alerts to Discord?
Sending alerts from a Pine script to a Discord chat room is possible using webhooks.
The message for Discord communication requires JSON format. The minimum requirement for a valid message is {"content": "Your message here"}
.
The script example below uses placeholders to dynamically populate alert messages with script values, including the new high or low price, and the chart’s symbol and timeframe:
To send these alert messages to Discord, follow these steps:
1. Create a Discord webhook
- Create a new webhook in a server using an account with webhook creation and management permissions. Refer to Discord’s Intro to Webhooks article for instructions.
- Copy the Webhook URL. This URL represents the address where the alert sends a POST request.
2. Set up an alert on TradingView
- Add the above “Discord demo” script to a chart and open the “Create Alert” dialog box.
- Choose one of the script’s alert conditions as the “Condition” in the dialog. If you select the “New High” or “New Low” alerts, choose the “Once Per Bar Close” option in the “Frequency” field to avoid triggering alerts for new highs or lows on an unconfirmed bar. When using the “Test” alert, choose “Only Once” as the “Frequency” option.
- In the “Notifications” tab of the “Create Alert” dialog, select “Webhook URL” and paste the URL of the Discord webhook.
3. Test the integration
- Check that alerts appear in the alert log on TradingView.
- Use the “Test” alert to check whether the webhook works as expected. After the alert fires, check your Discord to see if it received the message.
- If the alert message does not appear in Discord, check whether the pasted webhook URL is correct.
- If the message does not display correctly in Discord, check the JSON format. The minimum required format is
{"content": "Your message here"}
.
Consult Discord’s Webhook Resource to learn about advanced JSON message configurations.
For more information about dynamic values in alert messages, refer to How can I include values that change in my alerts?.
To learn about using JSON format in script alerts, see How can I create JSON messages in my alerts?.
How can I send alerts to Telegram?
Sending TradingView alerts directly to Telegram is challenging due to protocol differences and formatting requirements. One solution is to use an intermediary service, which receives webhook alerts from TradingView, formats them as required by Telegram, and then forwards them to a Telegram bot.
- Choose a platform like Zapier, Integromat, or Pipedream. Alternatively, programmers can consider developing a custom server script using Node.js or Python.
- In TradingView, set up alerts to send webhook requests to the intermediary service’s provided URL.
- Configure the intermediary service to reformat TradingView’s incoming requests for Telegram’s API and send the formatted message to a Telegram bot using the
sendMessage
method.
See the Telegram Bot API documentation for detailed technical information.