MultiCharts indicators and strategies can process manual mouse clicks that happen on the chart. But for that we first need to enable an attribute. How to do so?

In this article:

Enabling mouse click processing with a MultiCharts attribute

A PowerLanguage attribute is a keyword that enables or disables a certain script feature. Attributes are applied when the code compiles and cannot be modified during run-time (e.g., MultiCharts Wiki, 2012a). This means that we cannot change whichever feature is set by the attribute unless we change the attribute to true or false in the code and then recompile the script.

Furthermore, most attributes (including ProcessMouseEvents) have no manual setting. And so adding the attribute to a script’s code is often the only way to change whichever behaviour is affected by the attribute. While PowerLanguage attributes can be added anywhere in the script, their typical location is in the top of the script. Like we did here with the IntrabarOrderGeneration and RecoverDrawings attributes:

Example of placing MultiCharts attributes in a script

One PowerLanguage attribute is ProcessMouseEvents. This attribute, when set to true, allows an indicator or trading strategy to process mouse clicks that happen on the price chart (MultiCharts Wiki, 2012b). When this attribute isn’t added to the script’s code or set to false, then mouse clicks aren’t processed.

Using mouse clicks in MultiCharts PowerLanguage script

While the ProcessMouseEvents attribute enables mouse click processing in a script, this doesn’t mean that every mouse click on a MultiCharts chart is recognised. Clicks that happen on the status line, time axis, price axis, or in an indicator’s subchart are ignored. And so mouse clicks in the grey areas below won’t be known to the script even with ProcessMouseEvents enabled:

MultiCharts chart areas not processing mouse clicks
Note: ProcessMouseEvents only affects indicators and trading strategies (MultiCharts Wiki, 2012b). Mouse clicks are also only processed when the script is added to chart – clicks that happen in the Scanner/Watchlist or Portfolio Trader cannot be processed by a script.

After we’ve set the ProcessMouseEvents attribute to true and a recognised mouse click happens, several PowerLanguage keywords hold that click’s information:

See the chapter on working with mouse clicks in MultiCharts for more applications of mouse clicks.

Note: When ProcessMouseEvents is enabled, each recognised click on the chart causes a script recalculation. The calculation reason of a script can be retrieved with the GetAppInfo() keyword, which makes differentiating between left and right mouse clicks and only calculating a script with mouse clicks possible.

Enabling or disabling the processing of mouse clicks in MultiCharts

To have a script process mouse clicks, we set the ProcessMouseEvents attribute to true:


[ProcessMouseEvents = true];

When the attribute is omitted from the code or set to false, then the script will not process recognised mouse clicks.


[ProcessMouseEvents = false];

Mouse click processing has no manual equivalent option in the MultiCharts program. And so mouse click processing can only be enabled with ProcessMouseEvents is set to true.

Example: using mouse clicks to draw MultiCharts lines and text boxes

Now let’s look at how ProcessMouseEvents can be used. The example script below creates text boxes wherever a mouse click happened while the Control key was held down. The text of those boxes display the range of the bar where the click happened, and we connect them to that bar with a trend line. Mouse clicks that happened while the Shift key was held are also processed; those clicks will remove the oldest text box and trend line from the chart. After discussing the code we’ll look at how the indicator works when added to a chart.


[ProcessMouseEvents = true];
[RecoverDrawings = false];

Inputs:
    Text_Colour(blue),
    Text_Size(10),
    Text_FontName("Consolas");
    
Variables:
    textID(0),
    lineID(0),
    linePrice(0),
    bb(0),
    textMessage("");

// Create text box and line with a mouse click + Control
if (MouseClickCtrlPressed = true) then begin

    // Determine how many bars back the click is
    bb = (CurrentBar + MaxBarsBack) - MouseClickBarNumber;
    
    textMessage = "Range: " + 
        NumToStr(Symbol_High[bb] - Symbol_Low[bb], 0);
    
    // Create text box and format it
    textID = Text_New_DT(MouseClickDateTime,
        MouseClickPrice,
        textMessage);
        
    Text_SetSize(textID, Text_Size);
    Text_SetFontName(textID, Text_FontName);
    Text_SetColor(textID, Text_Colour);
    
    // Determine the line end point and draw it
    if (MouseClickPrice < Symbol_Low[bb]) then
        linePrice = MouseClickPrice + 3
    else
        linePrice = MouseClickPrice - 3;
    
    lineID = TL_New_DT(MouseClickDateTime, Symbol_Close[bb], 
        MouseClickDateTime, linePrice);
        
    TL_SetColor(lineID, Text_Colour);
    TL_SetStyle(lineID, 3);

end;

// Remove the last text box and line with each 
// mouse click + Shift
if (MouseClickShiftPressed) then begin

    // Get the text box and remove it
    textID = Text_GetFirst(1);
    
    if (textID <> -2) then
        Text_Delete(textID);

    // Get the trend line and remove it
    lineID = TL_GetFirst(1);
    
    if (lineID <> -2) then
        TL_Delete(lineID);
    
end;

