Before a strategy trades automatically, we’ll have to enable its automated trade execution. That means we’ll need to turn on that option on every chart before the trading session begins. But auto trading can also turn off automatically in several situations. So how do we create a notification when a strategy is off when it shouldn’t be?

In this article:

Generating alerts and checking if an ATS is enabled

We generate alerts programmatically with the Alert() keyword (PowerLanguage Keyword Reference, 2016) provided we’ve enabled the script’s alert setting. Alerts can then, depending on the manual alert options, appear as a notification window, audio alert, and/or email alert (MultiCharts Wiki, 2013).

Even though alerts typically fire based on prices (like a moving average crossover alert), risk management and notification alerts are just as useful. One example of that is generating an alert whenever the strategy’s automated trading execution is turned off. Especially when working with a lot of charts and multiple workspaces, it’s easy to overlook a chart on which automated trading is disabled.

On a single chart, we enable automated trading with the ‘Auto Trading Status’ button (also called ‘Automate Order Execution Switch’) that’s shown in the top left, and which either says ‘SA’ or ‘AA’ depending on whether we use synchronous or asynchronous auto trading (MultiCharts Wiki, 2014a).

Automated order switch disabled on the MultiCharts price chart

When this button is grey (like in the image above), automated trading is disabled. And it becomes green when automated trading is enabled for the chart’s strategy:

Automated trading enabled on the MultiCharts price chart

Without that automated trade execution switch turned on, the strategy cannot submit trades to the broker. And so to have our strategy submit trades, we need to enable automated trading before the session starts.

However, we’ll also need to monitor whether automated trading remains enabled. That’s because the following situations automatically turn off automated trading (MultiCharts Wiki, 2016):

  • Changing the symbol or chart on which the strategy calculates.
  • Turning one of the signals in the strategy on or off.
  • Adjusting the settings or inputs of one of the strategy’s signals.
  • Recompiling any of the strategy’s signals.
  • Removing or adding signals to the strategy.
  • Changing any setting in the ‘Strategy Properties’ window or one of its tabs (like the ‘Auto Trading’ tab).
  • When there’s a timeout in the connection between MultiCharts and the broker.
Note: Besides these situations, anything that affects the MultiCharts program (like turning off the computer, experiencing a computer crash, or accidentally closing the MultiCharts program) also turns off automated trading.

This shows that we can have automated trade execution enabled before the session starts, and only to later learn that auto trading became disabled due to some action (like recompiling a signal).

Unfortunately, it’s currently not possible to enable automated trading programmatically. What we can do is create a notification whenever automated trading isn’t enabled by the time the trading session starts. With that information we can then turn on automated trading before the session begins.

One way to create a notification is generating an alert programmatically. But for that we’ll need to know the status of the strategy’s automated trade execution. That’s something we retrieve with the GetAppInfo() keyword and aiStrategyAuto parameter, which makes that keyword return 1 when the signal has automated trade execution enabled and 0 when auto trading is off (PowerLanguage Keyword Reference, 2016).

We can make those alerts more helpful in two ways. First, by ensuring that there’s a certain number of seconds between successive alerts. That way there won’t be a flood of alert messages. The other improvement is to only generate alerts during a certain time period. That way we don’t get unnecessary alerts when the market is closed or when the strategy doesn’t trade at that time.

Let’s look at a programming example to see how we can generate those alerts when automated trading is turned off.

Example: generate MultiCharts alerts when auto trading is off

The example signal below generates an alert when the strategy’s automated trade execution isn’t enabled during a certain time period. Besides monitoring the status of automated trade execution and generating alerts programmatically, the signal doesn’t perform other tasks (like submitting trades). This way we can use the example script with any other signal that submits the actual strategy orders.

The image below shows how the alerts look like. After discussing the code we’ll take a closer look at the signal’s behaviour.

Example alert for when MultiCharts automated trading is not enabled

[IntrabarOrderGeneration = true];

Inputs:
    Recalculate_Seconds(10),
    Second_Between_Alerts(30),
    Start_Time(800),
    End_Time(1600);
    
Variables:
    IntrabarPersist timeLastAlert(0),
    inTimeRange(false),
    secondsSinceAlert(0),
    autoTradingOff(false);

