After we’ve drawn trend lines we can retrieve all trend lines from the chart. But how can we select lines with a specific feature out of all the lines on the chart?

Drawing MultiCharts .NET lines and using ID to select a line

The DrawTrendLine.Create() method draws trend lines and returns a reference to the line made (MultiCharts, 2014; PowerLanguage .NET Help, n.d.). When that reference is stored in an ITrendLineObject variable, we can modify or retrieve data from the line’s properties and methods through the variable.

One of those properties is ID which returns the trend line’s ID number (PowerLanguage .NET Help, n.d.). Each line in MultiCharts .NET is assigned an unique integer ID that starts at 1 for the first line, a feature that’s inherited from MultiCharts PowerLanguage (e.g., see MultiCharts Wiki, 2012).

A trend line’s ID number is not increased incrementally. Instead, an available ID number is assigned to a trend line when it’s created (Henry MultiCharts, 2015), meaning that the most recently created trend line won’t necessarily have the highest ID value. So removing a trend line that has an ID of 5 will give the drawing that’s created next this ID number. The IDs of other trend lines aren’t affected when a line is removed.

To change a trend line with a certain ID, we first need to retrieve a list of all trend lines. Such a trend line collection is returned by the DrwTrendLine.GetTrendLineObjects() method, which uses an EDrawingSource argument to specify the trend line type (see PowerLanguage .NET Help, n.d.). For more on the different EDrawingSource values, see working with a collection of trend lines. Once we have a collection of trend lines, we can loop over them with a foreach loop to see if any has the ID we’re looking for. An example of this is discussed below.

Example: changing certain trend lines based on their ID

The example draws 10 blue trend lines and then changes the trend line colour to black, green, and red of three trend lines based on their ID. When added to a CME’s Swiss Franc (CHF/USD) future chart, the indicator looks like:

Working with trend line ID in MultiCharts .NET

Programmatically changing MultiCharts .NET trend lines with certain IDs

The example indicator’s code is the following:

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

    protected override void CalcBar()
    {
        if (Bars.FullSymbolData.Current == (Bars.FullSymbolData.Count - 2))
        {
            // First, draw a couple of trend lines
            for (int i = 10; i <= 100; i += 10)
            {
                ChartPoint begin = new ChartPoint(
                    Bars.FullSymbolData.Time[i],
                    Bars.FullSymbolData.Close[i]);

                ChartPoint end = new ChartPoint(
                    Bars.Time[0], Bars.Close[0]);

                ITrendLineObject trendLine =
                    DrwTrendLine.Create(begin, end);

                trendLine.Size  = 1;
                trendLine.Color = Color.RoyalBlue;
            }

            // Now change the 3rd, 5th, and 7th trend line
            foreach (ITrendLineObject line in
                DrwTrendLine.GetTrendLineObjects(EDrawingSource.CurrentTech))
            {
                if (line.ID == 3)
                {
                    line.Size  = 5;
                    line.Color = Color.Red;
                }
                else if (line.ID == 5)
                {
                    line.Size  = 3;
                    line.Color = Color.Black;
                }
                else if (line.ID == 7)
                {
                    line.Size  = 3;
                    line.Style = ETLStyle.ToolDashed;
                    line.Color = Color.LimeGreen;
                }
            }
        }
    }
}

We start by adding two MultiCharts .NET class attributes. With SameAsSymbol set to true the indicator plots on the data series and not in its subchart. And with UpdateOnEveryTick set to false the indicator only calculates on bar close. Because its trend lines are only drawn once, the script doesn’t need to be evaluated with every tick.

Creating several MultiCharts .NET trend lines in a loop

The next part begins with an if statement inside the CalcBar() method that evaluates whether two values are equal to (==) each other. The first value is the Bars.FullSymbolData.Current property that returns the symbol’s current bar number starting from 1 (see PowerLanguage .NET Help, n.d.). The second is 2 minus Bars.FullSymbolData.Count, a property that returns the number of bars of the data series (see PowerLanguage .NET Help, n.d.).

This condition is true for the historical bar 2 bars before the last, and so won’t be triggered when new bars are formed due to real-time data. That way our trend lines are only drawn once.

When the script is evaluated on that historical bar, the code inside the if statement first executes a for loop. That loop starts at 10 and continues as long as the i loop variable is less than or equal to (<=) 100. After each loop cycle, the i loop variable has 10 added to its value with the additive compound assignment operator (+=). This type of operator combines a normal operator (in this case, +) with the assignment operator (=) (Sharp, 2013). In other words, i += 10 is just a shorthand way to write i = i + 10 (Dorman, 2010).