We first enable the ProcessMouseEvents attribute and then turn the RecoverDrawings attribute off. With that attribute set to false, intra-bar generated drawings (arrows, text boxes, and trend lines) will not be automatically removed by MultiCharts (MultiCharts Wiki, 2014).

Then we add three input options to the script:


Inputs:
    Text_Colour(blue),
    Text_Size(10),
    Text_FontName("Consolas");

The Text_Colour input is set to the blue colour, which we use to colour the text boxes and their trend lines. The Text_Size input sets the font size while Text_FontName specifies the font that’s used by the text boxes. These last two inputs are set to defaults of 10 points and the Consolas font.

Then we make several variables:


Variables:
    textID(0),
    lineID(0),
    linePrice(0),
    bb(0),
    textMessage("");

The textID and lineID variables are used to hold the numerical identifier of the text box and trend line that we’re working with. We use the linePrice variable to hold the trend line’s end point while bb (bars back) is used when accessing price data from historical bars. Last but not least, the textMessage string variable will hold the message that we’re placing in the text box.

The script’s actual code begins after creating the variables. That code consists out of two if statements. The first contains code that executes when a mouse click with Control happens, in which case the MouseClickCtrlPressed keyword equals (=) true. The second if statement holds code that’s processed after a mouse click with Shift (then MouseClickShiftPressed is true).

The ‘mouse click with Control’ code creates the text boxes and trend lines, and starts with the following:


bb = (CurrentBar + MaxBarsBack) - MouseClickBarNumber;

textMessage = "Range: " + 
    NumToStr(Symbol_High[bb] - Symbol_Low[bb], 0);

Here we set the bb variable to the number of bars back of where the mouse click happened (MouseClickBarNumber), relative to the bar number that the script currently calculates on (CurrentBar + MaxBarsBack). This calculated value (which tells us how many bars ago the click happened), is used afterwards to access price data from the clicked-on bar.

We then set the textMessage variable to a fixed string ("Range: ") plus the string that’s returned by NumToStr(). That PowerLanguage keyword converts a numerical value (its first parameter) to a string with a certain amount of decimals, which is set by its second parameter (MultiCharts Wiki, 2012c). The first argument of NumToStr() is set to the difference between the high (Symbol_High) and low (Symbol_Low) of the bar on which the click happened, which we access by placing the bb variable in the square brackets ([ and ]) after these keywords.

The range of that bar is formatted by NumToStr() to a string with 0 decimals. We can use zero decimals since the instrument that we add the example to doesn’t have decimals after the floating point of its price axis values (see images below).

We use Symbol_High and Symbol_Low instead of the typical High and Low PowerLanguage keywords because keywords prefixed with Symbol can access any price bar on the chart (see MultiCharts Wiki, 2012d), something that the standard price data keywords (like High and Low) cannot do.

After we’ve generated the text we want to place in the text box, we create the text box itself:


textID = Text_New_DT(MouseClickDateTime,
    MouseClickPrice,
    textMessage);
    
Text_SetSize(textID, Text_Size);
Text_SetFontName(textID, Text_FontName);
Text_SetColor(textID, Text_Colour);

The text box is made with Text_New_DT(). This keyword creates a text box at the specified DateTime and price value (MultiCharts Wiki, 2013a). The three values that we pass into this keyword’s parentheses are MouseClickDateTime (which holds the DateTime value of the click’s location), MouseClickPrice (which contains the mouse click’s price location), and textMessage. That latter is the string variable we’ve set a moment ago.

Text_New_DT() returns an integer identifier that’s needed to further modify the text box (MultiCharts Wiki, 2013a). We store that value in the textID variable. Then we change the text box’s appearance. First we set the font’s size with Text_SetSize() and pass into this keyword the textID variable (which identifies the text box) and Text_Size (our input that’s set to 10 by default). Next we use Text_SetFontName() to set the font to the Text_FontName input (which holds ‘Consolas’). The last change is setting the font colour to the Text_Colour input with the Text_SetColor() keyword.

In the second part of the if statement we draw a trend line between the text box and the price bar it’s placed above or below:


if (MouseClickPrice < Symbol_Low[bb]) then
    linePrice = MouseClickPrice + 3
else
    linePrice = MouseClickPrice - 3;

lineID = TL_New_DT(MouseClickDateTime, Symbol_Close[bb], 
    MouseClickDateTime, linePrice);
    
TL_SetColor(lineID, Text_Colour);
TL_SetStyle(lineID, 3);

We first determine the line’s end point with an if/else statement. We do that so the trend line doesn’t end on the text box, but just below or above it (depending on where the text box is, which is located at the MouseClickPrice value). And so we check if the mouse click happened below the low of the clicked-on bar (MouseClickPrice < Symbol_Low[bb]). When it did, we set the linePrice variable to 3 points above the mouse click location. Otherwise (the else portion), the variable with the trend line’s end point is set to 3 points below the location of the mouse click.

Then we draw the trend line with TL_New_DT(). That keyword draws a trend line based on four values: the DateTime and price value of the starting point and the DateTime and price value of the line’s end point (MultiCharts Wiki, 2013b). The values that we use here are MouseClickDateTime for both the begin and end time (which creates a vertical trend line), the closing price of the clicked-on bar (Symbol_Close[bb]), and the linePrice variable with the line’s end point.

