Situation
You want to know how to programmatically control MultiCharts .NET with centering the chart on a specific bar.

Programming example

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

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

        protected override void StartCalc()
        {
            Output.Clear();
        }

        protected override void CalcBar() { }

        // The OnMouseEvent() method will be called with every mouse click on a chart
        protected override void OnMouseEvent(MouseClickArgs arg)
        {
            // With Control + left mouse click: scroll the chart to the bar that is clicked on
            if ((arg.buttons == MouseButtons.Left) && (arg.keys == Keys.Control))
            {
                Output.WriteLine("{0} - Scrolling to bar number {1} of data series #{2} ({3}).",
                    DateTime.Now.ToString("HH:mm:ss.fff"),
                    arg.bar_number,
                    arg.data_number,
                    BarsOfData(arg.data_number).Info.Name);

                ChartCommands.ScrollToBar(arg.data_number, arg.bar_number);
            }
        }
    }
}

Output of the programming example

Applied to a chart like the following:

Example: programmatically scrolling to a price bar in MultiCharts .NET

The indicator generates the following output:

06:49:51.753 - Scrolling to bar number 723 of data series #2 (EUR/GBP).
06:49:55.840 - Scrolling to bar number 1673 of data series #1 (EUR/USD).
06:49:56.567 - Scrolling to bar number 1665 of data series #1 (EUR/USD).
06:49:59.751 - Scrolling to bar number 698 of data series #2 (EUR/GBP).
06:50:07.147 - Scrolling to bar number 1664 of data series #1 (EUR/USD).
06:50:08.708 - Scrolling to bar number 641 of data series #2 (EUR/GBP).
06:50:11.282 - Scrolling to bar number 1660 of data series #1 (EUR/USD).
06:50:13.580 - Scrolling to bar number 627 of data series #2 (EUR/GBP).
06:50:14.866 - Scrolling to bar number 596 of data series #2 (EUR/GBP).
06:50:17.029 - Scrolling to bar number 566 of data series #2 (EUR/GBP).
06:50:20.008 - Scrolling to bar number 536 of data series #2 (EUR/GBP).

Programmatically scrolling in MultiCharts .NET

MultiCharts .NET can be programmatically controlled to do a variety of things, such as recalculating a script based on a time interval or processing mouse clicks and keyboard modifier keys.

Another way to control MultiCharts .NET is by programmatically scrolling the price chart to a specific bar. This is done with the ChartCommands.ScrollToBar() method (see MultiCharts Blog, 2013).

The ChartCommands.ScrollToBar() method requires two arguments (MultiCharts Blog, 2013):

  • The data series number, starting with 1 for the primary data series;
  • The bar number to scroll to, starting with 1 for the first bar. This value is independent from the MaxBarsBack setting: if the MaxBarsBack are set to 50, the chart can still scroll back to bar 3, for example.

Let’s examine how this method can be used together with mouse clicks.

MultiCharts .NET programming example

The example begins with adding a reference to the System.Windows.Forms namespace:

using System.Windows.Forms;             // Added for convenience

This makes using the MouseButtons and Keys enumerations easier later on in the example: now we can type Keys.Control instead of needing to add the namespace (System.Windows.Forms.Keys.Control).

Setting MultiCharts .NET class attributes

Then two class attributes are set to true:

[SameAsSymbol(true), MouseEvents(true)]

Setting the SameAsSymbol attribute to true causes the indicator to be plotted on the main price chart instead of having its own separate sub-chart. And enabling the MouseEvents attribute makes it possible to process mouse clicks.

Cleaning the PowerLanguage .NET Editor Output Window

Next is the StartCalc() override method:

protected override void StartCalc()
{
    Output.Clear();
}

By the way, the example implements the CalcBar() override method even though it is empty (line 19). Because CalcBar() is marked abstract (in the CStudyAbstract class), its implementation is mandatory (see Albahari & Albahari, 2012). Failing to do this triggers the 'does not implement inherited abstract member'-error message.

The StartCalc() method is called every time before an indicator or trading strategy begins its calculations (MultiCharts, 2013). To prevent cluttering the PowerLanguage .NET Editor Output Window, this window is cleared with every calculation by calling the Output.Clear() method.

Processing mouse clicks and scrolling to a specific bar

Then we implement the OnMouseEvent() method, which processes mouse clicks on the chart:

// The OnMouseEvent() method will be called with every mouse click on a chart
protected override void OnMouseEvent(MouseClickArgs arg)
{
    // With Control + left mouse click: scroll the chart to the bar that is clicked on
    if ((arg.buttons == MouseButtons.Left) && (arg.keys == Keys.Control))
    {
        Output.WriteLine("{0} - Scrolling to bar number {1} of data series #{2} ({3}).",
            DateTime.Now.ToString("HH:mm:ss.fff"),
            arg.bar_number,
            arg.data_number,
            BarsOfData(arg.data_number).Info.Name);

        ChartCommands.ScrollToBar(arg.data_number, arg.bar_number);
    }
}

See the articles working with mouse clicks and combining mouse clicks with keyboard keys to learn more about the usage features of the OnMouseEvent() method.

The if statement (line 25) verifies if the received mouse click is a left click (MouseButtons.Left) and accompanied with a pressed down Control key (Keys.Control). When these two expressions evaluate to true, information about the mouse click is outputted to the Output Window (lines 27-31). Four pieces of information are included in this string through string substitution parameters:

First, the current computer DateTime is formatted to a string. Then the bar number (arg.bar_number) and data series number (arg.data_number) on which the click occurred are included. Finally, the name of the symbol is outputted with the BarsOfData() method. This method gives access to the Bars property of any data series on the chart (see MultiCharts, 2013). With this it gives a way to access the Bars.Info.Name property (which returns the symbol name) of each data series.

The last statement in the OnMouseEvent() method calls the ChartCommands.ScrollToBar() method with two arguments: the data series number (arg.data_number) and the bar number (arg.bar_number) to scroll to. This makes the chart center on the bar on which the mouse click occurred.

Key points:

  • Programmatically scrolling on the price chart is done with the ChartCommands.ScrollToBar() method, which centers the chart on the specified bar number;
  • This method requires two integer values: the data series and the bar number to scroll to, both starting from 1.
References

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

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

MultiCharts Blog (2013). MultiCharts 8.5 Release Candidate - What’s New. Retrieved on May 8, 2014, from http://www.multicharts.com/traders-blog/?p=834