Situation
Instead of recalculating a script based on a time interval, you want to know how to recalculate your indicator or strategy instantaneously.

Programming example

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

namespace PowerLanguage.Indicator
{
    [SameAsSymbol(true)]
    public class Example_RecalculateConditionally : IndicatorObject
    {
        private int recalcCounter = 1;

        public Example_RecalculateConditionally(object _ctx) : base(_ctx) { }
        
        protected override void Create()
        {
            Output.Clear();
        }
                
        protected override void StartCalc()
        {
            // Output information about the current (re)calculation
            Output.WriteLine("{0} - Calculating the indicator - #{1}", 
                DateTime.Now.ToString("HH:mm:ss.fff"),
                recalcCounter);
        }        
        
        protected override void CalcBar()
        {
            // Recalculate on the last bar of the chart, but no more than five times
            if (Bars.LastBarOnChart && (recalcCounter < 5))
            {
                recalcCounter++;

                ExecControl.Recalculate();
            }
        }
    }
}

Output of the programming example

The indicator generates the following text to the PowerLanguage .NET Editor Output window:

18:48:45.193 - Calculating the indicator - #1
18:48:45.202 - Calculating the indicator - #2
18:48:45.204 - Calculating the indicator - #3
18:48:45.207 - Calculating the indicator - #4
18:48:45.210 - Calculating the indicator - #5

Forcing a script to be recalculated in MultiCharts .NET

By default, in real-time MultiCharts .NET trading strategies are updated on every tick while indicators are updated once at bar close or with every price update depending on the UpdateOnEveryTick attribute (MultiCharts Wiki, 2012).

Programmatically forcing an indicator or trading strategy to be recalculated can be done in two ways:

  • Recalculation based on a time interval with the RecalcLastBarAfter() method. This is especially helpful in slow markets, because it ensures that the script is at least recalculated once every time interval.
  • Immediate recalculation with the Recalculate() method (see MultiCharts, 2013), which is useful if a script needs to be retroactively recalculated.

Script recalculation is also done in other circumstances, such as changing the data series, reloading price data, changing indicator or strategy settings, enabling a script after it has been turned off, or when using the Expert Commentary.

Implementation of an immediate recalculation is straightforward: just call the ExecControl.Recalculate() method in the StartCalc() or CalcBar() override methods (MultiCharts, 2013). To see how, let’s look at the programming example.

MultiCharts .NET programming example

The example begins with setting the SameAsSymbol attribute to true (line 8). This ensures that the indicator is plotted on the main price chart instead of on a separate sub-chart.

Then the recalcCounter integer variable is declared and assigned a value of 1 (line 11). This variable is used later on to keep track of the number of times the indicator has been recalculated.

Clearing the PowerLanguage .NET Editor Output window

The next part of the example is the Create() method:

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

In this method, executed when the indicator is created, the Output.Clear() method is called. This clears the PowerLanguage .NET Editor Output Window to prevent cluttering.

Outputting calculation information with PowerLanguage .NET

Next information is outputted on every (re)calculation:

protected override void StartCalc()
{
    // Output information about the current (re)calculation
    Output.WriteLine("{0} - Calculating the indicator - #{1}", 
        DateTime.Now.ToString("HH:mm:ss.fff"),
        recalcCounter);
}    

Here string substitution parameters are used to output two values. The first is the current computer DateTime formatted to a string. The second is the recalcCounter variable that keeps track of how many times the indicator was calculated.

Recalculating the script conditionally

Then we arrive at the CalcBar() override method:

// Recalculate on the last bar of the chart, but no more than five times
if (Bars.LastBarOnChart && (recalcCounter < 5))
{
    recalcCounter++;

    ExecControl.Recalculate();
}

Before the body of this if statement is executed, two conditions need to be satisfied. First, the current bar needs to be the last bar on the chart (in which case the Bars.LastBarOnChart property returns true). Second, the recalcCounter variable needs to be less than 5.

If you call the ExecControl.Recalculate() method unconditionally (without an if statement that acts as a filter) the indicator or strategy gets stuck in a recalculation loop.

When both evaluate to true, the recalcCounter variable is incremented by one with the postfix increment operator (++). This counter variable places a limit on how many times the indicator is recalculated, which prevents a never-ending recalculation loop.

The ExecControl.Recalculate() method (line 35) performs the recalculation. Because this method triggers an immediate recalculation, any statement after this line will not be executed. That’s why the recalcCounter variable is incremented before the actual recalculation.

Key points:

  • Recalculations based on a time interval are done with the RecalcLastBarAfter() method while immediate recalculations call the Recalculate() method;
  • If the ExecControl.Recalculate() statement executes, the remaining statements in that method will not be executed;
  • Calling the Recalculate() method unconditionally causes the indicator or strategy to be stuck in a recalculation loop.
References

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

MultiCharts Wiki (2012). How Scripts Work. Retrieved on May 4, 2014, from http://www.multicharts.com/trading-software/index.php/How_Scripts_Work