When configuring MultiCharts alerts, there’s also an option that specifies whether the script’s alerts should fire once per bar or possibly with every price update. While an alert once per bar does prevent many alerts quickly after each other, it also prevents periodic reminder alerts. So how do we programmatically generate MultiCharts alerts with a certain number of seconds between them?

In this article:

Only firing MultiCharts alerts every number of seconds

We generate MultiCharts alerts programmatically with Alert(), but we’ll need to enable the script’s manual alert setting before that keyword triggers alerts. Then, depending on the manual alert settings, alerts appear as notification windows, audio alerts, and/or email alerts (MultiCharts Wiki, 2013a).

The option that turns on the script’s alerts is the ‘Enable Alerts’ checkbox, and with the ‘Alert Conditions Check’ radio buttons we configure how often the alert may fire:

Enabling MultiCharts alerts by hand for indicators and trading strategies

With those options the indicator or signal either generates an alert once per bar (‘On Bar Close’ or ‘Once Per Bar’) or potentially with every price update (‘Every Tick’). So to prevent many alerts quickly after each other, we use that option to limit the alerts to once per bar.

But a once-per-bar alert may not happen often enough when we trade bars with a high time frame. It also prevents us from getting an occasional reminder alert in case we’re away from the computer when the first alert happened. Luckily, with a bit of PowerLanguage code we can generate alerts that have at least a certain number of seconds between them.

That has a couple of benefits. First and most obviously, an alert that occurs only so often prevents a flood of alerts happening quickly after each other. Second, it makes us independent from the time frame we’re trading. That is, since we don’t rely on a once-per-bar alert but instead use the time between the alerts, the alert frequency isn’t affected whether we trade a 1-minute or 60-minute bars.

Using PowerLanguage code to fire MultiCharts alerts periodically

We need to add a couple of things to the code of an indicator or signal before an alert fires at most every number of seconds. First we’ll need to store the time of when we generate an alert programmatically. By tracking that time, we can later on calculate how many seconds ago the last alert fired.

To successfully store that time in a variable, we need to mark that variable as IntrabarPersist. That keyword makes the variable remember each and every value assigned to it (MultiCharts Wiki, 2012b). While that’s how variables normally work, PowerLanguage variables by default only remember the value stored in them when the bar closes – and forget the values assigned to them during an intra-bar script calculation when we don’t use IntrabarPersist.

The second step is accessing the current time. We store that time in the variable that tracks when the last alert fired, but also use it to see how many seconds ago that previous alert fired. To access the current time we can use the ComputerDateTime keyword, which returns the computer’s time and date in DateTime format (MultiCharts Wiki, 2013b).

That DateTime format is a numerical value whose integer portion is the number of days since January 1, 1900, and whose fractional portion indicates the portion of the day that elapsed since midnight (MultiCharts Wiki, 2013b). That means DateTime values represent both a date and time of day. This also makes DateTime values suited for time calculations, and that allows us to accurately calculate the number of seconds between the current time and when the last alert fired.

Let’s examine a programming example to see how generating an alert every number of seconds looks like.

Example: generating MultiCharts alerts with a 30-second pause

In the indicator below we plot a 14-bar RSI (Relative Strength Index) alongside this oscillator’s overbought and oversold levels, which we set to 70 and 30 by default. Whenever the RSI is overbought or oversold, the script generates an alert. To prevent many alerts from quickly happening after each other, we only generate an alert when the previous alert was at least a certain number of seconds ago. We configure that amount of seconds with the Seconds_Between_Alerts input option.

The image below shows how the indicator generated two consecutive alerts with half a minute between them. After we discuss the programming example, we examine the indicator’s appearance and behaviour more closely.

Example alerts generated by the MultiCharts indicator

Inputs:
    Seconds_Between_Alerts(30),
    RSI_Length(14),
    Overbought_Level(70),
    Oversold_Level(30);
    
Variables:
    IntrabarPersist timeLastAlert(0),
    secondsSinceLastAlert(0),
    rsiValue(0);

// Compute and plot values
rsiValue = RSI(Close, RSI_Length);

Plot1(rsiValue, "RSI", DarkGray);
Plot2(Overbought_Level, "OB Level", DarkGreen);
Plot3(Oversold_Level, "OS Level", DarkGreen);

SetPlotWidth(1, 2);

// Calculate the seconds since the previous alert
secondsSinceLastAlert = (ComputerDateTime - timeLastAlert) /
    ELTimeToDateTime_s(1);
    
// Trigger alerts
if (secondsSinceLastAlert > Seconds_Between_Alerts) then begin

    if (rsiValue > Overbought_Level) then begin
        Alert("Overbought RSI @ " + NumToStr(rsiValue, 2));
        
        timeLastAlert = ComputerDateTime;
    end;

    if (rsiValue < Oversold_Level) then begin
        Alert("Oversold RSI @ " + NumToStr(rsiValue, 2));
        
        timeLastAlert = ComputerDateTime;
    end;

