Situation
You want to know how to plot indicator lines in a MultiCharts .NET indicator that use functions.

Programming example

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

namespace PowerLanguage.Indicator
{
    [UpdateOnEveryTick(false), SameAsSymbol(true)]
    public class Example_PlotMALines : IndicatorObject
    {
        private IPlotObject quickMAPlot, slowMAPlot;
        private AverageFC quickMA, slowMA;

        [Input]
        public int QuickMALength { get; set; }

        [Input]
        public int SlowMALength { get; set; }

        public Example_PlotMALines(object _ctx) : base(_ctx) 
        { 
            QuickMALength = 5;
            SlowMALength  = 30;
        }
        
        protected override void Create()
        {
            quickMAPlot = AddPlot(new PlotAttributes("QuickMA", EPlotShapes.Line, Color.ForestGreen,
                Color.Black, 2, EPlotStyle.Solid, true));

            slowMAPlot = AddPlot(new PlotAttributes("SlowMA", EPlotShapes.Line, Color.RoyalBlue,
                Color.Black, 1, EPlotStyle.Dash, false));

            quickMA = new AverageFC(this);
            slowMA  = new AverageFC(this);
        }
        
        protected override void StartCalc()
        {
            quickMA.price = Bars.Close;
            slowMA.price  = Bars.Close;

            quickMA.length = QuickMALength;
            slowMA.length  = SlowMALength;
        }
        
        protected override void CalcBar()
        {
            quickMAPlot.Set(quickMA.Value);
            slowMAPlot.Set(slowMA[0]);
        }
    }
}

Output of the programming example

The indicator will plot the following types of lines:

Example of plotting a function in MultiCharts .NET

Plotting in MultiCharts .NET

Any plot in MultiCharts .NET, whether it being a line plot, histogram plot, or textual plot, requires three things: declaring the plot object, creating (i.e., instantiating) the plot object in the Create() override method, and setting the value of the plot for each bar (MultiCharts, 2013). During this last step, a plot can be set to values from a MultiCharts .NET function.

To learn more about plotting in MultiCharts .NET, see plot types in MultiCharts .NET and setting plot options programmatically.

Using functions in MultiCharts .NET indicators and trading strategies

Working with functions in a MultiCharts .NET indicator or trading strategy requires the following steps (see MultiCharts, 2013):

  1. Since each function is a class, first an object from this class needs to be declared;
  2. An instance of this class needs to be created and assigned to the class object, which is done in the Create() method;
  3. In the StartCalc() override method, the properties of the function’s class instance are set (such as its length and the type of price data it should be calculated on);
  4. In the CalcBar() method, the function’s instance can be called to return its calculated value for that price bar.

The programming example below shows how to perform these four steps in a less abstract manner.

MultiCharts .NET programming example

The example begins with setting two MultiCharts .NET attributes:

[UpdateOnEveryTick(false), SameAsSymbol(true)]

By setting UpdateOnEveryTick to false, the indicator is only calculated on bar close. Setting SameAsSymbol to true ensures that the indicator is plotted on the main price chart.

Declaring plot and function class objects

Next a few objects are declared:

private IPlotObject quickMAPlot, slowMAPlot;
private AverageFC quickMA, slowMA;

The two IPlotObject objects (quickMAPlot and slowMAPlot) will do the plotting; the quickMA and slowMA instances of the AverageFC class are used to perform the moving average calculations.

Adding inputs to a MultiCharts .NET indicator

With inputs an indicator or trading strategy can have its settings conveniently changed in the ‘Format Study’ window. To do so, use the Input attribute:

[Input]
public int QuickMALength { get; set; }

[Input]
public int SlowMALength { get; set; }

public Example_PlotMALines(object _ctx) : base(_ctx) 
{ 
    QuickMALength = 5;
    SlowMALength  = 30;
}

Here two automatic properties are created: QuickMALength and SlowMALength. Both are set to default values in the indicator’s constructor (lines 22-23). This way there is a standard value for the indicator to calculate with.

Creating plot and function class objects

The objects we declared earlier (lines 11-12) will need to be instantiated in the Create() override method:

protected override void Create()
{
    quickMAPlot = AddPlot(new PlotAttributes("QuickMA", EPlotShapes.Line, Color.ForestGreen,
        Color.Black, 2, EPlotStyle.Solid, true));

    slowMAPlot = AddPlot(new PlotAttributes("SlowMA", EPlotShapes.Line, Color.RoyalBlue,
        Color.Black, 1, EPlotStyle.Dash, false));

    quickMA = new AverageFC(this);
    slowMA  = new AverageFC(this);
}

See plot types in MultiCharts .NET and setting plot options programmatically with PlotAttributes to learn more about plotting.

The first plot is given the name of ‘QuickMA’, set to a line (EPlotShapes.Line) with a green colour (Color.ForestGreen) and black Market Scanner background colour (Color.Black). The width of this line is set to 2, with a solid line (EPlotStyle.Solid) and the price marker is enabled (true).

The second plot is similar expect for a few differences: its name is set to ‘SlowMA’, the line is set to blue (Color.RoyalBlue) and has a dashed style (EPlotStyle.Dash).

In the second part of the Create() method (lines 34-35), two new instances of the AverageFC class are created. The this keyword refers to the current instance of an object (Liberty & MacDonald, 2009), and is used here to pass an instance of the current indicator to the function class.

Setting the function’s class properties

Next is the StartCalc() method:

protected override void StartCalc()
{
    quickMA.price = Bars.Close;
    slowMA.price  = Bars.Close;

    quickMA.length = QuickMALength;
    slowMA.length  = SlowMALength;
}

Two properties of the AverageFC class are set here. First, price sets the price data series on which the function is calculated on (in this case, the Bars.Close data). Second, length sets the length of the moving average. This is set here to the input values of QuickMALength and SlowMALength.

Plotting the moving average values

In the final part of the example the moving average values are plotted:

protected override void CalcBar()
{
    quickMAPlot.Set(quickMA.Value);
    slowMAPlot.Set(slowMA[0]);
}

To set the value of a plot object, its Set() method needs to be used (see MultiCharts, 2013). The current bar value from a function class can be retrieved in different ways: with the Value property (quickMA.Value; line 49) or with an index of zero (slowMA[0]; line 50).

Key points:

  • Creating a line plot first requires declaring an IPlotObject object, followed by object creation in the Create() method. Setting plot values is done by calling its Set() method;
  • Working with a function requires declaring a function class object and then creating this object in the Create() method. In the StartCalc() method the properties of this object are set, while in the CalcBar() method the calculated value for the current bar can be retrieved.
References

Liberty, J. & MacDonald, B. (2009). Learning C# 3.0: Master the Fundamentals of C# 3.0. 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