The MultiCharts .NET Command Line can be used to change a data series’ symbol, data range, or only the start or end date. But how can the data range be changed such that there a minimum amount of trading days on the chart?

Changing the data range with the MultiCharts .NET Command Line

The .csy Command Line command can change any chart symbol (MultiCharts Wiki, 2014) and is executed programmatically with ChartCommands.CommandLine() (PowerLanguage .NET Help, n.d.).

With .csy parameters from and to a symbol’s data range can be changed, but there is no parameter for setting this range to a certain amount of trading days (see MultiCharts Wiki, 2014). So, let’s create a workaround.

Determining the number of trading days in MultiCharts .NET

If we want to load a certain number of trading days on the chart, we can leave the chart’s ‘To’ date unchanged. The new ‘From’ date is determined with the NewStartDate() method:

private DateTime NewStartDate(int daysToLoad)
{
    int dayCounter = 0;

    DateTime beginDate = Bars.Request.Range.To;

    while (dayCounter < daysToLoad)
    {
        beginDate = beginDate.AddDays(-1);

        if (beginDate.DayOfWeek != DayOfWeek.Saturday &&
            beginDate.DayOfWeek != DayOfWeek.Sunday)
            dayCounter++;
    }

    Output.WriteLine("With {0} chart days, the start date is {1}.",
        daysToLoad,
        beginDate.ToString("d-M-yyyy"));

    return beginDate;
}

//> With 5 chart days, the start date is 1-12-2014.
//> .csy from=1-12-2014, to=8-12-2014

This method begins with declaring an integer (dayCounter) and DateTime (beginDate) variable. This latter is assigned the end value of the current chart’s data range, which is accessible with the Request.Range’s To variable (see PowerLanguage .NET Help, n.d.).

Then a while loop begins that continues as long as dayCounter is less than the daysToLoad parameter. This way the loop stops when dayCounter is equal to the number of bars we want to load. Inside the loop, the beginDate’s AddDays() method is called. With this method a specific number of days can be added or subtracted (Dorman, 2010). So with each loop cycle the beginDate value moves back one day in the past.

Counting the weekdays on a MultiCharts .NET price chart

The if statement inside the loop checks whether beginDate’s DayOfWeek enumeration is unequal to a Saturday and Sunday. When that evaluates to true, we know that beginDate currently is a weekday and add 1 to the value of dayCounter with the postfix increment operator.

This approach doesn’t deal with bank holidays, and price bars of today’s session aren’t taken into account. This is because these bars can still be an open session, and so we err on the safe side by not considering them a (completed) trading day.

The NewStartDate() method ends with printing information to the Output Window and returning the beginDate value to the caller method.

Changing the price chart to a certain amount of days

The chart’s data range is changed in the CalcBar() method:

private bool alreadyChanged = false;

protected override void CalcBar()
{
    if (Bars.LastBarOnChart && !alreadyChanged)
    {
        string command = String.Format(".csy from={0}, to={1}",
            NewStartDate(5).ToString("d/M/yyyy"),
            Bars.Request.Range.To.ToString("d/M/yyyy"));

        Output.WriteLine(command);

        ChartCommands.CommandLine(command);

        alreadyChanged = true;
    }
}

This if statement checks if the current bar is the last on the chart and if it’s true that alreadyChanged is false, tested with the logical not (!) operator. Since we later set alreadyChanged to true inside the if statement, this check prevents the data range from changing repeatedly.

Then the command string variable with the .csy command is generated with the String.Format() method and substitution parameters for the chart’s begin and end date. The DateTime value for the from parameter is returned by NewStartDate(5) (to load 5 trading days), while the to parameter uses the current end date of the chart (Bars.Request.Range.To).

Both DateTime values are formatted to a string with custom format specifiers, whereby "d" is the day of the month (1 to 31), "M" the month (1 through 12), and "yyyy" the year as a four-digit number (Dorman, 2010). The date format of from and to depends on your Windows settings (Andrew MultiCharts, 2014), and so you may need to use ToString("M/d/yyyy") instead of the format used in the code above.

The command variable is then passed into the Output.WriteLine() method for verification and into the ChartCommands.CommandLine() method to execute it.

For more on .csy and its parameters, see changing a symbol with the Command Line. Other examples of adjusting a symbol’s data range programmatically are changing the data range and loading a minimum amount of price bars on the chart.

Summary

The from and to parameters of the .csy Command Line command change a symbol’s data range. Such commands can be executed programmatically with ChartCommands.CommandLine(). By looping over historical calendar days a date range can be determined that includes a minimum amount of weekdays.

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_LoadMinAmountOfDays : IndicatorObject
    {
        public Example_LoadMinAmountOfDays(object _ctx) : base(_ctx) { }

        private bool alreadyChanged = false;

        protected override void CalcBar()
        {
            if (Bars.LastBarOnChart && !alreadyChanged)
            {
                string command = String.Format(".csy from={0}, to={1}",
                    NewStartDate(5).ToString("d/M/yyyy"),
                    Bars.Request.Range.To.ToString("d/M/yyyy"));

                Output.WriteLine(command);

                ChartCommands.CommandLine(command);

                alreadyChanged = true;
            }
        }

        private DateTime NewStartDate(int daysToLoad)
        {
            int dayCounter = 0;

            DateTime beginDate = Bars.Request.Range.To;

            while (dayCounter < daysToLoad)
            {
                beginDate = beginDate.AddDays(-1);

                if (beginDate.DayOfWeek != DayOfWeek.Saturday &&
                    beginDate.DayOfWeek != DayOfWeek.Sunday)
                    dayCounter++;
            }

            Output.WriteLine("With {0} chart days, the start date is {1}.",
                daysToLoad,
                beginDate.ToString("d-M-yyyy"));

            return beginDate;
        }

        //> With 5 chart days, the start date is 1-12-2014.
        //> .csy from=1-12-2014, to=8-12-2014
    }
}

References

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.

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