When we generate MultiCharts alerts programmatically, we occasionally generate a lot of alerts quickly after each other. What are some of the approaches that prevent a script from firing many alerts in a short period of time?

In this article:

Generating too many MultiCharts alerts quickly after each other

We generate MultiCharts alerts with the Alert() keyword (PowerLanguage Keyword Reference, 2016) as long as we’ve manually enabled the script’s alert setting. Depending on the manual alert configuration, alerts can fire as a notification window, audio alert, and/or email alert (MultiCharts Wiki, 2013).

The Alert() keyword triggers an alert each time the script executes this keyword. While beneficial for generating multiple alerts per bar, it also leads to situations in which we simply get too many alerts. For instance, our email inbox can fill with alerts just minutes apart from each other:

Example of a flood of email alert messages generated by MultiCharts

Similarly, a script can also generate so many alerts that it’s not practical anymore:

Example of a flood of alert pop-ups in MultiCharts

With all programmatically-generated alerts tracked in the ‘Alerts’ tab of the Order and Position Tracker, that log of alerts also fills with noise:

Alert messages overflooding the MultiCharts Order and Position Tracker window

As these three examples show, too many alerts may be as useful as having no alerts at all. That makes it a good programming practice to limit how many alerts a script can generate. There are several benefits to doing so.

Most obviously: limiting the number of alerts prevents too many alerts firing quickly after each other. A related benefit is that, with more restrictive alert conditions, when an alert does fire, it almost immediately captures our attention. Furthermore, being more thoughtful about exactly when an alert should fire often makes a script better structured and clearer. This latter can even make a script run more efficient. For instance, when we only generate alerts on bar close, then any calculation related to the alert also only has to happen once per bar, when the bar closes.

And so limiting the number of alerts that our script generates has clear advantages. But in which ways can we do that?

Manually limiting the number of MultiCharts alerts per bar

The first and easiest way to prevent many alerts quickly after each other is to change the manual alert settings so that the script only generates on alert per bar.

To configure that when our script is added to a chart, we first right-click on the script’s name in the chart’s Status Line and then select ‘Format [script name]…’:

Formatting an indicator in MultiCharts

This opens the ‘Format Study’ window and there we select the ‘Alerts’ tab. We then enable the script’s alert settings with the ‘Enable Alerts’ checkbox, and we can configure how often the alert may fire with the ‘Alert Conditions Check’ option:

Configuring the alert settings in MultiCharts

(See enabling a script’s alerts in MultiCharts for how to find that ‘Alerts’ tab in the Scanner/Watchlist, Portfolio Trader, and when a signal is added to a chart.)

As the above image shows, there are two options that limit the number of alerts per bar (MultiCharts Wiki, 2013):

  • With the On Bar Close option our script only generates an alert when the alert condition happens at the close of the price bar.
  • And the Once Per Bar option allows the script to generate an alert with every tick (so immediately when the alert condition happens), but only one time each price bar.

While these settings limit the number of alerts per bar, they also give less flexibility: we either generate one alert per bar (‘On Bar Close’, ‘Once Per Bar’) or possibly an alert with every real-time price update (‘Every Tick’).

Another disadvantage is that we can only fire one alert per bar, even though we might use the Alert() keyword more than once in the same script. So when our script can generate three different alerts, when the first alert fires the others cannot trigger anymore (and that makes it a ‘race’ to determine which alert may fire). These manual alert settings also depend on the chart’s resolution: with a once-per-bar alert, a 5-minute chart may generate 12 alerts per hour while there’s a maximum of 1 alert with hourly charts.

Luckily, with code we can limit alerts and have a lot more flexibility. Now before we discuss the different ways for doing that, let’s first make an example indicator that generates several alerts quickly after each other. Then we’ll rewrite that script in different ways to limit the number of alerts.

Example indicator: several MultiCharts alerts quickly after each other

The example script below generates alerts whenever the bar’s high is the 20-bar highest high or when the bar’s low is the lowest low of the recent 20 bars. Other than this, the indicator doesn’t perform other actions. This keeps the code to a minimum, which in turn makes the examples later on easier to follow.

Because a real-time price bar can have several price updates during a breakout that all make a new high or low, our example indicator can fire several alerts after each other. We’ll look at that behaviour in a moment. First let’s examine the code:


Inputs:
    Lookback_Period(20);
    
