The Command Line can be used to change the primary data series. But how to change additional data series, for example such that both symbols have the same data range?

Changing MultiCharts .NET data series programmatically

The .csy Command Line command modifies existing symbols on the price chart (MultiCharts Wiki, 2014) and can be executed programmatically with the ChartCommands.CommandLine() method (PowerLanguage .NET Help, n.d.).

The dnum parameter specifies the data series number that .csy applies to, for example:

ChartCommands.CommandLine(".csy name=EUR/USD, df=LMAX, dnum=2");

Here .csy changes the second data series to LMAX’s EUR/USD. Omitted parameters, like those for the resolution and data range, default to the current data series’ properties. For more on .csy parameters, see changing the chart symbol with the Command Line.

A helpful method when working with multiple data series is BarsOfData(). This method provides access to data series information just like the Bars property does for the primary data series (MultiCharts, 2013).

Outputting the data range in MultiCharts .NET

The programming example begins with the StartCalc() method, which is executed once at the beginning of each calculation cycle (MultiCharts, 2013):

protected override void StartCalc()
{
    Output.WriteLine("Data 1\. From {0} to {1}.",
        BarsOfData(1).Request.Range.From.ToString("d-M-yyyy"),
        BarsOfData(1).Request.Range.To.ToString("d-M-yyyy"));

    Output.WriteLine("Data 2\. From {0} to {1}.",
        BarsOfData(2).Request.Range.From.ToString("d-M-yyyy"),
        BarsOfData(2).Request.Range.To.ToString("d-M-yyyy"));
}

Here the data range of both data series is outputted with Output.WriteLine(). For the first data series, we use BarsOfData(1) coupled with the Request.Range.From and Request.Range.To variables. These return the DateTime values of the data range (PowerLanguage .NET Help, n.d.), which is the range you’ll find in the ‘Format Instrument’ window.

Those DateTime values are formatted to a string with the "d-M-yyyy" custom format specifiers, which stand for the day of the month ("d"; 1 to 31), the month ("M"; 1 through 12), and the year as a four-digit number with "yyyy" (Dorman, 2010).

The second data series is outputted in the same way, except that 2 is passed into BarsOfData() for accessing the second data series.

Changing multiple data series with the Command Line

The next part changes both data series:

protected override void CalcBar()
{
    if (Bars.LastBarOnChart && !alreadyChanged)
    {
        DateTime maxToDate = new DateTime(Math.Max(
            BarsOfData(1).Request.Range.To.Ticks,
            BarsOfData(2).Request.Range.To.Ticks));

        DateTime minFromDate = new DateTime(Math.Min(
            BarsOfData(1).Request.Range.From.Ticks,
            BarsOfData(2).Request.Range.From.Ticks
            ));

        Output.WriteLine("Dates combined: earliest: {0}, latest: {1}.",
            minFromDate.ToString("d-M-yyyy"),
            maxToDate.ToString("d-M-yyyy"));

        ChartCommands.CommandLine(String.Format(
            ".csy dnum=1, from={0}, to={1}",
            minFromDate.ToString("d/M/yyyy"),
            maxToDate.ToString("d/M/yyyy")));

        ChartCommands.CommandLine(String.Format(
            ".csy dnum=2, from={0}, to={1}",
            minFromDate.ToString("d/M/yyyy"),
            maxToDate.ToString("d/M/yyyy")));

        alreadyChanged = true;
    }
}
//> Data 1\. From 24-10-2014 to 6-12-2014.
//> Data 2\. From 1-12-2014 to 6-12-2014.
//> Dates combined: earliest: 24-10-2014, latest: 6-12-2014.
//> Data 1\. From 24-10-2014 to 6-12-2014.
//> Data 2\. From 24-10-2014 to 6-12-2014.

This if statement verifies whether the current bar is the last bar on the chart (then Bars.LastBarOnChart returns true) and if the alreadyChanged variable is false, tested here with the logical not (!) operator.

When both of these expressions evaluate to true, the most recent (maxToDate) and oldest (minFromDate) DateTime values from both data series are determined. This is done with the Math.Max() and Math.Min() methods, which return the highest and lowest values of two arguments, respectively (Albahari & Albahari, 2012).

