Whenever we want to generate alerts programmatically, we have to enable the script’s alert setting by hand (and disable that option when the script shouldn’t fire alerts). That’s a bit tiring over time. So how do we process mouse clicks in our code so that a single click is enough to enable or disable alerts?

In this article:

Using alerts together with mouse clicks in MultiCharts

We generate MultiCharts alerts programmatically with the Alert() keyword (PowerLanguage Keyword Reference, 2016). Depending on our manual alert settings, those alerts can appear as a notification window, audio alert, and/or email alert (MultiCharts Wiki, 2013). However, alerts only fire when we’ve enable the script’s alert option.

That latter is something we shouldn’t forget when we expect the script to generate alerts, but it also something that’s cumbersome: opening the script’s settings, changing the alert settings, confirming the changed settings. The script then processes all price bars again, from the first to the current real-time bar. Then we need to change those manual settings for each and every other chart on which the indicator or signal runs.

Luckily, a convenient and faster way to toggle a script’s alerts is with mouse clicks. That is, we can programmatically process mouse clicks so that a click on the chart enables alerts (when they were disabled) or disables alerts (if they were enabled to begin with). Unfortunately, we cannot actually change the ‘Enable Alerts’ checkbox option programmatically. But we can simulate that behaviour by creating a true/false variable that specifies when alerts should fire and when not, and then set the state of this variable with mouse clicks.

Doing that has a couple of requirements. First, we have to add the ProcessMouseEvents attribute to the script’s code. Only when we’ve set that attribute to true can the script process mouse clicks that happen on the chart (PowerLanguage Keyword Reference, 2016). Several keywords then provide information about a (possible) click, like MouseClickCtrlPressed and MouseClickShiftPressed, which tell us whether the Control and Shift keyboard keys where held when the click happened (PowerLanguage Keyword Reference, 2016).

That approach allow us to enable or disable alerts with a single mouse click. But it sadly won’t work in the Portfolio Trader or in the Watchlist/Scanner. That’s because MultiCharts scripts currently cannot register mouse clicks in those environments.

Example: using a mouse click to turn a script’s alerts on or off

In the example below we create a true/false variable to specify whether alerts should fire or not. Whenever a left or right click on the chart happens while the Control keyboard key is held down, we switch the value of that variable. Since we check the variable’s value before generating an alert, in effect alerts are toggled on or off when a click happens.

To keep track of the current alert status, we draw a text box on the chart that shows whether alerts are currently enabled or not. That also gives feedback about whether the script registered the mouse click. The image below gives an example of the indicator’s alerts. After examining the code, we’ll look at the indicator’s behaviour and text box.

Example of the alerts generated by the MultiCharts indicator

[ProcessMouseEvents = true];

Variables:
    IntrabarPersist alertsEnabled(true),
    textBoxID(0);

// Create the text box once 
once begin
    textBoxID = Text_New_DT(0, 0, "");
    Text_SetBGColor(textBoxID, black);
    Text_SetStyle(textBoxID, 1, 1);
    Text_SetSize(textBoxID, 10);  
end;

// Determine whether the alerts should be enabled or disabled
if (MouseClickCtrlPressed) then
    alertsEnabled = not alertsEnabled;
    
// Generate an alert with consecutive higher highs or lower lows
if (alertsEnabled) then begin

    if (High > High[1]) and (High[1] > High[2]) and (High[2] > High[3]) then
        Alert("Three higher highs in a row.")
        
    else if (Low < Low[1]) and (Low[1] < Low[2]) and (Low[2] < Low[3]) then
        Alert("Three lower lows in a row.");

end;

// Update the text box's content
if (alertsEnabled) then begin
    Text_SetString(textBoxID, " Alerts enabled ");
    Text_SetColor(textBoxID, green);
end
else begin
    Text_SetString(textBoxID, " Alerts disabled ");
    Text_SetColor(textBoxID, red);
end;

// Update the text box location
Text_SetLocation_DT(textBoxID,
    GetAppInfo(aiRightDispDateTime),
    GetAppInfo(aiLowestDispValue));

We begin with the ProcessMouseEvents attribute to enable mouse click processing by our script. Then we create two variables:


Variables:
    IntrabarPersist alertsEnabled(true),
    textBoxID(0);

The alertsEnabled variable is our true/false variable that tracks whether the script should generate alerts (when true) or not (false). We give it an initial value of true and place the IntrabarPersist keyword before it. With that keyword, the variable retains its value from one intra-bar script calculation to the next (MultiCharts Wiki, 2012a).

That overrides the default behaviour of PowerLanguage, which is that variables only remember the value stored in them when the bar closes. Since we update our variable each time a new click occurred (and not just when the bar closes), we need to mark it as IntrabarPersist.

