Situation
You want to know how to use mouse clicks and keyboard keys to reload a price chart in MultiCharts .NET.

Programming example

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using System.Windows.Forms;             // Added for easy referencing

namespace PowerLanguage.Indicator
{
    [SameAsSymbol(true), MouseEvents(true)]
    public class Example_ReloadMouseClick : IndicatorObject
    {
        public Example_ReloadMouseClick(object _ctx) : base(_ctx) { }

        protected override void CalcBar() { }

        // The OnMouseEvent() method is called with every mouse click on the chart
        protected override void OnMouseEvent(MouseClickArgs arg)
        {
            // Don't take action with right mouse clicks or when no key is pressed
            if (arg.buttons == MouseButtons.Right || arg.keys == Keys.None)
                return;

            switch (arg.keys)
            {
                // Left mouse button + Control: reloads 1 day of data on the active chart
                case Keys.Control:
                    OutputMessage(arg, "reloading 1 day worth of data.");
                    ChartCommands.CommandLine(".rld int = 1 day");
                    break;

                // Left mouse button + Shift: reloads 3 days worth of data on the active chart
                case Keys.Shift:
                    OutputMessage(arg, "reloading 3 days worth of data.");
                    ChartCommands.CommandLine(".rld int = 3 days");
                    break;

                // Left mouse button + Control + Shift: reloads all data series of the same 
                //      resolution on which the click took place
                case Keys.Control | Keys.Shift:
                    string timeFrame = BarsOfData(arg.data_number).Request.Resolution.Size + " " +
                        BarsOfData(arg.data_number).Request.Resolution.Type;

                    OutputMessage(arg, string.Format("reloading all {0} data series.",
                        timeFrame));

                    ChartCommands.CommandLine(".rld res = " + timeFrame);
                    break;
                    
                default:
                    break;
            }
        }

        // The OutputMessage() method outputs mouse click data
        private void OutputMessage(MouseClickArgs clickData, string message)
        {
            Output.WriteLine("{0} - {1} click + {2} received: {3}",
                DateTime.Now.ToString("HH:mm:ss.fff"),
                clickData.buttons,
                clickData.keys,
                message);
        }
    }
}

Output of the programming example

Applied to a chart like the following:

Example of reloading a chart with mouse clicks

The indicator generates the following output:

10:25:07.142 - Left click + Control received: reloading 1 day worth of data.
10:25:17.996 - Left click + Shift, Control received: reloading all 30 Minute data series.
10:25:27.857 - Left click + Shift received: reloading 3 days worth of data.
10:25:33.040 - Left click + Control received: reloading 1 day worth of data.
10:26:02.218 - Left click + Shift, Control received: reloading all 15 Minute data series.

Working with mouse events in MultiCharts .NET

Programmatically dealing with mouse clicks is one way to control MultiCharts .NET. Mouse clicks can, for example, be used to recalculate a script, cycle through a list of charts, or submit market orders.

See working with mouse clicks and combining mouse clicks with keyboard keys to learn more about processing mouse clicks in MultiCharts .NET.

Working with mouse clicks in a MultiCharts .NET script has two requirements:

  • The MouseEvents attribute needs to be set to true;
  • The OnMouseEvent() method, which allows control of mouse click events on the chart (PowerLanguage .NET Help, n.d.), needs to be implemented.

One way to use mouse clicks is by having them execute Command Line commands.

Reloading a chart programmatically in MultiCharts .NET

The MultiCharts .NET Command Line allows manipulation of the active chart with textual commands (MultiCharts Wiki, 2014). These commands can either be typed in manually or provided programmatically with the ChartCommands.CommandLine() method (MultiCharts Blog, 2013).

One of these commands is .rld, which reloads the price chart. Two .rld parameters are used in this article: int (reloads a specified amount of time back) and res, which reloads data series with a certain resolution (MultiCharts Wiki, 2014).

MultiCharts .NET programming example

First, a namespace is added:

using System.Windows.Forms;             // Added for easy referencing

The System.Windows.Forms namespace contains the MouseButtons and Keys enumerations. Including it saves having to specify the fully qualified name every time: now we can type Keys.Shift instead of System.Windows.Forms.Keys.Shift.

Then two MultiCharts .NET attributes are added:

[SameAsSymbol(true), MouseEvents(true)]

SameAsSymbol set to true plots the indicator on the main price chart (instead of a sub-chart), and setting MouseEvents to true turns on mouse click processing.

By the way, the CalcBar() override method (line 14) is an abstract method in the base class, and therefore always needs to be implemented (see Liberty & MacDonald, 2009). Not including it gives the ‘does not implement inherited abstract member’ error.

Processing mouse clicks in MultiCharts .NET

The mouse clicks are processed in the OnMouseEvent() method (lines 17-52), which has two parts: an if (lines 20-21) and switch statement (lines 23-51). These are discussed in turn below.

Conditionally calling the C# return statement

First, the if statement:

// Don't take action with right mouse clicks or when no key is pressed
if (arg.buttons == MouseButtons.Right || arg.keys == Keys.None)
    return;

The MouseClickArgs struct variable (named arg here; see line 17) contains all mouse click information, such as keys (arg.keys) and mouse buttons (arg.buttons).

Two expressions are evaluated here: whether arg.buttons equals the MouseButton.Right enumerator and if arg.keys signals that no keyboard key (Keys.None) was pressed during the mouse click.

With the conditional or operator (||) the entire statement will be true if one of these expressions are true. When that happens the return statement is called to exit the current method (see Albahari & Albahari, 2012). To learn more about return, see how to ‘stop’ a script from calculating.

