Generating MultiCharts alerts based on a manually-chosen price level is a bit cumbersome. Sure, we can place a manual drawing at that price level and then have that drawing generate alerts. But that requires a lot of manual actions for each drawing, and still gives us an alert with little actionable information. So how we can generate a semi-automatic alert that fires at a discretionary price level and that displays a custom alert message?

In this article:

Creating custom price-based MultiCharts alerts with mouse clicks

We generate MultiCharts alerts with the Alert() keyword (PowerLanguage Keyword Reference, 2016), although for this we’ll need to enable the script’s alert option. Then, depending on our manual alert settings, the alert can appear as a notification window, audio alert, and/or email alert (MultiCharts Wiki, 2013).

To trigger alerts based on discretionary prices, there are several options for configuring that custom price value. One approach would be to add an input option to a script, and then generate an alert based on that input’s value. This method is a bit slow, however, because changing an input option requires several manual steps. And once we change an input, the indicator or signal recalculates itself on all price bars. That can have unintended consequences, like disabling automated trading, writing identical information to a file, or moving and deleting drawings.

Another approach is to process mouse clicks that happen on the chart, and use the price coordinate of those clicks as the alert’s price level. For this we only need to click once on the chart (so no need to perform several actions by hand) and this doesn’t make the script process all historical price bars again. To make this approach work, we first need to enable the script’s mouse click processing. That’s done by adding the ProcessMouseEvents attribute to the code and setting it to true (MultiCharts Wiki, 2012a).

Once the script can process mouse clicks, we need to get the price coordinate of the click’s location. That value is returned by the MouseClickPrice keyword (PowerLanguage Keyword Reference, 2016). By tracking that value, we can generate an alert programmatically each time the bar crosses that price.

We can make that approach more useful by drawing a horizontal trend line at the mouse click location. That way we can see which price the script uses to generate alerts with. It also gives feedback about whether that price value was successfully updated after we click on the chart again.

Let’s look at the below example for to programmatically implement all of this.

Example: generating semi-automatic MultiCharts alerts

The example indicator below generates alerts based on where we click on the chart while holding down the Control key. For visual confirmation, the script draws a horizontal trend line at that price coordinate. We configure that line’s formatting with several input options. The indicator’s alert messages generate when the bar closes above or below that trend line.

The images show the alerts and indicator. After discussing the code we’ll take a closer look at the script’s behaviour and the alerts it generates.

Example alert triggered by mouse clicks Example chart with the trend lines drawn by the MultiCharts script

[ProcessMouseEvents = true];

Inputs:
    LineColour(blue),
    LineWidth(2),
    LineExtension(true),
    LineLength(10);

Variables:
    trendLineID(0),
    linePrice(0);

// Create and format the trend line once    
once begin
    
    trendLineID = TL_New_DT(DateTime[1], Close, DateTime, Close);
    
    TL_SetColor(trendLineID, LineColour);
    TL_SetSize(trendLineID, LineWidth);
    TL_SetExtRight(trendLineID, LineExtension);

end;

// We update the trend line with each click + Control
if (MouseClickCtrlPressed) then begin

    TL_SetEnd_DT(trendLineID, Symbol_DateTime, MouseClickPrice);
    TL_SetBegin_DT(trendLineID, Symbol_DateTime[LineLength - 1], 
        MouseClickPrice);

end;

// When the bar closes, check if the bar crossed above or
// below the trend line's price value
if (BarStatus = 2) then begin
    
    linePrice = TL_GetEndVal(trendLineID);
    
    if (Close > linePrice) and (Close[1] < linePrice) then
        Alert("Bar closed above the trend line @ " + NumToStr(linePrice, 5))
        
    else if (Close < linePrice) and (Close[1] > linePrice) then
        Alert("Bar closed below the trend line @ " + NumToStr(linePrice, 5));

end;

We first set the ProcessMouseEvents attribute to true. That makes it possible for the script to process mouse clicks (MultiCharts Wiki, 2012a; PowerLanguage Keyword Reference, 2016).

Then we create 4 input options and 2 numerical variables:


Inputs:
    LineColour(blue),
    LineWidth(2),
    LineExtension(true),
    LineLength(10);

Variables:
    trendLineID(0),
    linePrice(0);

The input options all affect the appearance of the horizontal trend line. LineColour specifies that line’s colour, whereas LineWidth sets the size of the line. The LineExtension input sets if the trend line continues indefinitely to the right (true) or not (false). And the LineLength input configures how many bars the line has to extend to the left. The higher that value, the longer the line becomes by encompassing more historical bars.

The two numerical variables that we make are trendLineID and linePrice. We’ll use the first later to hold the trend line’s ID number, which we store in a variable to access the trend line later on. The second variable will hold the trend line’s price, which we use when generating the alerts.

Creating the trend line is next:


once begin
    
    trendLineID = TL_New_DT(DateTime[1], Close, DateTime, Close);
    
    TL_SetColor(trendLineID, LineColour);
    TL_SetSize(trendLineID, LineWidth);
    TL_SetExtRight(trendLineID, LineExtension);

end;

The line is made here in an once code block. Any statement inside this code block – that is, the code between begin and end – only executes once. That creates the line just once, which is more efficient than creating and removing a line repeatedly.

The line is made with TL_New_DT() here. That keyword draws a trend line between a start and end point, and returns a trendline-specific ID number that’s needed to access and modify the line later on (PowerLanguage Keyword Reference, 2016). To draw the line, the keyword needs the DateTime and price value of the line’s starting and ending point as parameters.

Note: A ‘DateTime’ value is a numerical value whose integer portion represents the number of days elapsed since January 1, 1900, and whose fractional value indicates the portion of the day that elapsed since midnight (PowerLanguage Keyword Reference, 2016). This makes DateTime values contain both a date as well as a time of day.

We use TL_New_DT() here to draw a trend line between the time (DateTime[1]) and close (Close[1]) of the previous bar and the time and close of the current bar (DateTime and Close). This creates a small, horizontal trend line between two bars. For now, that’s okay; later on we’ll update the location of this trend line when a mouse click happens.

After creating our initial line, we store its numerical identifier in the trendLineID variable. Then we use that variable to change the line’s visual appearance. With TL_SetColor() we set the colour of the trend line we’ve just made to the LineColour input option (that has a default colour of blue). And TL_SetSize() changes the line’s size to the LineWidth input option, which has a default value of 2 to make the line a bit bigger than default (PowerLanguage Keyword Reference, 2016). With the TL_SetExtRight() keyword we then extend the trend line to the right or not, depending on the value of the LineExtension input. Since that input has a default of true, the line is initially extended indefinitely to the right.

After we making and adjusting the line, we move it to its proper location each time a mouse click with the Control key happens:


if (MouseClickCtrlPressed) then begin

    TL_SetEnd_DT(trendLineID, Symbol_DateTime, MouseClickPrice);
    TL_SetBegin_DT(trendLineID, Symbol_DateTime[LineLength - 1], 
        MouseClickPrice);

end;

This if statement evaluates MouseClickCtrlPressed. That keyword returns true when a mouse click happened while the Control key was held down. It returns false whenever such a mouse click with keyboard key didn’t happen (PowerLanguage Keyword Reference, 2016).

Now when such a mouse click indeed happened, the if statement’s code begins with updating the line’s end point with TL_SetEnd_DT(). That keyword requires three parameters: the ID of the trend line to update alongside the DateTime and price value of the line’s new end point (PowerLanguage Keyword Reference, 2016). To identify the line we use the trendLineID variable in which we stored the trend line ID a moment ago. We set the time coordinate of the line’s end point to the bar’s DateTime value (Symbol_DateTime) while the price value of the line’s end point becomes the clicked-on price (MouseClickPrice).

Next we use TL_SetBegin_DT() to update the line’s begin point. That keyword also requires three parameters: the numerical value to identify the trend line besides the DateTime and price value of that line’s new starting point. We identify the line with trendLineID, and update its location to the Symbol_DateTime[LineLength - 1] DateTime value and MouseClickPrice price value.

We use the Symbol_DateTime value of LineLength - 1 bars ago here because that LineLength input option specifies how many bars the line should extend to the left. With the line already ending on the current bar, its begin point has to be one bar less than the LineLength input option specifies. So when that input has its default value of 10, we place the line’s begin point 9 bars ago so that it overlaps 10 bars in total. And by using Symbol_DateTime for that here we can access the DateTime value of any price bar that’s on the chart (see MultiCharts Wiki, 2012b).

Note: When changing the location of a trend line, its end point has to be changed before adjusting the line’s begin point (MultiCharts Wiki, 2012c). That’s why we first used TL_SetEnd_DT() before TL_SetBegin_DT(). A line’s end point is, by the way, the coordinate that has the later date and time or, when the line is vertical, the higher price (MultiCharts Wiki, 2012c).

After drawing and updating the trend line, it’s time to generate alerts based on the mouse click price:


if (BarStatus = 2) then begin
    
    linePrice = TL_GetEndVal(trendLineID);
    
    if (Close > linePrice) and (Close[1] < linePrice) then
        Alert("Bar closed above the trend line @ " + NumToStr(linePrice, 5))
        
    else if (Close < linePrice) and (Close[1] > linePrice) then
        Alert("Bar closed below the trend line @ " + NumToStr(linePrice, 5));

end;

To only generate alerts when the bar closes above or below the mouse click price, this if statement checks whether BarStatus returns a value equal to (=) 2. Such a value is returned by that keyword when the script currently calculates on the closing tick of the price bar (PowerLanguage Keyword Reference, 2016).

That makes the code inside this if statement only execute once per bar, on bar close. There are two benefits of that. First, it allows us to compare the current closing price with the previous close. That makes the script look for a cross over or under based on closing prices, not the current tick compared with the previous close. Second, it naturally limits the number of alerts per bar to 1.