Since we store the trend line ID number returned by TL_New_DT() in the lineID variable, we can manipulate the trend line after making it. We first use TL_SetColor() to set the trend line to the same colour as the text (Text_Colour). Then we use TL_SetStyle() to set the style of the trend line (lineID) to 3, which gives the trend line a dotted line style (MultiCharts Wiki, 2013c).

Where the first part of the script makes the text box and trend line, the second part removes the oldest text box and trend line whenever a mouse click with Shift happens:


if (MouseClickShiftPressed) then begin

    // Get the text box and remove it
    textID = Text_GetFirst(1);
    
    if (textID <> -2) then
        Text_Delete(textID);

    // Get the trend line and remove it
    lineID = TL_GetFirst(1);
    
    if (lineID <> -2) then
        TL_Delete(lineID);
    
end;

This if statement evaluates the value of MouseClickShiftPressed, a keyword that returns true when a click with Shift happens on the chart. When that’s the case, we start by setting the textID variable to the value of Text_GetFirst(1). That keyword returns, with the value of 1 between its parentheses, the numerical ID of the oldest text box that’s made by the current script (MultiCharts Wiki, 2012e). Whenever that firstly created text box is removed, then the next oldest (the second created) text box becomes the oldest one (MultiCharts Wiki, 2012e).

Text_GetFirst() can return an invalid value (-2) when, for example, there is no text box on the chart. And so we first use an if statement to see whether the value of textID is unequal to (<>) -2. When that’s the case, we use Text_Delete() to remove the text box we’ve just retrieved with Text_GetFirst().

The remaining code in this if statement does the same for the trend line. That is, we first retrieve the oldest trend line with TL_GetFirst() and store that line’s identifier in the lineID variable. Then we check whether that variable has a valid value, in which case we use TL_Delete() to remove that trend line. And so each mouse click on the chart with Shift causes the oldest text box and trend line to be removed.

Using the ProcessMouseEvents attribute in a MultiCharts indicator

When we add the above example indicator to a chart, nothing happens yet and the chart remains empty:

Empty chart before using the MultiCharts script

However, once we click on the chart while holding down Control, the script draw a text box and trend line. After a couple of clicks, the chart looks like:

MultiCharts chart with the script's text boxes plotted

Each click with Shift removes the oldest text box and trend line. After 3 of those clicks, the previous chart changes to:

Removing MultiCharts drawings with each mouse click

And after three more clicks with Shift, only two text boxes with their trend lines remain:

Removing even more MultiCharts text boxes and trend lines

With two additional clicks with Shift the script has cleared the entire chart:

Empty MultiCharts chart after removing all drawings

The indicator has the following input options:

Input options of the MultiCharts script

When we change these to the Arial font with a size of 15, and set the colour to magenta, then the text boxes and trend lines made with each drawing look like:

Example of custom MultiCharts drawings, made with mouse clicks

To learn about other MultiCharts attributes, see RecoverDrawings to prevent intra-bar drawings from being removed automatically and IntrabarOrderGeneration to have a strategy generate intra-bar orders.

Summary

Indicators and trading strategies process mouse clicks when the ProcessMouseEvents attribute is set to true. Then each left or right mouse click on the chart triggers a script recalculation, as long as that click did not happen on the chart’s Status Line, price axis, time axis, or in an indicator’s subchart. Mouse click information is returned by several keywords: MouseClickPrice and MouseClickDateTime hold the price and time of where the click happened while MouseClickBarNumber returns the click’s bar number. The MouseClickCtrlPressed and MouseClickShiftPressed keywords make it possible to check whether the Control and/or Shift key(s) were held during the click. And MouseClickDataNumber returns the data series of where the click happened. Mouse clicks aren’t processed when ProcessMouseEvents is set to false, when the attribute is not present in the script’s code, or when the script runs in a different environment than a trading chart.


References

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

MultiCharts Wiki (2012b, February 24). ProcessMouseEvents. Retrieved on January 31, 2016, from http://www.multicharts.com/trading-software/index.php/ProcessMouseEvents

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

MultiCharts Wiki (2012d, March 1). Symbol_Close. Retrieved on January 31, 2016, from https://www.multicharts.com/trading-software/index.php/Symbol_Close

MultiCharts Wiki (2012e, February 13). Text_GetFirst. Retrieved on January 31, 2016, from http://www.multicharts.com/trading-software/index.php/Text_GetFirst

MultiCharts Wiki (2013a, June 5). Text_New_DT. Retrieved on January 31, 2016, from https://www.multicharts.com/trading-software/index.php/Text_New_DT

MultiCharts Wiki (2013b, June 5). TL_New_DT. Retrieved on January 31, 2016, from http://www.multicharts.com/trading-software/index.php/TL_New_Dt

MultiCharts Wiki (2013c, April 3). TL_SetStyle. Retrieved on January 31, 2016, from https://www.multicharts.com/trading-software/index.php/TL_SetStyle

MultiCharts Wiki (2014, January 23). RecoverDrawings. Retrieved on January 31, 2016, from http://www.multicharts.com/trading-software/index.php/RecoverDrawings