if (High = Highest(High, Lookback_Period)) then begin
    
    Alert("This bar's high (" + NumToStr(High, 1) + 
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar high.");
        
end;

if (Low = Lowest(Low, Lookback_Period)) then begin

    Alert("The low of this bar (" + NumToStr(Low, 1) +
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar low.");

end;

We first make the Lookback_Period input option and give it a default value of 20. We use this input later on as the number of bars to retrieve the highest high and lowest low from.

The indicator’s remaining code consists out of two if statements. The first generates the highest high alerts:


if (High = Highest(High, Lookback_Period)) then begin
    
    Alert("This bar's high (" + NumToStr(High, 1) + 
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar high.");
        
end;

The condition of this if statement checks whether the bar’s high (High) equals (=) the 20-bar highest high. We retrieve that latter with the Highest() function, which requires two parameters: a series of values to process and the number of bars to calculate on. Here we have Highest() calculate on High prices with a length of Lookback_Period bars, which is the input option that we set to 20 earlier.

When the bar’s high is indeed the highest high, the Alert() statement executes to generate an alert. Inside that keyword’s parentheses we specify an alert message that contains fixed strings (like "This bar's high (") and dynamic numerical values. Those values are the bar’s high (High) and highest high period (Lookback_Period), and we convert these values to a string with 1 and 0 decimals by using NumToStr() (PowerLanguage Keyword Reference, 2016). We combine the different text pieces together with the + operator.

When this highest high alert message triggers, it looks like:

Example MultiCharts alert when reaching a highest high

The second if statement of the example indicator is much like the first:


if (Low = Lowest(Low, Lookback_Period)) then begin

    Alert("The low of this bar (" + NumToStr(Low, 1) +
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar low.");

end;

Here we check with the if statement whether the bar’s low (Low) equals (=) the 20-bar lowest low. We get that latter value with Lowest(), a function that requires two parameters: the values to process and the number of bars to calculate on. Here we use it with the bar low prices (Low) and a length of 20 bars (the value of the Lookback_Period input).

When the bar’s low is the 20-bar lowest low, we generate an alert with Alert(). In the parentheses of that keyword we generate a text message just like we did with the highest high alert. Those 20-bar lowest low alerts appear like:

Example MultiCharts alert of reaching a new lowest low

After coding this example indicator, we compile it and add it to the chart. Then we can configure the ‘Lookback_Period’ setting in the script’s inputs:

Configuring the settings of the MultiCharts script with the input options

To have the indicator generate multiple alerts per bar, we enable the script’s alerts and configure the alert setting to ‘Every Tick’. That way the script can generate an alert with each possible price update:

Configuring a MultiCharts script to generate an alert with every tick

Besides generating alerts more than once per bar, for our purposes the indicator also needs to calculate during intra-bar price updates. Otherwise it cannot fire alerts based on the latest real-time price update. And so we have to enable the indicator’s ‘Update on every tick’ option. That setting is located in the ‘Properties’ tab of the same window where we configure the inputs and alert settings:

Configuring a MultiCharts indicator to calculate with every tick

Note that we use the same settings for all examples below. That is, we keep the ‘Alert Conditions Check’ option set to ‘Every Tick’ and have the script process every price update (‘Update on every tick’).

We can do that because the examples place their own limit on the number of alerts, and so an ‘Every Tick’ alert won’t fire with every price update. Furthermore, some approaches (like generating an alert every number of seconds) only work properly when the script updates on every tick.

Overview: different ways to limit MultiCharts alerts

Now let’s see what approaches limit the number of alerts an indicator or signal generates. We discuss each of the following further down below, based on the code of the original indicator that we looked at above:

Use the links above to quickly jump to the programming example you’re interested in.

Approach 1: Generating an alert at most once per bar

The original example indicator generates multiple alerts per bar. Now to only have it fire once per bar, we change its code to the following:


Inputs:
    Lookback_Period(20);

Variables:
    IntrabarPersist alertGenerated(false);

if (alertGenerated = false) then begin
    
    // Generate the highest high alert
    if (High = Highest(High, Lookback_Period)) then begin
        
        Alert("This bar's high (" + NumToStr(High, 1) + 
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar high.");
            
        alertGenerated = true;
            
    end;

    // Generate the lowest low alert
    if (Low = Lowest(Low, Lookback_Period)) then begin

        Alert("The low of this bar (" + NumToStr(Low, 1) +
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar low.");
            
        alertGenerated = true;

    end;

end;

// Reset variable on bar close
if (BarStatus = 2) then
    alertGenerated = false;

A couple of differences make the once-per-bar alert possible. The first change is adding a true/false variable to the script:


Variables:
    IntrabarPersist alertGenerated(false);

We use the alertGenerated variable later on to check if the script has already generated an alert. The variable has a default value of false. And after we generate an alert we set its value to true. That way we’ll know whether there’s already an alert generated on the current bar.

But to have alertGenerated keep any value we assign to it, we mark it as IntrabarPersist. That keyword ensures that the variable remembers any value we store in it (PowerLanguage Keyword Reference, 2016). This is opposed to the default PowerLanguage behaviour, which is to only remember the value of a variable when the bar closes. Since our indicator processes intra-bar price updates and checks the value of alertGenerated each time, we need to have this variable remember its value from one intra-bar script calculation to the next.

Another difference compared to the original indicator is that now we generate alerts inside the following if statement:


if (alertGenerated = false) then begin
    
    // ..

end;

This if statement requires that the alertGenerated variable equals (=) false. Based on how we’re going to use that variable later on, the if statement’s code only executes when there hasn’t been an alert generated on this bar yet. Since we place the code for generating alerts inside this if statement, those alerts only fire once per bar.

For that to work we set the alertGenerated variable to true immediately after generating an alert:


if (High = Highest(High, Lookback_Period)) then begin
    
    Alert("This bar's high (" + NumToStr(High, 1) + 
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar high.");
        
    alertGenerated = true;
        
end;

Here we still trigger an alert with the same conditions as in the original script. But now, immediately after generating an alert with Alert(), we set the alertGenerated variable to true. That invalidates the top-most if statement (which requires that variable to be false), and so on the next script calculation the code inside that if statement won’t execute. That means the two nested if statement which evaluate the alert conditions also won’t execute.

To generate one alert per bar (and not one alert in total), we have to reset the alertGenerated variable. That way the script can fire an alert again on the next bar. We do that in the last part of the example’s code:


if (BarStatus = 2) then
    alertGenerated = false;

This if statement checks whether the value returned by BarStatus equals (=) 2. That keyword returns a numerical value that indicates the status of the most recent price update from the data series that the script calculates on (PowerLanguage Keyword Reference, 2016).

Of the different values that BarStatus can return, a 2 signals that the script processes the bar’s closing tick. Now in that case, we switch the alertGenerated variable back to false again. With that value, the script can generate an alert on the next bar. When it does, alertGenerated becomes true again and the script has to wait till the next bar before generating another alert.

See programmatically triggering an alert once per bar for more on this approach and its benefits.

Approach 2: Only generating an alert when the bar closes

Another approach that limits the alerts of the original indicator is to only generate an alert on bar close. This is especially useful when the alert requires several calculations. That’s because when an alert may only fire when the bar closes, those calculations also only have to be done once per bar (instead of with every price update). And with that the script becomes a bit more efficient.

For alerts that only fire when the bar closes, we change the indicator’s code to:


Inputs:
    Lookback_Period(20);

// Only generate alerts on bar close
if (BarStatus = 2) then begin
    
    if (High = Highest(High, Lookback_Period)) then begin
        
        Alert("This bar's high (" + NumToStr(High, 1) + 
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar high.");
            
    end;

    if (Low = Lowest(Low, Lookback_Period)) then begin

        Alert("The low of this bar (" + NumToStr(Low, 1) +
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar low.");

    end;

end;

This programming example is nearly identical to the original version. The only change is that alerts are now generated inside the following if statement:


if (BarStatus = 2) then begin
    
    // ..

end;

The BarStatus keyword returns a numerical value, which indicates the status of the most recent price update of the data series that the script calculates on (PowerLanguage Keyword Reference, 2016). When a script calculates to process a bar’s closing tick, then BarStatus returns 2. And when that happens, the code inside this if statement executes.

Because alerts generate inside that if statement, they can only fire once per bar, when the bar closes. Another benefit is that the Highest() and Lowest() functions now only run once per bar, instead of calculating with every real-time price update.

For more on this approach, see firing alerts only on bar close. We can also combine an alert that may fire with every price update with one that is only allowed to fire when the bar closes. We discuss that in combining an intra-bar alert with an on-bar-close alert.

Approach 3: Generating a maximum number of alerts per bar

The previous two approaches both generated one alert per bar. While that reduces the alert amount, it’s also less flexible and on high time frames it can create a lot of time between alerts. An alternative is to limit the number of alerts per bar. That does increase the frequency of alerts a bit, but still prevents too many alerts from firing.

Let’s say we want to limit the original example indicator to 3 alerts per bar. One way to implement that is to adjust its code to:


Inputs:
    Lookback_Period(20);
    
Variables:
    IntrabarPersist alertsCount(0);

// Only generate alerts when there are 3 or less generated already
if (alertsCount < 3) then begin

    if (High = Highest(High, Lookback_Period)) then begin
        
        Alert("This bar's high (" + NumToStr(High, 1) + 
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar high.");
            
        alertsCount = alertsCount + 1;
            
    end;

    if (Low = Lowest(Low, Lookback_Period)) then begin

        Alert("The low of this bar (" + NumToStr(Low, 1) +
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar low.");
            
        alertsCount = alertsCount + 1;

    end;

end;

// Reset the alert count on bar close
if (BarStatus = 2) then
    alertsCount = 0;

There are several differences compared to the original version. First, we added a variable:


Variables:
    IntrabarPersist alertsCount(0);

We use this alertsCount numerical variable to track how many alerts generate on the current bar. With that we can check whether the script already reached its maximum number of alerts before generating another alert.

The alertsCount variable is marked as IntrabarPersist. When that keyword is placed before a variable, the variable also remembers values stored in it during intra-bar script calculations (PowerLanguage Keyword Reference, 2016) – instead of the default behaviour of PowerLanguage variables to only remember values stored in them when the bar closes.

Since we’re going to update alertsCount whenever the script generates an alert (which more often than not happens during an intra-bar script calculation), we need to mark it as IntrabarPersist to have it correctly count the number of triggered alerts.

Another difference is that the two if statements (which determine whether a highest high or lowest low alert should fire) are now placed inside the following if statement:


if (alertsCount < 3) then begin

    // ..

end;

This if statement’s condition checks whether the alertsCount variable is less than (<) 3. Because we generate alerts with code inside this if statement, those alerts only fire when the maximum number of alerts per bar hasn’t been reached yet. (Because alertsCount starts counting at zero, we require it here to be less than 3 instead of 4.)

Besides limiting the alerts, this approach also makes the script a bit more efficient. That’s because the highest high and lowest low values now only need to compute at most 3 times per bar, instead of with every price update.

To accurately track how many alerts fired, we increase alertsCount with 1 each time we trigger an alert. We do that like this:


if (High = Highest(High, Lookback_Period)) then begin
    
    Alert("This bar's high (" + NumToStr(High, 1) + 
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar high.");
        
    alertsCount = alertsCount + 1;
        
end;

This if statement and the code inside it is much like the original script version. The one difference is that now, after generating an alert with Alert(), we increase the alertsCount variable with 1. Now by checking the value of alertsCount on the next script calculation, we can see whether we’ve already reached the maximum number of alerts for this bar or not.

To count the alerts per bar (and not the alerts generated in total), we reset alertsCount each time the bar closes:


if (BarStatus = 2) then
    alertsCount = 0;

The BarStatus keyword returns a value that’s equal to (=) 2 when the recent price update of the data series that the script calculates on is the closing tick (PowerLanguage Keyword Reference, 2016). Should the indicator indeed calculate on that last tick, we reset alertsCount to 0. That way the variable starts counting anew on the next bar, which makes it possible for that bar to also generate up to 3 alerts.

For more limiting alerts with this approach, see triggering alerts at most a certain number of times per bar.

Approach 4: Generating an alert at most every number of seconds

The three previous approaches all relied on the price bar to limit the number of alerts. While practical, this also makes the amount of alerts depend on the chart’s resolution. For instance, on a 30-minute chart with an alert that fires once per bar, we get at most 2 alerts per hour. But with 1-minute bars, we can have up to 60 alerts in the same hour.

Luckily, we can also limit alerts by taking into account the number of seconds between alerts. To programmatically implement that, we change the original example script to the following to generate alerts at least 45 seconds apart:


Inputs:
    Lookback_Period(20);
    
Variables:
    timeSinceLastAlert(0),
    IntrabarPersist timeLastAlert(0);

// To calculate the time interval, we subtract the current computer
// time from the stored time, and translate that difference to seconds
timeSinceLastAlert = (ComputerDateTime - timeLastAlert) /
    ELTimeToDateTime_s(1);
    
// Only generate a new alert when more than 45 seconds have passed
if (timeSinceLastAlert > 45) then begin   
    
    if (High = Highest(High, Lookback_Period)) then begin
        
        Alert("This bar's high (" + NumToStr(High, 1) + 
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar high.");
            
        timeLastAlert = ComputerDateTime;
            
    end;

    if (Low = Lowest(Low, Lookback_Period)) then begin

        Alert("The low of this bar (" + NumToStr(Low, 1) +
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar low.");
            
        timeLastAlert = ComputerDateTime;

    end;

end;

We’ve made several changes to the original example indicator, starting with creating two variables:


Variables:
    timeSinceLastAlert(0),
    IntrabarPersist timeLastAlert(0);

We’ll use the timeSinceLastAlert numerical variable to calculate how many seconds passed since the last alert. In the timeLastAlert variable we’ll store the computer time of when that last alert happened.

Because that latter variable should keep its value from one intra-bar script calculation to the next, we place the IntrabarPersist keyword before it (PowerLanguage Keyword Reference, 2016). That keyword overrides the default PowerLanguage behaviour, which is that variables only remember the values stored in them when the bar closes.

Another change to the original script is figuring out how many seconds passed since the previous alert:


timeSinceLastAlert = (ComputerDateTime - timeLastAlert) /
    ELTimeToDateTime_s(1);

To calculate that number of seconds, we first subtract the timeLastAlert variable from ComputerDateTime. Later on in the script, we’ll update timeLastAlert with the current computer time of when we generate an alert programmatically with Alert().

That ComputerDateTime keyword returns a numerical value with the computer’s current date and time in the so-called DateTime format (PowerLanguage Keyword Reference, 2016). The integer portion of a DateTime value represents the number of days since January 1, 1900, while the decimal fraction represents the portion of the day since midnight (PowerLanguage Keyword Reference, 2016). Combined, a DateTime value contains both a date and time of day. With DateTime using this kind of numerical scale, we can perform calculations with them.

But when we subtract two DateTime values from each other (ComputerDateTime - timeLastAlert), we get a DateTime value without knowing how many seconds this represents. We fix that by dividing that DateTime difference with the DateTime value of 1 second. That latter is something we get with the ELTimeToDateTime_s() keyword, which has one parameter: a time specified in HHmmss 24-hour format. The keyword then returns the DateTime value that belongs to that time (PowerLanguage Keyword Reference, 2016).

If we use a parameter of 1 with ELTimeToDateTime_s(), it returns the DateTime value of 1 second. Now when we divide the time difference between the computer and last alert time with one second, we get the number of seconds elapsed since the last alert. That number of seconds is what we store in the timeSinceLastAlert variable.

Now to only generate an alert at most every number of seconds, we place the two if statement that evaluate the highest high and lowest low alert conditions inside the following if statement:


if (timeSinceLastAlert > 45) then begin   
    
    // ..

end;

Here we check whether the timeSinceLastAlert variable holds a value greater than (>) 45. When it does, more than 45 seconds passed since the last alert. The code that’s inside this if statement then runs. That also means that the highest high and lowest low calculate at most once every 45 seconds, as opposed to with every price update.

To calculate how much time passed since the last alert, we have to store the computer time when generating an alert programmatically. We do that like so:


if (High = Highest(High, Lookback_Period)) then begin
    
    Alert("This bar's high (" + NumToStr(High, 1) + 
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar high.");
        
    timeLastAlert = ComputerDateTime;
        
end;

We generate an alert here just like in the original script, but now also set the timeLastAlert variable to the computer’s current time and date (ComputerDateTime). With that we can see on the next script calculations how long ago the alert happened.

Because we don’t reset the timeLastAlert variable when the bar closes (or at any other point in the script), the number of seconds that passed since the previous alert is the only thing that can make another alert appear. That makes the frequency of the script’s alerts independent from the chart’s resolution.

For more on this method of limiting alerts, see keeping a certain number of seconds between successive alerts.

Approach 5: Generate an alert every number of alert conditions

The last approach we discuss in this article only generates an alert every number of times the alert condition happens. The reasoning behind limiting alerts in this way is the following. When an alert condition is true for the first time, we want it to fire immediately. But after that, we don’t need to notified each time the same alert condition happens again. But an occasional reminder that confirms the initial alert is helpful, however.

This approach is independent from the actual time between alerts. Instead, we simply look at how often the alert condition happens and base how many alerts actually fire on that. To implement this, we change the original example indicator to:


Inputs:
    Lookback_Period(20);
    
Variables:
    IntrabarPersist alertConditions(-1);

if (High = Highest(High, Lookback_Period)) then begin

    // Increment the number of alert conditions that have been triggered
    alertConditions = alertConditions + 1;
    
    // Generate an alert when the number of triggered alerts is an
    // even multiple of 5
    if (mod(alertConditions, 5) = 0) then
        Alert("This bar's high (" + NumToStr(High, 1) + 
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar high.");
        
end;

if (Low = Lowest(Low, Lookback_Period)) then begin

    alertConditions = alertConditions + 1;
    
    if (mod(alertConditions, 5) = 0) then
        Alert("The low of this bar (" + NumToStr(Low, 1) +
            ") reached a new " + NumToStr(Lookback_Period, 0) +
            "-bar low.");

end;

// Reset the variable on bar close
if (BarStatus = 2) then
    alertConditions = -1;

The first difference compared to the original version is adding a variable:


Variables:
    IntrabarPersist alertConditions(-1);

We use the alertConditions numerical variable to track how often an alert conditions happens. Since we increase this variable with 1 before checking its value to see if we can generate an alert, we give the variable an initial value of -1. That way it has a value of 0 prior to the first alert.

We also mark the alertConditions variable as IntrabarPersist. That makes the variable remember its value from one intra-bar script calculation to the next (PowerLanguage Keyword Reference, 2016). Without IntrabarPersist, alertsConditions would only keeps the value stored in it when the bar closes.

Another difference compared with the original script is tracking how often the alert condition happens. We do that in both the if statement that checks for the highest high and the one that looks for the lowest low. For instance:


if (High = Highest(High, Lookback_Period)) then begin

    alertConditions = alertConditions + 1;
    
    // ..
        
end;

Immediately after checking if the bar’s high is the highest high, we increase the alertConditions variable with 1. Now let’s say we want to generate an alert every 5 times that the alert condition happens. To implement that, we check whether the value of alertConditions is an even multiple of 5 before generating an alert, like this:


if (mod(alertConditions, 5) = 0) then
    Alert("This bar's high (" + NumToStr(High, 1) + 
        ") reached a new " + NumToStr(Lookback_Period, 0) +
        "-bar high.");

This if statement evaluates whether the value returned by mod() with the alertConditions and 5 parameters equals (=) 0. The mod() keyword returns the remainder of dividing the first parameter with the second (PowerLanguage Keyword Reference, 2016). In our case, that remainder is 0 when alertConditions divides evenly into 5. That happens whenever that variable is an even multiple of 5 (so 0, 5, 10, 15, 20, and so on). In all those cases, we generate an alert with Alert().

If we use alertConditions to track how often the alert condition happens per bar, then we’ll have to reset the variable when the bar closes. That way on the next bar the variable starts counting anew. We can do that like this:


if (BarStatus = 2) then
    alertConditions = -1;

This if statement evaluates whether BarStatus returns a value equal to (=) 2. That keyword returns that value when the recent price update of the data series that the script calculates on is the bar’s closing price (PowerLanguage Keyword Reference, 2016). When that’s the case, we set alertConditions back to -1. That way with the first alert condition on the next bar, alertConditions is increased with 1 to become 0, and that value makes it possible to generate that bar’s first alert with the mod() if statement.

We take a closer look at this approach for limiting alerts in generating a MultiCharts alert every number of alert conditions.

Summary

The Alert() keyword programmatically generates MultiCharts alerts, provided we’ve enabled the script’s alert option by hand. How often those alerts can fire depends on the ‘Alert Conditions Check’ option. To prevent many alerts quickly after each other, we can set that option to ‘Once Per Bar’ or ‘On Bar Close’. While that generates an alert at most once per bar, it comes at the loss of flexibility. For instance, that manual option applies to any alert generated by the script – meaning we can’t have one alert fire on bar close while another possibly with every price update. Luckily, we can limit alerts programmatically in several ways. One approach is to have alerts only fire once during the bar or when the bar closes. That greatly brings down the number of alerts generated. It also means we don’t have to configure every instance of the script manually, and can have the script run more efficient by only performing the calculations related to the alert when they’re needed. Other ways to limit the number of alerts are placing a maximum on the number of alerts per bar, firing an alert at most every number of seconds, and generating an alert every number of times the alert condition happens. With these latter two approaches we can also create helpful reminder alerts that confirm the initial alert condition.

Learn more:


References

MultiCharts Wiki (2013, May 10). Using Alerts. Retrieved on March 7, 2016, from https://www.multicharts.com/trading-software/index.php/Using_Alerts

PowerLanguage Keyword Reference (2016). Retrieved on May 25, 2016, from http://www.multicharts.com/trading-software/images/c/c6/PowerLanguage_Keyword_Reference.pdf