if (CheckAlert) then begin

    // Check if the computer's time is in the specified range
    if (Start_Time < End_Time) then
        inTimeRange = (CurrentTime >= Start_Time) and (CurrentTime <= End_Time)
    else
        inTimeRange = (CurrentTime > Start_Time) or (CurrentTime < End_Time);

    // Calculate the seconds since the last alert
    secondsSinceAlert = (ComputerDateTime - timeLastAlert) / 
        ELTimeToDateTime_s(1);
    
    // Check if auto trading is off
    autoTradingOff = (GetAppInfo(aiStrategyAuto) <> 1);
    
    // Trigger the alert when all three situations happen
    if (inTimeRange = true) and (autoTradingOff = true) and
        (secondsSinceAlert > Second_Between_Alerts) then begin
        
        Alert("The automated trading strategy on the " +
            SymbolName + " (" + ExchListed + ") chart has NOT been enabled.");
        
        // Update the variable for the next alert
        timeLastAlert = ComputerDateTime;
        
    end;
    
    // Recalculate the script every number of seconds   
    RecalcLastBarAfter(Recalculate_Seconds);

end;

We begin with the IntrabarOrderGeneration attribute set to true. That makes the signal process every real-time tick instead of only calculating on once per bar, when the bar closes (MultiCharts Wiki, 2012a). With that, our signal generates an alert as soon as automated trading is off (instead of having to wait till the current bar closes).

Then we create several input options and variables:


Inputs:
    Recalculate_Seconds(10),
    Second_Between_Alerts(30),
    Start_Time(800),
    End_Time(1600);
    
Variables:
    IntrabarPersist timeLastAlert(0),
    inTimeRange(false),
    secondsSinceAlert(0),
    autoTradingOff(false);

With the Recalculate_Seconds input option we configure how often (in seconds) the signal at least needs to calculate. That will keep our script up to date, even when the market is slow or closed. We use the Seconds_Between_Alerts input option to configure how many seconds there are least need to be between consecutive alerts.

We’ll use the Start_Time and End_Time inputs to specify the time period between which the script should check whether automated trade execution is enabled. The default values of these inputs (800 and 1600) correspond to 8:00 and 16:00 o’clock.

We also create four variables. In the timeLastAlert variable we’ll store when the previous alert generated. By tracking that time we’re able to keep a certain number of seconds between consecutive alerts. We’ll use the inTimeRange true/false variable to determine whether the current time falls inside the time range set by the input options. The secondsSinceAlert variable is going to hold how many seconds ago the last alert happened, and with the autoTradingOff true/false variable we’ll track whether auto trading is off or not.

Before the timeLastAlert variable we place IntrabarPersist. With that keyword the variable keeps any value we store in it during an intra-bar script calculation. While it makes sense that a variable remembers its value, the default behaviour of PowerLanguage is to only update the value of variables when the bar closes (PowerLanguage Keyword Reference, 2016).

Since the signal also processes intra-bar price updates, we place IntrabarPersist before the variable so that it remembers its value from one intra-bar script calculation to the next. (Since we use the other variables only during the current script calculation, it doesn’t matter that they don’t remember their value from the previous script calculation.)

After making the inputs and variables, the signal’s actual code begins. All that code is inside the following if statement:


if (CheckAlert) then begin

    // ...

end;

We check whether the script’s alerts are enabled with CheckAlert here, a keyword that returns true when the script’s alert settings are enabled and the script calculates on the last bar of the data series (PowerLanguage Keyword Reference, 2016). When one or both of those situations aren’t the case, CheckAlert returns false.

With CheckAlert the code of our if statement only executes when the script can actually generate alerts, which is on the last bar of the data series (MultiCharts Wiki, 2012b) and when the ‘Enable Alerts’ option is enabled. And so when CheckAlert returns false, there’s no point in performing calculations for triggering an alert since they cannot fire then.

Inside that if statement, we first check whether the computer’s time falls inside the time range we specified with the Start_Time and End_Time input options:


if (Start_Time < End_Time) then
    inTimeRange = (CurrentTime >= Start_Time) and (CurrentTime <= End_Time)
else
    inTimeRange = (CurrentTime > Start_Time) or (CurrentTime < End_Time);

With this if/else statement we account for the two different ways that we can use the Start_Time and End_Time input options: to set a time range that remains on the same day (like 8:00 till 16:00) or one that crosses midnight (such as 22:00 till 10:00).