end;

We begin with creating a couple of input options and variables:


Inputs:
    Seconds_Between_Alerts(30),
    RSI_Length(14),
    Overbought_Level(70),
    Oversold_Level(30);
    
Variables:
    IntrabarPersist timeLastAlert(0),
    secondsSinceLastAlert(0),
    rsiValue(0);

With an input option we can easily change a value that’s used in the script manually, without having to edit and recompile the script’s code. We give the numerical input Seconds_Between_Alerts a default value of 30, and use this input later on when configuring how many seconds there need to be between consecutive alerts.

The other three input options (RSI_Length, Overbought_Level, and Oversold_Level) are going to set the length of the RSI and the overbought and oversold levels, and have defaults of 14, 70, and 30.

Then we create three variables. We’ll use the first, timeLastAlert, to track the time of when the last alert generated. Since we’re going to update that variable intra bar, we mark it as IntrabarPersist. That way it remembers each value that we store in it, regardless of when the script calculates (MultiCharts Wiki, 2012b).

The other two variables are secondsSinceLastAlert and rsiValue. We’re going to use the first to temporarily hold how many seconds ago the last alert happened, while the other will hold the RSI value during the current script calculation.

Next we calculate and then plot that RSI:


rsiValue = RSI(Close, RSI_Length);

Plot1(rsiValue, "RSI", DarkGray);
Plot2(Overbought_Level, "OB Level", DarkGreen);
Plot3(Oversold_Level, "OS Level", DarkGreen);

SetPlotWidth(1, 2);

We calculate the Relative Strength Index with the RSI() function, which requires two parameters: a series of values to process and a numerical value that sets the RSI length in number of bars. Here we set those parameters to the bar’s closing prices (Close) and the RSI_Length input option, which we gave a default of 14 earlier.

Then we display that oscillator value on the chart with Plot(). This keyword has several parameters, of which we use the first three: the plot’s value, name, and colour (MultiCharts Wiki, 2012c). Although the plot name isn’t relevant in our example, we need to provide this parameter if we want to set the plot’s colour programmatically.

We display the RSI values (rsiValue) with Plot1(), name this plot “RSI” and set it to the DarkGray default MultiCharts colour. The other two plot statements, Plot2() and Plot3(), display the overbought and oversold levels that we specified with the Overbought_Level and Oversold_Level input options. Both of those plots are coloured in DarkGreen.

Then we change the width of the RSI plot with SetPlotWidth(), a keyword that requires two parameters: the number of the plot to change and the new width, expressed with a value that ranges from 1 to 14 (MultiCharts Wiki, 2012d). We set the first argument to 1 (to change the first plot) and the second to 2, and that makes the plot one step bigger than the default size (which is 1).

The remaining part of the indicator’s code is tasked with generating an alert programmatically. But before doing that, we first have to calculate how many seconds ago the previous alert happened:


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

While this is a short statement, several things happen here. First we subtract the time of the previous alert (the timeLastAlert variable, which we update later on) from the computer’s time. We get that latter with the ComputerDateTime keyword, which returns the computer’s current time and date in DateTime format (MultiCharts Wiki, 2013b). That format is a number that contains both a time and date, and which can be used for time calculations.

Since we update timeLastAlert to a DateTime value later on, we’re subtracting here one DateTime value from another. That operation gives a DateTime value, but that doesn’t tell us how many seconds there are between the computer’s current DateTime and the DateTime of when the alert last fired. For instance, a time period of 13 hours and 41 minutes has a corresponding DateTime value of 0.5701456481. And so we need to standardise such a fractional DateTime value to a seconds amount.

We do that by dividing the difference in DateTime values with the DateTime value of 1 second. We get that latter with the ELTimeToDateTime_s() keyword, which converts a time in HHmmss format (like 9:10:23) to a DateTime value (MultiCharts Wiki, 2012e). A handy trick is that, when we pass a value of 1 inside the parentheses of this keyword, it then returns the DateTime value of 1 second (which is 0.0000115741, by the way).

Now when we divide the difference between ComputerDateTime and timeLastAlert with the DateTime value of 1 second, we end up with how many seconds there are between the current computer time and when the last alert triggered. That number of seconds is what we’re going to store in the secondsSinceLastAlert variable.

The value of that variable is then checked prior to generating an alert:


if (secondsSinceLastAlert > Seconds_Between_Alerts) then begin

    // ...

end;

This if statement evaluates whether the number of seconds that we’ve just computed (secondsSinceLastAlert) is greater than (>) the Seconds_Between_Alerts input option, which we gave a default value of 30 earlier. Because we generate alerts inside this if statement, the script only fires an alert when the previous alert happened more than 30 seconds ago.

The code to fire the alert consists out of two nested if statements:


if (rsiValue > Overbought_Level) then begin
    Alert("Overbought RSI @ " + NumToStr(rsiValue, 2));
    
    timeLastAlert = ComputerDateTime;