‘Switching on’ the value of an enumerator

Next is the switch statement:

switch (arg.keys)
{
    // Left mouse button + Control: reloads 1 day of data on the active chart
    case Keys.Control:
        OutputMessage(arg, "reloading 1 day worth of data.");
        ChartCommands.CommandLine(".rld int = 1 day");
        break;
 
    // Left mouse button + Shift: reloads 3 days worth of data on the active chart
    case Keys.Shift:
        OutputMessage(arg, "reloading 3 days worth of data.");
        ChartCommands.CommandLine(".rld int = 3 days");
        break;
 
    // Left mouse button + Control + Shift: reloads all data series of the same
    //      resolution on which the click took place
    case Keys.Control | Keys.Shift:
        string timeFrame = BarsOfData(arg.data_number).Request.Resolution.Size + " " +
            BarsOfData(arg.data_number).Request.Resolution.Type;
 
        OutputMessage(arg, string.Format("reloading all {0} data series.",
            timeFrame));
 
        ChartCommands.CommandLine(".rld res = " + timeFrame);
        break;
         
    default:
        break;
}

Depending on the evaluation of the arg.keys enum variable, one of four cases (including the default case) are executed. Both the Control key (lines 26-29) and Shift key (lines 32-35) reload a certain amount of days back on the chart. The Control and Shift combination (Keys.Control | Keys.Shift, lines 39-47) reloads the full data range from any data series with a certain time frame.

Reloading a specific amount of days back in MultiCharts .NET

Both the Control and Shift key are processed similarly. Each first calls the OutputMessage() method (discussed below) in lines 27 and 33. Two arguments are provided to this method: the MouseClickArgs arg struct variable and a string with a short message.

Then the ChartCommands.CommandLine() method is called (lines 28 and 34) to reload price data programmatically, and with the int parameter either 1 or 3 days of price data are reloaded.

Reloading all data series with a specific resolution in MultiCharts .NET

A mouse click with both Control and Shift is processed in three steps:

// Left mouse button + Control + Shift: reloads all data series of the same
//      resolution on which the click took place
case Keys.Control | Keys.Shift:
    string timeFrame = BarsOfData(arg.data_number).Request.Resolution.Size + " " +
        BarsOfData(arg.data_number).Request.Resolution.Type;
 
    OutputMessage(arg, string.Format("reloading all {0} data series.",
        timeFrame));
 
    ChartCommands.CommandLine(".rld res = " + timeFrame);
    break;

PS: The BarsOfData() method provides, like the Bars property, access to all information from price bars from any data series (MultiCharts, 2013). This method can be used to retrieve data from additional data series.

First a string (timeFrame) is generated with time frame information. To access the data series on which the click took place, the arg.data_number variable is passed to the BarsOfData() method. This way the resolution size (Request.Resolution.Size) and resolution type (Request.Resolution.Type) for each of the two data series on the chart can be retrieved.

Then the OutputMessage() method (discussed below) is called with two arguments: the arg struct variable and the Format() method of the string class. This latter uses a substitution parameter in formatting the string.

The last part calls the ChartCommands.CommandLine() method. The res parameter is specified by the timeFrame variable. This way the data series resolution that needs to be reloaded is programmatically determined.

Output mouse click information in MultiCharts .NET

The OutputMessage() method is created as follows:

// The OutputMessage() method outputs mouse click data
private void OutputMessage(MouseClickArgs clickData, string message)
{
    Output.WriteLine("{0} - {1} click + {2} received: {3}",
        DateTime.Now.ToString("HH:mm:ss.fff"),
        clickData.buttons,
        clickData.keys,
        message);
}

This method has two parameters: clickData, which is a MouseClickArgs struct variable, and the message string variable. Both are used to generate a message to the Output Window with substitution parameters for four values: the current computer DateTime formatted to a string, the mouse button (clickData.buttons) and keyboard key(s) (clickData.Keys), and the message parameter.

The OutputMessage() method provides a convenient way to output this information without having to repeatedly type these statements.

Key points

  • Working with mouse clicks requires setting the MouseEvents attribute to true and implementing the OnMouseEvent() method;
  • Reloading a chart programmatically is done with the .rld command passed into the ChartCommands.CommandLine() method;
  • The int parameter of the .rld command specifies how much data needs to be reloaded, while the res parameter specifies which data series resolutions need to be reloaded.
References

Albahari, J. & Albahari, B. (2012). C# 5.0 in a Nutshell: The Definitive Reference (5th edition). Sebastopol, CA: O’Reilly Media.

Liberty, J. & MacDonald, B. (2009). Learning C# 3.0: Master the Fundamentals of C# 3.0. Sebastopol, CA: O’Reilly Media.

MultiCharts (April 2013). MultiCharts .NET Programming Guide (version 1.0). Retrieved from http://www.multicharts.com/downloads/MultiCharts.NET-ProgrammingGuide-v1.0.pdf

MultiCharts Blog (2013, May 31). MultiCharts .NET 8.7 Beta 2 – What’s New. Retrieved on September 1, 2014, from http://www.multicharts.com/traders-blog/?p=937

MultiCharts Wiki (2014). MultiCharts Work Area: Understanding Command Line. Retrieved on May 10, 2014, from http://www.multicharts.com/trading-software/index.php/MultiCharts_Work_Area#Understanding_Command_Line

PowerLanguage .NET Help (n.d.). Retrieved on May 16, 2014, from http://www.multicharts.com/downloads/PowerLanguage.NET.chm