To check if the inputs set a same-day time range, we evaluate whether Start_Time is before (that is, less than; <) End_Time. When that’s the case, we set the inTimeRange variable to a true/false value based on two expressions that we combine with the and logical keyword. That keyword returns true when the value on its left and the value on its right are both true too; when one or both values are false, then and returns false too (PowerLanguage Keyword Reference, 2016).

The first expression is whether the computer’s current time (that we retrieve with the CurrentTime keyword; PowerLanguage Keyword Reference, 2016) is greater than or equal to (>=) the Start_Time input option. With the second true/false expression we check whether the computer’s time (CurrentTime) is less than or equal to (<=) the End_Time input option.

Combined, those two expressions are true when the current time is somewhere between 8:00 till 16:00 (the default values of the Start_Time and End_Time inputs). And this condition is false when the computer time is less than Start_Time or bigger than End_Time. We store the true/false result here in the inTimeRange variable for use later on in the script.

The else portion of our if/else statement deals with the situation where the Start_Time and End_Time inputs specify a session that crosses midnight (like 22:00 till 10:00). Because the time of day naturally ‘resets’ at midnight, we can see such a time range as having two parts: the late evening till midnight (22:00 till 0:00) and the morning (0:00 until 10:00).

To see if the current time falls inside one of those periods, we evaluate whether CurrentTime is greater than (>) Start_Time and check whether CurrentTime is less than (<) End_Time. Since the time only has to be in one of those parts to fall into the overnight session, we combine those true/false expressions with the or logical keyword. That keyword returns true when its left value, its right value, or both values are true. Only when both the value on its left and right are false, will or return false too (PowerLanguage Keyword Reference, 2016).

That means we set the inTimeRange true/false variable to true whenever the current time falls in the late evening or early morning of the overnight session, and give that variable a value of false when the time is before or after the time range set by Start_Time and End_Time. But regardless of whether those input options specify a same-day or overnight session, the inTimeRange variable holds true when the current time falls inside the time range and false otherwise.

To prevent many alerts quickly after each other, we then calculate how many seconds ago the previous alert happened:


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

Here we first get the difference between the computer’s current time (ComputerDateTime) and the timeLastAlert variable, which we update with the computer’s time whenever we generate an alert.

That ComputerDateTime keyword returns a value whose integer portion represents the number of days since January 1, 1900, while its decimal part is the portion of the day that elapsed since midnight (PowerLanguage Keyword Reference, 2016). With this so-called DateTime format we can perform calculations with time. That is helpful for our purposes, but such calculations return a DateTime value and not a number of seconds.

To convert that DateTime value to a seconds amount, we divide it by ELTimeToDateTime_s(1). That keyword returns the DateTime value of a time in HHmmss format (PowerLanguage Keyword Reference, 2016). Here we use it with a value of 1 to get the DateTime value of one second. That number of seconds since the last alert happened is then stored in the secondsSinceAlert variable for use later on.

Besides the time range and ‘seconds since last alert’ filters, the third and last alert condition is that the signal’s automated trade execution is turned off. We track that with the autoTradingOff variable:


autoTradingOff = (GetAppInfo(aiStrategyAuto) <> 1);

To get the auto trading status, we use GetAppInfo() with the aiStrategyAuto parameter. That makes the keyword return 1 when automated trade execution is enabled (PowerLanguage Keyword Reference, 2016).

To see if automated trading is off, we evaluate whether GetAppInfo(aiStrategyAuto) returns a value unequal to (<>) 1. When that happens, the autoTradingOff variable is set to true and we’ll generate an alert next. Otherwise, auto trading is still on and autoTradingOff is set to false.

With all three alert requirements programmed, it’s time to fire the actual alerts:


if (inTimeRange = true) and (autoTradingOff = true) and
    (secondsSinceAlert > Second_Between_Alerts) then begin
    
    Alert("The automated trading strategy on the " +
        SymbolName + " (" + ExchListed + ") chart has NOT been enabled.");
    
    timeLastAlert = ComputerDateTime;
    
end;

This if statement evaluates three true/false expressions combined with the and logical keyword. That means all expressions have to be true before the if statement’s condition is true (and the code inside the if statement executes) (PowerLanguage Keyword Reference, 2016).