The code inside the for loop, executed for each of the 10 loop cycles, begins with declaring two ChartPoint struct variables. The first, begin, is set to the time and close of i bars ago. Thanks to the Bars.FullSymbolData property we can access any price bar of the data series here (see PowerLanguage .NET Help, n.d.), irrespective of the indicator’s MaxBarsBack setting. The second ChartPoint variable, end, is set to the current bar’s time and close (Bars.Time[0] and Bars.Close[0]).

Then we call the DrwTrendLine.Create() method to draw a trend line between both ChartPoint variables. Since begin was created with help of the i loop variable, while end wasn’t, each trend line drawn in the loop starts at a different point but always ends on the same bar (see image above).

The value returned by DrwTrendLine.Create() is assigned to an ITrendLineObject variable named trendLine. We subsequently use this variable to change the line’s appearance by setting its Size and Color properties to new values.

Changing specific MultiCharts .NET trend lines with their ID

In the second part of the CalcBar() method we change the 3rd, 5th, and 7th lines of the 10 we’ve just drawn. To do so, we first retrieve all trend lines with DrwTrendLine.GetTrendLineObjects(). In this method we pass the CurrentTech value from the EDrawingSource enumeration so that it only returns the lines created by the current script (PowerLanguage .NET Help, n.d.).

The foreach loop uses the collection returned by that method as the items to loop over. This loop has its type set to ITrendLineObject and its variable is named line. We’ll use that variable to access the collection’s current item inside the loop.

An if/else statement inside the loop compares the current item’s ID (line.ID) with the values of 3, 5, and 7. When the line that’s currently being processed in the loop has an ID of 3, we set that line’s Size property to 5 and its Color property to Color.Red. Likewise, the lines with IDs of 5 and 7 also have their visual appearance changed by assigning new values to the Size, Color, and Style properties. And so when the foreach loop ends, three out of 10 trend lines have a distinct look.

More examples of working with a collection of trend lines are retrieving all MultiCharts .NET trend lines and removing all trend lines from the chart. Instead of using a line’s ID property we can also select a specific trend line.

Summary

The DrwTrendLine.Create() method draws a trend line and returns a reference to the line created. With that reference assigned to an ITrendLineObject, the line’s properties and methods are accessible through that variable. A line’s ID property returns the unique numerical ID of a line. This integer starts at 1 and is incremented with 1 for every new line drawn. The IDs of trend lines that are removed are reused when new drawings are made. So the most recent trend line doesn’t need to have the highest ID value.

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_TrendLineID : IndicatorObject
    {
        public Example_TrendLineID(object _ctx) : base(_ctx) { }

        protected override void CalcBar()
        {
            if (Bars.FullSymbolData.Current == (Bars.FullSymbolData.Count - 2))
            {
                // First, draw a couple of trend lines
                for (int i = 10; i <= 100; i += 10)
                {
                    ChartPoint begin = new ChartPoint(
                        Bars.FullSymbolData.Time[i],
                        Bars.FullSymbolData.Close[i]);

                    ChartPoint end = new ChartPoint(
                        Bars.Time[0], Bars.Close[0]);

                    ITrendLineObject trendLine =
                        DrwTrendLine.Create(begin, end);

                    trendLine.Size  = 1;
                    trendLine.Color = Color.RoyalBlue;
                }

                // Now change the 3rd, 5th, and 7th trend line
                foreach (ITrendLineObject line in
                    DrwTrendLine.GetTrendLineObjects(EDrawingSource.CurrentTech))
                {
                    if (line.ID == 3)
                    {
                        line.Size  = 5;
                        line.Color = Color.Red;
                    }
                    else if (line.ID == 5)
                    {
                        line.Size  = 3;
                        line.Color = Color.Black;
                    }
                    else if (line.ID == 7)
                    {
                        line.Size  = 3;
                        line.Style = ETLStyle.ToolDashed;
                        line.Color = Color.LimeGreen;
                    }
                }
            }
        }
    }
}

References

Dorman, S. (2010). Sams Teach Yourself Visual C# 2010 in 24 Hours. Indianapolis, IN: Sams/Pearson Education.

Henry MultiCharts (2015, April 29). TL_new, TL_delete, TL_lock – forum discussion. Retrieved on May 18, 2015, from http://www.multicharts.com/discussion/viewtopic.php?f=1&t=48459#p115296

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

MultiCharts Wiki (2012, February 13). TL_New_s. Retrieved on May 18, 2015, from http://www.multicharts.com/trading-software/index.php/TL_New_s

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

Sharp, J. (2013). Microsoft Visual C# 2013 Step by Step. Microsoft Press.