In MultiCharts .NET we can programmatically create a trend line or even work with a collection of trend lines. But how do we remove trend lines from the chart?

Removing trend lines programmatically in MultiCharts .NET

Creating trend lines is done by the DrwTrendLine.Create() method, which returns a trend line reference after drawing the line (MultiCharts, 2014; PowerLanguage .NET Help, n.d.). That reference, when assigned to an ITrendLineObject variable, provides access to the trend line’s properties and methods.

One of those methods is Delete() which removes the trend line from the chart (MultiCharts, 2014) and returns a Boolean value that indicates if that operation succeeded or not (PowerLanguage .NET Help, n.d.). Afterwards, a line’s Exist property can be used to verify if the trend line is on the chart (see PowerLanguage .NET Help, n.d.).

By the way, drawings (trend lines, arrows, and text boxes) not made on bar close are automatically removed from the chart (MultiCharts, 2014). This counterintuitive behaviour is changeable with the RecoverDrawings attribute.

Creating and removing MultiCharts .NET trend lines: visual example

When the example indicator is added to a chart, like the GBP/USD chart below, it draws a trend line on every even bar number:

Remove MultiCharts .NET trend line - 1

It then removes that trend line on every odd bar number:

Remove MultiCharts .NET trend line - 2

Programmatically creating and removing trend lines in MultiCharts .NET

We achieve that behaviour with the following code:

[SameAsSymbol(true), UpdateOnEveryTick(false)]
public class Example_RemoveTrendLine : IndicatorObject
{
    public Example_RemoveTrendLine(object _ctx) : base(_ctx) { }

    ITrendLineObject myTrendLine;

    protected override void CalcBar()
    {
        if (Bars.LastBarOnChart)
        {
            if ((Bars.CurrentBar % 2 == 0))
            {
                // Create the trend line
                myTrendLine = DrwTrendLine.Create(
                    new ChartPoint(Bars.FullSymbolData.Time[50],
                        Bars.FullSymbolData.Close[50]),
                    new ChartPoint(Bars.Time[0], Bars.Close[0]));

                myTrendLine.Size  = 3;
                myTrendLine.Color = Color.Firebrick;
            }
            else
            {
                // Delete the trend line if it exists
                if (myTrendLine != null)
                    myTrendLine.Delete();
            }
        }
    }
}

The example first sets the SameAsSymbol attribute to true to plot the indicator on the data series. And with UpdateOnEveryTick set to false the script is only calculated on bar close. That way the trend line is only created or removed once per bar.

We then declare an ITrendLineObject reference variable named myTrendLine. Later on this variable will hold a reference to the trend line object and will be used to access the trend line’s Delete() method.

Drawing a trend line on every even bar number

The CalcBar() method starts with an if statement that checks if the current bar is the last (then Bars.LastBarOnChart returns true; see PowerLanguage .NET Help, n.d.). When that’s the case, an if/else statement is executed.

Its if statement uses the modulus operator (%) to see if the current bar number (Bars.CurrentBar) divides evenly into two. When it does, the DrwTrendLine.Create() method is called to create a trend line between two ChartPoint struct arguments.

The line’s starting coordinate is set to the time and close of an arbitrary 50 bars ago, which we access here with the Bars.FullSymbolData property. This property allows access to any price bar of the data series (see PowerLanguage .NET Help, n.d.). The line’s ending coordinate is set to the time (Bars.Time[0]) and close (Bars.Close[0]) of the current bar.

The ITrendLineObject reference returned by DrwTrendLine.Create() is assigned to the myTrendLine variable. We can then use that variable to modify the line, which we do by setting the Size and Color properties to change a trend line’s visual appearance.

Remove a trend line programmatically in MultiCharts .NET

The else part of the if/else statement removes the trend line. But when the script is added to the chart while Bars.CurrentBar is an odd number (so before the trend line is drawn), it will try to remove a trend line that isn’t there.

Accessing a trend line property or method when its reference variable doesn’t point to a trend line object on the chart generates a NullReferenceException error (see Stellman & Greene, 2010). For instance:

NullReferenceException in MultiCharts .NET

Such ‘empty’ reference variables have a default value of null (Sempf, Sphar, & Davis, 2010), which means they don’t point to an object (Albahari & Albahari, 2012). Knowing that, we can prevent that exception by first checking if myTrendLine is unequal to (!=) null before calling its Delete() method. That way we only execute Delete() when there’s actually something to delete.

To learn more about removing trend lines, see removing all trend lines from the chart and removing all manually drawn lines. Furthermore, we can also verify if the trend line is removed and delete the trend line object completely.

Summary

Trend lines are made with DrwTrendLine.Create(). This method returns an ITrendLineObject reference which, when assigned to a variable, allows us to call a line’s Delete() method. That method removes a trend line from the chart (but doesn’t remove the trend line object itself). If we use a trend line variable to access a property or method before this variable holds a reference to a trend line object, a NullReferenceException error is triggered.

Complete MultiCharts .NET indicator example

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

namespace PowerLanguage.Indicator
{
    [SameAsSymbol(true), UpdateOnEveryTick(false)]
    public class Example_RemoveTrendLine : IndicatorObject
    {
        public Example_RemoveTrendLine(object _ctx) : base(_ctx) { }

        ITrendLineObject myTrendLine;

        protected override void CalcBar()
        {
            if (Bars.LastBarOnChart)
            {
                if ((Bars.CurrentBar % 2 == 0))
                {
                    // Create the trend line
                    myTrendLine = DrwTrendLine.Create(
                        new ChartPoint(Bars.FullSymbolData.Time[50],
                            Bars.FullSymbolData.Close[50]),
                        new ChartPoint(Bars.Time[0], Bars.Close[0]));

                    myTrendLine.Size  = 3;
                    myTrendLine.Color = Color.Firebrick;
                }
                else
                {
                    // Delete the trend line if it exists
                    if (myTrendLine != null)
                        myTrendLine.Delete();
                }
            }
        }
    }
}

References

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

MultiCharts (2014). MultiCharts .NET Programming Guide (version 1.1). Retrieved from http://www.multicharts.com/downloads/MultiCharts.NET-ProgrammingGuide-v1.1.pdf

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

Sempf, B., Sphar, C., & Davis, S.R. (2010). C# 2010 All-In-One for Dummies. Hoboken, NJ: John Wiley & Sons.

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