The other variable is the textBoxID numerical variable. This one will hold the text box’s numerical identifier. We’ll need to use that value whenever we want to reference the text box (to change its appearance or location, for instance). (Since we’re not going to update that variable from one intra-bar script calculation to the next, we don’t mark it as IntrabarPersist.)

We make and format the text box next:


once begin
    textBoxID = Text_New_DT(0, 0, "");
    Text_SetBGColor(textBoxID, black);
    Text_SetStyle(textBoxID, 1, 1);
    Text_SetSize(textBoxID, 10);  
end;

To only make the text box once, we begin this code with once. That way all code between begin and end only executes once. With that we don’t end up with multiple text boxes on the chart.

Inside the code block, we begin with Text_New_DT(). This keyword creates a text box on the chart and returns a drawing-specific ID number that’s needed to change the text box after making it (PowerLanguage Keyword Reference, 2016). Text_New_DT() has three parameters: the box’s time coordinate (in DateTime format), the price value, and the text to display in the text box.

Here we set the parameters to 0, 0, and an empty string (""). Those values won’t place the text box at a visible location. So why a price and date time of 0? Because here we only create the text box and its appearance; later on in the code we’ll move the drawing to its correct location. This ‘trick’ of reusing the same text box is much more efficient (in terms of CPU and memory usage) than repeatedly creating a text box.

We store the value that’s returned by Text_New_DT() here in the textBoxID variable. Later we’ll use this variable when updating the text box’s location, but first we use it to change the appearance of the text box.

With the Text_SetBGColor() keyword we set the box’s background colour to black, while Text_SetStyle() adjusts the horizontal and vertical alignment of the text box. With parameter values of 1 and 1 the text box anchors to the left of its time coordinate and above its price location (PowerLanguage Keyword Reference, 2016). We set the font size of the text box to 10 points with Text_SetSize().

Next we toggle the state of the alertsEnabled variable:


if (MouseClickCtrlPressed) then
    alertsEnabled = not alertsEnabled;

This if statement evaluates the MouseClickCtrlPressed keyword, which returns true when the Control keyboard key is pressed during a mouse click on the chart (PowerLanguage Keyword Reference, 2016).

When that happens, we switch the value of the alertsEnabled true/false variable. We do that by updating the variable’s value to not alertsEnabled. The not logical keyword returns the logical opposite of the expression it’s placed for (MultiCharts Wiki, 2012b). That is, with not placed before something that’s true, it returns false. And preceding something that’s false with not results in true.

So whenever the alertsEnabled variable currently holds true, then its new value becomes false (since that’s returned by not alertsEnabled and then stored in the variable). Likewise, when the script shouldn’t generate alerts (so alertsEnabled is false), then a click with Control enables the alerts (since not alertsEnabled returns true then).

Then we generate the indicator’s alerts, depending on the value of alertsEnabled:


if (alertsEnabled) then begin

    if (High > High[1]) and (High[1] > High[2]) and (High[2] > High[3]) then
        Alert("Three higher highs in a row.")
        
    else if (Low < Low[1]) and (Low[1] < Low[2]) and (Low[2] < Low[3]) then
        Alert("Three lower lows in a row.");

end;

Inside this if statement that evaluates if alerts are allowed (that is, whether alertsEnabled returns true), there’s an if/else statement. Both the if and else if part use a condition where the and logical keyword combines several expressions. That keyword returns true whenever the value on its left and the one on its right are both true; when one or both values are false, then and returns false too (MultiCharts Wiki, 2012c).

And so that means for the first if statement, three things have to happen before an alert generates. First the high of the current bar (High) has to be greater than (>) the previous bar’s high (High[1]). The previous bar (High[1] > High[2]) and the bar before that (High[2] > High[3]) also have to achieve a higher high. When there are indeed three higher highs in a row, we generate an alert message that says so with Alert().

Likewise, the second nested if statement checks for three lower lows in a row. We evaluate that by seeing if the current bar’s low is less than the previous bar’s low (Low < Low[1]), and require that the low of 1 and 2 bars ago is also lower (Low[1] < Low[2] and Low[2] < Low[3]). With three consecutive lower lows, we generate an alert message with Alert(). (The image above and further down below shows how the alerts look like.)

Next we change the content and appearance of the text box, depending on whether we’ve enabled or disabled alerts with a mouse click:


if (alertsEnabled) then begin
    Text_SetString(textBoxID, " Alerts enabled ");
    Text_SetColor(textBoxID, green);
end
else begin
    Text_SetString(textBoxID, " Alerts disabled ");
    Text_SetColor(textBoxID, red);
end;