The if statement’s code first retrieves the trend line’s current price (which is the same as where the mouse click happened). We use TL_GetEndVal() for that, a keyword that returns the price value of a line’s end point and has one parameter: the numerical ID of the trend line in question (PowerLanguage Keyword Reference, 2016). Here we identify the line with the trendLineID variable. The line’s price value that this returns is stored in the linePrice variable. Since the line is horizontal, the line’s end point has the same price as other parts of the line have.

Then an if/else statement compares the bar’s current and previous close with the line’s price. The condition of the if part evaluates 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; otherwise, when one or both values are false, then the result combined with and is false too (MultiCharts Wiki, 2012d).

The first expression checks whether the bar’s closing price (Close) is greater than (>) the price of the line (linePrice). And the second expression evaluates if the previous bar’s closing price (Close[1]) is less than (<) the trend line’s price. Combined, this if statement’s condition is true whenever the bar crossed above the trend line (which we placed at the mouse click location).

In that case, we generate an alert programmatically with Alert() (PowerLanguage Keyword Reference, 2016). The message that we generate here is a fixed text (“Bar closed aboveĀ…”) coupled with numerical value in the alert message. We do that latter part with NumToStr(). That keyword formats a number to a string with a certain amount of decimals and requires two parameters: the number to convert and how many decimals that number should get (PowerLanguage Keyword Reference, 2016). Here we use linePrice and 5 as parameters, and that makes the clicked-on price level appear with 5 decimals in the alert messages (see images further down below for an example).

The else if portion of the if/else statement is practically the same. Now we check whether the bar’s closing price (Close) is less than (<) the trend line’s price (linePrice) while the previous bar’s close (Close[1]) was still above (>) that price value. When that’s the case, we again generate an alert with Alert() and include the current trend line price value in the alert message.

Example: generating MultiCharts alerts with mouse clicks

Now let’s see what the above indicator does. Before it can generate alerts, we do need to enable the script’s alert settings like so:

Configuring the alert settings of the MultiCharts indicator

In the same ‘Format Study’ window as where we configure the manual alert settings, we can also set the indicator’s input options:

Input options of the MultiCharts example indicator

When we add the script to the chart, nothing happens yet:

Empty chart with the recently added example indicator

This chart is still ‘empty’ because the script needs a mouse click before it can draw a trend line. And so when we click on the chart while holding down Control, it changes to:

Drawing trend lines semi-automatically with the MultiCharts script

After the click, the script made a blue horizontal trend line that indicates where the mouse click happened. When a price bar crosses the line like so:

Example of a price bar crossing our MultiCharts trend line

Then the indicator generates an alert saying that the bar closed above the trend line:

Example alert for a close above the trend line

A similar thing happens when the bar drops below the price level we’ve specified with a mouse click like this:

Price bar dropping below the semi-automatic MultiCharts trend line

Then the alert generated by the script looks like:

Example of an alert generated by the script

We can change the appearance of the trend line with the script’s inputs. For instance, a line width of 3 with a colour of yellow and no extension makes the line show as:

Different trend lines on the MultiCharts chart after changing the script's settings

For another example that combines alerts with trend lines, see programmatically generating alerts with MultiCharts trend lines. And a different example that uses alerts with clicks is enable or disable a script’s alerts with a single mouse click.

Summary

When the script’s ‘Enable Alerts’ option is turned on, we can generate alerts programmatically with Alert(). While some manual MultiCharts drawings can also generate alerts, those alerts won’t have meaningful alert messages and each of those drawings has to be configured by hand. Another, more automatic approach is processing mouse clicks programmatically. That way we can simply click somewhere on the chart to generate an alert at that price level. To implement this, we first add the ProcessMouseEvents attribute to the script. Then when we click on the chart, the MouseClickPrice keyword returns the click’s price location. By using that price to draw a horizontal line (for instance with the TL_New_DT() keyword), we can see which price level is currently used by the script. With the line made, we need to update it whenever a new click happened. That’s something we do with the TL_SetEnd_DT() and TL_SetBegin_DT() keywords. When we use a line to highlight where the click happened, we can get the line’s price value with TL_GetEndVal() and then use that price to generate an alert with.

Learn more:


References

MultiCharts Wiki (2012a, February 24). ProcessMouseEvents. Retrieved on July 14, 2016, from https://www.multicharts.com/trading-software/index.php/ProcessMouseEvents

MultiCharts Wiki (2012b, March 1). Symbol_Close. Retrieved on July 21, 2016, from http://www.multicharts.com/trading-software/index.php/Symbol_Close

MultiCharts Wiki (2012c, May 2). TL SetEnd. Retrieved on July 22, 2016, from http://www.multicharts.com/trading-software/index.php/TL_SetEnd

MultiCharts Wiki (2012d, February 19). And. Retrieved on July 22, 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