DateTime’s Tick property is used since Math.Max() and Math.Min() don’t accept regular DateTime values. Ticks returns the number of ticks representing the date and time that have elapsed since 1 January 0001 (Microsoft Developer Network [MSDN], n.d.), which allows for comparing greater or smaller numeric values.

Generating MultiCharts .NET Command Line commands programmatically

maxToDate and minFromDate are then outputted to the Output Window for verification and subsequently used as the to and from .csy parameters in the ChartCommands.CommandLine() method. Note that the date format of from and to depends on your Windows settings and is either day/month/year or month/day/year (Andrew MultiCharts, 2014).

In both ChartCommands.CommandLine() methods, String.Format() with substitution parameters is used to generate the .csy Command Line string. In the first ChartCommands.CommandLine() method call, .csy applies to the first data series with the dnum=1 parameter, whereas in the second it operates on the secondary data series (dnum=2).

The last statement sets the alreadyChanged variable to true. That way the code inside this if statement is only executed once, which prevents the .csy command from changing the chart repeatedly.

Summary

The .csy Command Line command can change different data series on the chart with its dnum parameter. This command can be executed programmatically with the ChartCommands.CommandLine() method.

Complete code of the MultiCharts .NET indicator

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;

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

        protected override void StartCalc()
        {
            Output.WriteLine("Data 1\. From {0} to {1}.",
                BarsOfData(1).Request.Range.From.ToString("d-M-yyyy"),
                BarsOfData(1).Request.Range.To.ToString("d-M-yyyy"));

            Output.WriteLine("Data 2\. From {0} to {1}.",
                BarsOfData(2).Request.Range.From.ToString("d-M-yyyy"),
                BarsOfData(2).Request.Range.To.ToString("d-M-yyyy"));
        }

        private bool alreadyChanged = false;

        protected override void CalcBar()
        {
            if (Bars.LastBarOnChart && !alreadyChanged)
            {
                DateTime maxToDate = new DateTime(Math.Max(
                    BarsOfData(1).Request.Range.To.Ticks,
                    BarsOfData(2).Request.Range.To.Ticks));

                DateTime minFromDate = new DateTime(Math.Min(
                    BarsOfData(1).Request.Range.From.Ticks,
                    BarsOfData(2).Request.Range.From.Ticks
                    ));

                Output.WriteLine("Dates combined: earliest: {0}, latest: {1}.",
                    minFromDate.ToString("d-M-yyyy"),
                    maxToDate.ToString("d-M-yyyy"));

                ChartCommands.CommandLine(String.Format(
                    ".csy dnum=1, from={0}, to={1}",
                    minFromDate.ToString("d/M/yyyy"),
                    maxToDate.ToString("d/M/yyyy")));

                ChartCommands.CommandLine(String.Format(
                    ".csy dnum=2, from={0}, to={1}",
                    minFromDate.ToString("d/M/yyyy"),
                    maxToDate.ToString("d/M/yyyy")));

                alreadyChanged = true;
            }
        }
        //> Data 1\. From 24-10-2014 to 6-12-2014.
        //> Data 2\. From 1-12-2014 to 6-12-2014.
        //> Dates combined: earliest: 24-10-2014, latest: 6-12-2014.
        //> Data 1\. From 24-10-2014 to 6-12-2014.
        //> Data 2\. From 24-10-2014 to 6-12-2014.
    }
}

References

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

Andrew MultiCharts (2014, October 6). Command line to change start date – forum discussion. Retrieved on November 21, 2014, from http://www.multicharts.com/discussion/viewtopic.php?f=1&t=47294#p108924

Dorman, S. (2010). Sams Teach Yourself Visual C# 2010 in 24 Hours. Indianapolis, IN (USA): Sams/Pearson Education.

Microsoft Developer Network (MSDN) (n.d.). DateTime.Ticks property. Retrieved on December 7, 2014, from http://msdn.microsoft.com/en-us/library/system.datetime.ticks%28v=vs.110%29.aspx

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

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

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