The first expression checks if inTimeRange equals (=) true, which it is when the computer’s time is between the Start_Time and End_Time inputs. With the second expression we check if auto trading is off (autoTradingOff = true). And the third one evaluates if the number of seconds since the last alert (secondsSinceAlert) is bigger than (>) the Seconds_Between_Alerts input option (that we gave a default value of 30). When all three situations are the case, the if statement’s code executes.

That code first generates an alert with Alert(). Inside that keyword’s parentheses we specify an alert message that consists out of static strings and dynamic values. The dynamic information is the symbol’s name and exchange, which we retrieve with the SymbolName and ExchListed keywords (PowerLanguage Keyword Reference, 2016).

After firing an alert, we set timeLastAlert to the computer’s current time (ComputerDateTime). That way, on the next script calculation, we can use the timeLastAlert variable to see how long ago this alert happened (and that way we prevent alerts firing quickly after each other).

With the last part of the example we make sure that the script keeps updated when the market is slow or even closed:


RecalcLastBarAfter(Recalculate_Seconds);

Here we use the RecalcLastBarAfter() keyword to recalculate the script periodically. We set that time period to the Recalculate_Seconds input option, which has a default value of 10. That way our signal calculates at least once every 10 seconds, regardless of how active the instrument is (MultiCharts Wiki, 2014). This keeps the signal up to date and allows for timely alerts.

Example: firing alerts when auto trading is disabled

Now let’s see how the example signal behaves on the chart. When we add it to the chart, we use the following alert settings:

Configuring the alert settings of the MultiCharts strategy

(See enabling MultiCharts alerts and configuring MultiCharts alerts manually for more on configuring this window.)

Besides the alert options, we can configure our signal with the following input options:

Input options of the MultiCharts example signal

Since our signal only generates alerts, we’ll need to add other signals to the chart for the actual trading. When we also add two inside bar strategies (‘Inside Bar LE’ and ‘Inside Bar SE’), the chart looks like:

MultiCharts chart with the example signal added

Here the ‘SA’ button is still grey, signalling that automated trade execution is currently disabled. When we keep the Start_Time and End_Time inputs at their defaults of 800 and 1600, then just after 8:00 o’clock the script triggers an alert saying automated trading is off:

MultiCharts alerts triggered when automated trading is disabled when trading begins

When we use the signal’s inputs to specify that trading should happen between 22:00 and 10:00, then the script generates alerts like the following when auto trading is off during that overnight session:

MultiCharts signalling that auto-trading is off during the overnight session

With its default settings, the signal generates alerts 30 seconds apart. That makes consecutive alerts appear like this:

Alerts generated with 30 seconds apart in MultiCharts

For more examples that combine signals with alerts, see generating an alert when the strategy’s position changes and firing alerts when the broker position doesn’t match the chart. Besides generating an alert when automated trading isn’t enabled when the session starts, we can also monitor the strategy and its market position to generate an alert when automated trading becomes turned off.

Summary

The Alert() keyword generates alerts, provided the script’s alert setting are enabled. One way to use those alerts is to trigger a notification whenever the strategy’s automated trade execution is accidentally turned off. With that information we can then quickly (re-)enable the strategy’s auto trading, perhaps even before the session begins. To generate those alerts, we need to programmatically retrieve whether the strategy’s automated trade execution is enabled or not. For that we use the GetAppInfo() keyword with the aiStrategyAuto parameter, which makes that keyword return 1 whenever auto trading is on. Should GetAppInfo(aiStrategyAuto) signal that automated trading is off, we generate an alert. We can improve those alerts by only generating them during the strategy’s trading hours and, when they do fire, keeping a minimum number of seconds between consecutive alerts.

Learn more:


References

MultiCharts Wiki (2012a, August 31). IntraBarOrderGeneration. Retrieved on August 1, 2016, from http://www.multicharts.com/trading-software/index.php/IntraBarOrderGeneration

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

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

MultiCharts Wiki (2014a, November 4). Getting Started with AutoTrading. Retrieved on July 29, 2016, from http://www.multicharts.com/trading-software/index.php/Getting_Started_with_AutoTrading

MultiCharts Wiki (2014b, September 3). RecalcLastBarAfter. Retrieved on August 2, 2016, from http://www.multicharts.com/trading-software/index.php/RecalcLastBarAfter

MultiCharts Wiki (2016, June 14). Auto Trading. Retrieved on July 29, 2016, from http://www.multicharts.com/trading-software/index.php/Auto_Trading

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