Trend lines can be drawn on the first data series and on multiple data series. But how do we create trend lines in an indicator’s subchart?

Drawing trend lines in an indicator’s subchart

We create trend lines with the DrwTrendLine.Create() method, which returns a reference to the line created (MultiCharts, 2014; PowerLanguage .NET Help, n.d.). That reference, when put in an ITrendLineObject interface variable, allows access to the line’s properties and methods. With those we can modify the line after it’s made, such as changing the trend line’s location or its visual appearance.

The DrwTrendLine.Create() method is overloaded, meaning we can use it in several ways (see Liberty & MacDonald, 2009). One version of this method requires two ChartPoint structs (for the line’s begin and end point) and a Boolean value, which indicates if the line should be drawn in the script’s subchart (when true) or not (false; the default behaviour) (PowerLanguage .NET Help, n.d.). So by using that version of DrwTrendLine.Create() we can draw trend lines in either the indicator’s subchart or on the data series that the indicator is applied to.

Example of trend lines in an indicator’s subchart

The example indicator added to a EUR/GBP chart looks like:

MultiCharts .NET trend lines in a subchart

Programmatically drawing trend lines in a subchart

This is achieved with the following code:

[RecoverDrawings(false)]
public class Example_TrendLineSubchartData : IndicatorObject
{
    public Example_TrendLineSubchartData(object _ctx) : base(_ctx) { }

    private IPlotObject closingPrice;
    private ITrendLineObject myTrendLine;

    protected override void Create()
    {
        closingPrice = AddPlot(new PlotAttributes(
            "Close", EPlotShapes.Line, Color.Black));
    }

    protected override void CalcBar()
    {
        closingPrice.Set(Bars.Close[0]);

        if (Bars.LastBarOnChart && myTrendLine == null)
        {
            // Create first trend line
            myTrendLine = DrwTrendLine.Create(
                new ChartPoint(Bars.FullSymbolData.Time[40],
                    Bars.FullSymbolData.Close[40]),
                new ChartPoint(Bars.Time[0],
                    Bars.Close[0]),
                true);

            myTrendLine.Color = Color.SpringGreen;
            myTrendLine.Size  = 3;
            myTrendLine.Style = ETLStyle.ToolDashed;

            // Second trend line
            myTrendLine = DrwTrendLine.Create(
                new ChartPoint(Bars.FullSymbolData.Time[15],
                    Bars.FullSymbolData.Close[15]),
                new ChartPoint(Bars.Time[0], 
                    Bars.Close[0]),
                true);

            myTrendLine.Color = Color.Tomato;
            myTrendLine.Size  = 2;
        }
    }
}

We first set the RecoverDrawings attribute set to false so that intra-bar generated drawings aren’t removed (MultiCharts, 2014). Then an IPlotObject variable named closingPrice and an ITrendLineObject variable (myTrendLine) are declared. These are used afterwards for the indicator’s plot and for changing the trend line, respectively.

Then in the Create() method, AddPlot() creates the indicator’s line with the PlotAttributes struct. This set’s the plot name to “Close” makes it a black (Color.Black) line (EPlotShapes.Line).

Drawing trend lines in an indicator’s subchart

Next is the CalcBar() method. In it we first call the plot’s Set() method to set it to the current bar’s price (Bars.Close[0]). An if statement then evaluates whether the current bar is the last (Bars.LastBarOnChart returns true then; PowerLanguage .NET Help, n.d.) and if the myTrendLine variable equals (==) null. This latter happens when this trend line reference variable doesn’t point to a trend line object on the chart (see Albahari & Albahari, 2012). In other words, when myTrendLine equals null, we haven’t associated it with an actual, created trend line yet – and so we first create a line when both conditions evaluate to true.

To draw a trend line we call DrwTrendLine.Create() with three arguments. The first two are ChartPoint structures with the line’s coordinates. The data of the line’s starting point is set to the time and close of 40 bars ago, which we retrieve here with the Bars.FullSymbolData property that allows for accessing any bar on the chart (see PowerLanguage .NET Help, n.d.). The trend line’s end point is set to the current bar’s time (Bars.Time[0]) and price (Bars.Close[0]). The third and last argument of DrwTrendLine.Create() is the true Boolean value that causes the line to be drawn in the indicator’s subchart.

After making this line, we change its visual appearance by setting its Color, Size, and Style properties through the myTrendLine variable. That makes this first line green with a size of 3.

The second trend line is made similar to the first, but this time drawn between the close of 15 bars ago and the current bar. Notice that we reuse the myTrendLine variable by assigning it the value returned by DrwTrendLine.Create(). We now cannot use this variable to access the first trend line anymore, but we can use myTrendLine to access the second trend line’s Color and Size properties.

See creating trend lines on different data series to learn more about drawing trend lines. We can also draw trend lines based on indicator values instead of price bar-based trend lines in the subchart, as we did in this article.

Summary

Drawing trend lines programmatically is done with DrwTrendLine.Create(), a method that has multiple versions. One overloaded version draws trend lines in an indicator’s subchart. For that the method requires two ChartPoint struct values for the line’s begin and end coordinates together with a Boolean value. When that true/false value is true, the line is drawn in the subchart; otherwise, with false (the default value) the trend line is created on the indicator’s data series.

Complete MultiCharts .NET indicator example

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

namespace PowerLanguage.Indicator
{
    [RecoverDrawings(false)]
    public class Example_TrendLineSubchartData : IndicatorObject
    {
        public Example_TrendLineSubchartData(object _ctx) : base(_ctx) { }

        private IPlotObject closingPrice;
        private ITrendLineObject myTrendLine;

        protected override void Create()
        {
            closingPrice = AddPlot(new PlotAttributes(
                "Close", EPlotShapes.Line, Color.Black));
        }

        protected override void CalcBar()
        {
            closingPrice.Set(Bars.Close[0]);

            if (Bars.LastBarOnChart && myTrendLine == null)
            {
                // Create first trend line
                myTrendLine = DrwTrendLine.Create(
                    new ChartPoint(Bars.FullSymbolData.Time[40],
                        Bars.FullSymbolData.Close[40]),
                    new ChartPoint(Bars.Time[0],
                        Bars.Close[0]),
                    true);

                myTrendLine.Color = Color.SpringGreen;
                myTrendLine.Size  = 3;
                myTrendLine.Style = ETLStyle.ToolDashed;

                // Second trend line
                myTrendLine = DrwTrendLine.Create(
                    new ChartPoint(Bars.FullSymbolData.Time[15],
                        Bars.FullSymbolData.Close[15]),
                    new ChartPoint(Bars.Time[0], 
                        Bars.Close[0]),
                    true);

                myTrendLine.Color = Color.Tomato;
                myTrendLine.Size  = 2;
            }
        }
    }
}

References

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

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