end;

if (rsiValue < Oversold_Level) then begin
    Alert("Oversold RSI @ " + NumToStr(rsiValue, 2));
    
    timeLastAlert = ComputerDateTime;
end;

Both if statements are very similar, so let’s focus on discussing the first. The condition of that if statement evaluates whether the 14-bar RSI (rsiValue) is greater than (>) the Overbought_Level input option, which we gave a default value of 70. When the oscillator is indeed above that level, the if statement’s code executes.

That code first generates an alert programmatically with Alert() (MultiCharts Wiki, 2012a). Inside that keyword’s parentheses we create an alert message that contains static text ("Overbought RSI @ ") with a dynamic number converted to text. For that latter we use NumToStr(), a keyword that requires two parameters: the numerical value to convert to a string and how many decimals that number should get (MultiCharts Wiki, 2012f). We use rsiValue and 2 as parameters, and that makes NumToStr() convert the 14-bar RSI value to a 2-decimal string. (See the images above and further below for how that value appears in the alert messages.)

Next we update the timeLastAlert variable with the computer’s current date and time (ComputerDateTime). This way timeLastAlert gets the current time each time we fire an alert with Alert(). During the next script calculations after generating this alert, we use the timeLastAlert variable to calculate how many seconds ago this alert happened. And that way our script keeps a certain number of seconds between consecutive alerts.

Example: MultiCharts alerts with a time pause between them

Let’s see how the above example indicator behaves. When we add the indicator to a chart, we do so with the following manual alert settings:

Configuring the alert settings of the MultiCharts indicator

Even though we set the ‘Alert Conditions Check’ option here to ‘Every Tick’, our script won’t generate alerts that often since we programmatically track the number of seconds between successive alerts.

Our script has the following input options:

Example input options of the MultiCharts indicator

The indicator itself plots as follows on the chart:

Example chart of the MultiCharts example RSI indicator

And the different alerts that it generates look like this:

Alerts generated by the MultiCharts indicator - 30 seconds apart

Here we can see that the alerts trigger with at least 30 seconds apart, which is the amount of time that we’ve configured with the ‘Seconds_Between_Alerts’ input option. That time gap happened even those alerts generated during a downtrend in EUR/CAD where the RSI remained in oversold territory with almost every price update.

Another chart that shows the example indicator is:

Example EUR/CAD chart of the MultiCharts indicator

Here the EUR/CAD is again oversold, and this time the indicator triggered the following alerts:

Oversold RSI alerts triggered by the MultiCharts example indicator

To learn more about other ways to prevent a lot of alert messages happening quickly after each other, see the different ways to limit the number of alerts per bar.

Summary

The Alert() keyword generates alerts programmatically, but before this keyword can actually trigger alerts we need to enable the script’s alert setting. Then, depending on the manual ‘Alert Conditions Check’ option, the indicator or signal can fire an alert each time Alert() is executed. One approach that prevents alerts from firing quickly after each other is tracking how many seconds happen between consecutive alerts. That makes alerts appear less often, but still allows for a periodic reminder in case we missed the first notification. This can be coded with the help of ComputerDateTime, a keyword that returns the computer’s current time and date in DateTime format. The numerical values of that format consist out of an integer portion (representing the number of days) and a fractional portion, which signals the time of day. When we store ComputerDateTime in a variable each time we generate an alert programmatically, then on next script calculations we can determine how many seconds ago the last alert fired. For this approach to work we need to mark that variable as IntrabarPersist when making it. That way the variable remembers any value that’s assigned to it during an intra-bar script calculation; otherwise, it only remembers the value stored in it during an on bar close calculation.

Learn more:


References

MultiCharts Wiki (2012a, February 7). Alert. Retrieved on March 7, 2016, from http://www.multicharts.com/trading-software/index.php/Alert

MultiCharts Wiki (2012b, August 11). IntraBarPersist. Retrieved on May 8, 2016, from https://www.multicharts.com/trading-software/index.php/IntraBarPersist

MultiCharts Wiki (2012c, February 19). Plot. Retrieved on May 12, 2016, from https://www.multicharts.com/trading-software/index.php/Plot

MultiCharts Wiki (2012d, February 19). SetPlotWidth. Retrieved on May 12, 2016, from http://www.multicharts.com/trading-software/index.php/SetPlotWidth

MultiCharts Wiki (2012e, February 13). ELTimeToDateTime_s. Retrieved on May 12, 2016, from https://www.multicharts.com/trading-software/index.php/ELTimeToDateTime_s

MultiCharts Wiki (2012f, February 13). NumToStr. Retrieved on May 12, 2016, from https://www.multicharts.com/trading-software/index.php/NumToStr

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

MultiCharts Wiki (2013b, June 5). ComputerDateTime. Retrieved on May 11, 2016, from https://www.multicharts.com/trading-software/index.php/ComputerDateTime