This if/else statement evaluates alertEnabled. When that true/false variable is true, the part of the code that’s below if executes. That code first updates the text displayed inside the text box with Text_SetString(). That keyword requires two parameters (PowerLanguage Keyword Reference, 2016): the text box identifier (which we stored in the textBoxID variable earlier) and the new message, that’s set to “Alerts enabled” here. Then we use Text_SetColor() to change the text box’s font colour to green (PowerLanguage Keyword Reference, 2016). Since we’ve already set the box’s background to black, those green letters can be read clearly.

The else portion of the if/else statement executes when alerts aren’t enabled (meaning, alertEnabled is false). Those two lines of code use Text_SetString() and Text_SetColor() to set the text box’s content to “Alerts disabled” in red letters. By formatting the text box like this, we can quickly see if the script is allowed to generate alerts or not.

After placing text inside the text box, the last thing to do is update its location:


Text_SetLocation_DT(textBoxID,
    GetAppInfo(aiRightDispDateTime),
    GetAppInfo(aiLowestDispValue));

This code, which moves the text box, executes each time the script calculates. That makes the text box always relocate to the chart’s lower right bottom. Without this code, the text box would move out of view when new bars form or we scroll the chart to historical bars.

We update the text box location with the Text_SetLocation_DT() keyword, which requires three parameters: the text box ID as well as the DateTime and price value to move the text box to (PowerLanguage Keyword Reference, 2016). For the first parameter we use the textBoxID variable we updated earlier.

We set the second parameter to GetAppInfo() with the aiRightDispDateTime parameter, which returns the DateTime of the rightmost bar displayed in the current chart window (PowerLanguage Keyword Reference, 2016). A DateTime value is a numerical value that consists out of an integer and decimal value. Its integer portion are the number of days since January 1, 1900, while the fractional part represents how much of the current day elapsed since midnight (PowerLanguage Keyword Reference, 2016). Combined, that makes a DateTime value represent both a date and time of day.

The third parameter of Text_SetLocation_DT() is set to GetAppInfo() with the aiLowestDispValue parameter. That makes the keyword return the lowest price scale value that’s shown in the current chart window (PowerLanguage Keyword Reference, 2016). By combining that value with the date and time of the chart’s right bar, we get the chart coordinates of the lower right corner. And using those values with Text_SetLocation_DT() keeps our text box in the chart’s lower right.

Enabling and disabling MultiCharts alerts with mouse clicks

Let’s see how the example indicator behaves on the chart. To make generating alerts possible, we use the script with the following alert settings:

Configuring the alert settings of the MultiCharts example indicator

When we add the indicator to the chart, its alerts are initially enabled with the alertsEnabled variable. We can see a confirmation of that in the following text box:

Example chart showing the script's alerts enabled

Now when there are three higher highs or lower lows in a row, the script generates alerts like the following:

Example alerts generated by the MultiCharts indicator

But as soon as we click on the chart while holding down the Control key, the value of the alertsEnabled variable switches and the script can’t generate alerts anymore. Instead, the following message appears in the text box:

Example chart when the script's alerts are toggled off

This shows how we can easily enable or disable whether a script generates alerts without having to navigate to the ‘Enable Alerts’ option. Additionally, with the text box we can quickly see whether alerts are currently possible or not.

Summary

We generate MultiCharts alerts programmatically with Alert(), but that keyword can only fire alerts when we enable the script’s alerts setting. When we temporarily don’t want to generate alerts, we need to manually disable that ‘Enable Alerts’ option and then to re-enable it later. Luckily, a quicker way to enable or disable alerts is by programmatically processing mouse clicks that happen on the chart. One keyword we can use for that is MouseClickCtrlPressed, which returns true when a click with the Control key held down happens on the chart. When such a click occurs, we toggle the value of a true/false variable. Then by checking the value of that variable before generating an alert, we can effectively ‘enable’ or ‘disable’ alerts based on a mouse click with Control. We’ll need to mark that variable as IntrabarPersist, however. That way it remembers any value we store in it during an intra-bar script calculation. While it makes sense for variables to remember their value, by default PowerLanguage variables only remember the value we stored in them when the bar closes.

Learn more:


References

MultiCharts Wiki (2012a, August 11). IntraBarPersist. Retrieved on July 7, 2016, from http://www.multicharts.com/trading-software/index.php/IntraBarPersist

MultiCharts Wiki (2012b, February 19). Not. Retrieved on July 8, 2016, from http://www.multicharts.com/trading-software/index.php/Not

MultiCharts Wiki (2012c, February 19). And. Retrieved on July 8, 2016, from http://www.multicharts.com/trading-software/index.php/And

MultiCharts Wiki (2013, May 10). Using Alerts. Retrieved on June 11, 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