After drawing a trend line we can use its Delete() method to remove the trend line. But how can we check if a line is on the chart or if it’s already been removed?

Checking the existence of a MultiCharts .NET trend line

The DrwTrendLine.Create() method draws a trend line and returns a reference needed to further modify the line (MultiCharts, 2014; PowerLanguage .NET Help, n.d.). By assigning that reference to an ITrendLineObject interface variable, the trend line’s properties and methods can be accessed through the variable. That allows for things like relocating a trend line, changing its visual appearance, and removing a trend line.

One trend line property is Exist, which returns a Boolean true/false value that indicates if the line exists on the chart or not (see PowerLanguage .NET Help, n.d.). This property is typically used after checking if a line’s reference variable is unequal to (!=) null but before manipulating the trend line (see Henry MultiCharts, 2012).

The reasoning behind that is the following. When a trend line’s variable is null, it isn’t associated with a trend line object on the chart (see Albahari & Albahari, 2012) and using it to work with the trend line will throw a NullReferenceException exception (Stellman & Greene, 2010). So we don’t want to use the Exist property when the line’s variable is null.

Checking if Exist returns true before working with the line also makes sense. That’s because when Exist returns false, the trend line is removed from the chart and so for example changing its visual appearance is unnecessary and its Begin and End properties will return invalid values then.

Example: verifying a line’s existence in MultiCharts .NET

If we add the example indicator to an E-mini S&P 500 future chart, it draws a trend line like:

Verify if a MultiCharts .NET trend line exists

The indicator generates the following output in the PowerLanguage .NET Editor Output window after a mouse click with Control on the chart:

The line exists: begin at 2077,75 and end at 2071,75
The line is removed from the chart

Programmatically verifying the presence of a MultiCharts .NET trend line

The programming example looks as follows:

[SameAsSymbol(true), MouseEvents(true), RecoverDrawings(false)]
public class Example_TrendLineExist : IndicatorObject
{
    public Example_TrendLineExist(object _ctx) : base(_ctx) { }

    ITrendLineObject basicLine;

    protected override void CalcBar()
    {
        if (Bars.LastBarOnChart && basicLine == null)
        {
            // Create and adjust the trend line
            basicLine = DrwTrendLine.Create(
                new ChartPoint(Bars.Time[30], Bars.Close[30]),
                new ChartPoint(Bars.Time[0], Bars.Close[0]));

            basicLine.Color = Color.Purple;
            basicLine.Size  = 2;
        }
    }

    protected override void OnMouseEvent(MouseClickArgs arg)
    {
        if (arg.keys == Keys.Control)
        {
            if (basicLine.Exist)
            {
                Output.WriteLine(
                    "The line exists: begin at {0} and end at {1}",
                    basicLine.Begin.Price,
                    basicLine.End.Price);
            }

            // Remove the trend line
            basicLine.Delete();

            if (!basicLine.Exist)
            {
                Output.WriteLine("The line is removed from the chart");
            }

            //> The line exists: begin at 2077,75 and end at 2071,75
            //> The line is removed from the chart
        }
    }
}

We kickoff the example by setting three MultiCharts .NET class attributes. The first, SameAsSymbol, makes the indicator display on the data series and not in its own subchart. The second, MouseEvents, turns on mouse click processing. And the last, RecoverDrawings, prevents removal of intra-bar generated drawings (MultiCharts, 2014).

Then we declare an ITrendLineObject variable named basicLine in the top of the indicator’s class. This variable will hold the reference to the trend line we create later on.

Creating a MultiCharts .NET trend line

The CalcBar() method contains an if statement that evaluates two expressions. The first is whether the current bar is the last of the data series, in which case the Bars.LastBarOnChart property returns true (PowerLanguage .NET Help, n.d.). The second expression evaluates whether the basicLine variable equals null. Because the default value of reference variables is null (Sempf, Sphar, & Davis, 2010), basicLine is null at this point since it isn’t associated with a trend line yet.

In the if statement’s code block we call the DrwTrendLine.Create() method to draw a trend line. In it we pass two ChartPoint struct variables. This first is initialised to the time and close of an arbitrary 30 bars ago (Bars.Time[30] and Bars.Close[30]), while the second is set to the current bar’s time and close.

We assign the value returned by DrwTrendLine.Create() to the basicLine variable. This variable now holds a reference to the trend line object, making it to be different than null — which causes the if statement’s code block to be executed once. We can also use this variable now to modify the trend line, which we do by setting its Color and Size properties to new values to change its visual appearance.

Verifying the existence of a trend line in MultiCharts .NET

Next in the example is the OnMouseEvent() method that processes registered mouse clicks on the chart (see PowerLanguage .NET Help, n.d.). In it, an if statement evaluates if the keyboard key held down during the click (arg.keys) equals the Keys.Control value. This latter enumerator originates from the System.Windows.Forms namespace, which we’ve added with a using directive to the top of the indicator’s source code (see full code example below).

When a click with Control happened, a nested if statement evaluates whether the trend line’s (basicLine) Exist property returns true. When that is the case, the line is located on the chart and we output that information to the PowerLanguage .NET Editor’s Output Window.

After that we call the line’s Delete() method to remove the trend line from the chart. Another if statement then evaluates the line’s Exist property again, but this time with the logical not operator (!). An expression with this operator returns true when the value is false, and false when the value is true (Sempf et al., 2010). In this case, Exist returns false since we’ve just removed the trend line from the chart. That means !Exist returns true, and so the if statement’s code is executed and another confirming message is printed to the Output Window with Output.WriteLine().

To learn more, see removing a trend line and removing several trend lines for trend line removal and deleting a trend line object for how to schedule the trend line object itself for removal.

Summary

Trend lines are drawn with DrwTrendLine.Create(), a method that returns a reference to the line created. A line is removed by calling its Delete() method through the trend line’s reference variable. When a line might be removed, we can use a line’s Exist property to see whether the trend line is on the chart before performing actions on it.

Full code of MultiCharts .NET indicator example

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using System.Windows.Forms;         // For the Keys enumeration

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

        ITrendLineObject basicLine;

        protected override void CalcBar()
        {
            if (Bars.LastBarOnChart && basicLine == null)
            {
                // Create and adjust the trend line
                basicLine = DrwTrendLine.Create(
                    new ChartPoint(Bars.Time[30], Bars.Close[30]),
                    new ChartPoint(Bars.Time[0], Bars.Close[0]));

                basicLine.Color = Color.Purple;
                basicLine.Size  = 2;
            }
        }

        protected override void OnMouseEvent(MouseClickArgs arg)
        {
            if (arg.keys == Keys.Control)
            {
                if (basicLine.Exist)
                {
                    Output.WriteLine(
                        "The line exists: begin at {0} and end at {1}",
                        basicLine.Begin.Price,
                        basicLine.End.Price);
                }

                // Remove the trend line
                basicLine.Delete();

                if (!basicLine.Exist)
                {
                    Output.WriteLine("The line is removed from the chart");
                }

                //> The line exists: begin at 2077,75 and end at 2071,75
                //> The line is removed from the chart
            }
        }
    }
}

References

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

Henry MultiCharts (2012, October 3). How to delete previously drawn object and not last one? Forum discussion. Retrieved on April 7, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=19&t=11062#p54701

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.