Situation
Instead of crudely aborting a MultiCharts .NET script, you want to ‘stop’ the calculation of an indicator or trading strategy while still keeping the possibility of re-continuing the calculations at a later point.

Programming example

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

namespace PowerLanguage.Indicator
{
    [UpdateOnEveryTick(false)]
    public class Example_StoppingScript : IndicatorObject
    {
        private IPlotObject closingPrice;

        public Example_StoppingScript(object _ctx) : base(_ctx) { }
        
        protected override void Create()
        {
            closingPrice = AddPlot(new PlotAttributes("Close", EPlotShapes.Line, Color.Red));
        }
        
        protected override void CalcBar()
        {
            int stopAfterBarNum = Bars.FullSymbolData.Count - 20;

            // Don't calculate the indicator on the last 20 bars
            if (Bars.CurrentBar > stopAfterBarNum)
            {
                Output.WriteLine("{0} - Bar number: {1}. 'Stopping' calculation..",
                        Bars.Time[0].ToString("HH:mm"),
                        Bars.CurrentBar);

                return;
            }

            closingPrice.Set(Bars.Close[0]);
        }
    }
}

Output of the programming example

When applied to a chart, the indicator plots its line as follows:

Example of stopping a MultiCharts .NET script

An output similar to the following is generated to the PowerLanguage .NET Editor Output Window:

06:30 - Bar number: 3297. 'Stopping' calculation..
06:31 - Bar number: 3298. 'Stopping' calculation..
06:32 - Bar number: 3299. 'Stopping' calculation..
06:33 - Bar number: 3300. 'Stopping' calculation..
06:34 - Bar number: 3301. 'Stopping' calculation..
06:35 - Bar number: 3302. 'Stopping' calculation..
06:36 - Bar number: 3303. 'Stopping' calculation..
06:37 - Bar number: 3304. 'Stopping' calculation..
06:38 - Bar number: 3305. 'Stopping' calculation..
06:39 - Bar number: 3306. 'Stopping' calculation..
06:40 - Bar number: 3307. 'Stopping' calculation..
06:41 - Bar number: 3308. 'Stopping' calculation..
06:42 - Bar number: 3309. 'Stopping' calculation..
06:43 - Bar number: 3310. 'Stopping' calculation..
06:44 - Bar number: 3311. 'Stopping' calculation..
06:45 - Bar number: 3312. 'Stopping' calculation..
06:46 - Bar number: 3313. 'Stopping' calculation..
06:47 - Bar number: 3314. 'Stopping' calculation..
06:48 - Bar number: 3315. 'Stopping' calculation..
06:49 - Bar number: 3316. 'Stopping' calculation..

Controlling calculations in MultiCharts .NET

Managing indicator or strategy calculations is a way to control MultiCharts .NET, and can be done with either recalculating a script (see recalculating after a time period and triggering an immediate recalculation) or with aborting script calculations. This latter is done with the ExecControl.Abort() method (see PowerLanguage .NET Help, n.d.).

ExecControl.Abort() is a useful method, but does have two drawbacks. First, since it completely turns off the script until manually re-enabled, temporarily skipping calculations is not possible. Second, once the indicator or strategy has been turned off, it cannot be reactivated again programmatically. Luckily, the C# return statement can be used as an alternative to ExecControl.Abort().

‘Stopping’ a MultiCharts .NET script with the C# return statement

When the return statement is called in a method, code execution immediately exits the method (Stellman & Greene, 2010). The return statement can appear anywhere in a method, except in a finally block (Albahari & Albahari, 2012), and the same method can have multiple return statements.

By the way, 'stop' is deliberately used with single quotation marks because return does not literally stop or terminate the MultiCharts .NET script like ExecControl.Abort() does. With return, the CalcBar() method will still be called, but not all its statements will be executed anymore.

Technically, the return statement passes the value of the method back to the statement that called it (Stellman & Greene, 2010). When a method is marked void, the optional return statement ends with a semicolon, whereas for non-void methods it must return an expression of the method’s return type (Albahari & Albahari, 2012; Stellman & Greene, 2010).

For MultiCharts .NET, this means that the void CalcBar() method, which is called on every price bar (see MultiCharts, 2013), can be exit prematurely by calling return to skip any remaining statements in this method.

MultiCharts .NET programming example

The example begins with setting the UpdateOnEveryTick attribute to false, so that the indicator is only calculated on bar close:

[UpdateOnEveryTick(false)]

Adding a plot line to a MultiCharts .NET indicator

Next an IPlotObject is declared:

private IPlotObject closingPrice;

This closingPrice object is subsequently initialised in the Create() method:

protected override void Create()
{
    closingPrice = AddPlot(new PlotAttributes("Close", EPlotShapes.Line, Color.Red));
}

Here the plot line is given the name of "Close" in the MultiCharts .NET Data Window, and set to a line (EPlotShapes.Line) with the colour red (Color.Red).

‘Stopping’ calculating a MultiCharts .NET script

The CalcBar() override method is the last part of the example:

protected override void CalcBar()
{
    int stopAfterBarNum = Bars.FullSymbolData.Count - 20;

    // Don't calculate the indicator on the last 20 bars
    if (Bars.CurrentBar > stopAfterBarNum)
    {
        Output.WriteLine("{0} - Bar number: {1}. 'Stopping' calculation..",
                Bars.Time[0].ToString("HH:mm"),
                Bars.CurrentBar);

        return;
    }

    closingPrice.Set(Bars.Close[0]);
}

To 'stop' calculations for the last 20 bars on the chart, this bar number will first need to be calculated. This is done with the Bars.FullSymbolData.Count property to retrieve the bar number of the last bar of the data series (line 22).

The Bars.FullSymbolData property provides access to any price bar. To learn more, see how to access any historical price bar and accessing future price bars.

The if statement (lines 25-32) verifies if the current bar number (returned by Bars.CurrentBar) is greater than the just calculated stopAfterBarNum value. When that evaluates to true, the Output.WriteLine() method is called to print information to the Output Window (line 27-29). With string substitution parameters two values are included in the string: the bar's DateTime formatted to a string (line 28) and the bar number.

After that, the return statement is called (line 31) and the CalcBar() method is prematurely exited. This skips remaining statements in the method, so line 34 (which sets the line plot to the closing price of the primary data series) is not executed. In effect, this causes the indicator to be ‘stopped’ for the last 20 price bars.

Key points:

  • Indicators and strategies can be terminated programmatically by aborting script calculation with ExecControl.Abort();
  • Alternatively, the return statement can be used to exit a method prematurely;
  • Compared to ExecControl.Abort(), the return statement is more user-friendly and provides more flexibility, but does not actually prevent the CalcBar() from being executed.
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

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

Stellman, A. & Greene, J. (2010). Head First C#: A Brain-Friendly Guide (2nd edition). Sebastopol, CA: O’Reilly Media.