Trend lines can be drawn on price data, on indicator values, and in an indicator’s subchart. But how can we draw a trend line into the future?

Drawing a MultiCharts .NET trend line into the future

The DrwTrendLine.Create() method draws trend lines and returns a reference to the line created (MultiCharts, 2014; PowerLanguage .NET Help, n.d.). With that reference assigned to an ITrendLineObject reference variable, the line’s properties and methods can be accessed through the variable. That allows for things like relocating a line, changing a line’s appearance, removing a line, and getting a line’s future price values possible.

A line’s begin and end points are specified with ChartPoint structs (see PowerLanguage .NET Help, n.d.). These chart coordinates consists out of a price with either a DateTime value or a bar number for the x-axis price coordinate. To draw trend lines into the future, one (or both) of the ChartPoint values passed into the DrwTrendLine.Create() method need to be based on a future price bar (that is, the ‘bars’ in the chart’s right margin).

Tip: When drawing a trend line with DrwTrendLine.Create(), both ChartPoint values need to hold DateTime values or bar numbers (MultiCharts Support, personal communication, March 25, 2015). That means a line with its begin point set to a bar number but its end point defined with DateTime won’t draw correctly.

Example: draw trend lines on future bars in MultiCharts .NET

When we add the example indicator to the chart, like this EUR/CAD chart, it draws three trend lines with coordinates in the chart’s right margin:

MultiCharts .NET trend line into the future - 1

These lines don’t have their location updated and so remain in place when new bars form:

MultiCharts .NET trend line into the future - 2

These lines are completely visible with enough empty space in the chart’s right margin. To change that setting, right-click on the chart and select ‘Format Window’. Then move to the ‘X - Time Scale’ tab and set the ‘Chart Shift’ option to the number of future, empty price bars to display (alternatively, click on the ‘Bars’ button to switch to a percentage chart shift):

MultiCharts .NET: configuring the chart shift option

Programmatically drawing trend lines into the future

Drawing those future trend lines is done as follows:

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

    private bool plotLinesOnce = false;

    protected override void CalcBar()
    {
        if (Bars.LastBarOnChart && !plotLinesOnce)
        {
            ChartPoint lineStart, lineEnd;

            // Create a future trend line with bar numbers
            lineStart = new ChartPoint(
                Bars.FullSymbolData.Current - 10 - ExecInfo.MaxBarsBack,
                Bars.High.Highest(10));

            lineEnd = new ChartPoint(
                Bars.FullSymbolData.Current + 20 - ExecInfo.MaxBarsBack,
                Bars.High.Highest(10));

            ITrendLineObject highLine = DrwTrendLine.Create(lineStart, lineEnd);

            highLine.Color = Color.ForestGreen;
            highLine.Size  = 2;

            // Create a future trend line with DateTime values
            lineStart = new ChartPoint(
                Bars.Time[10],
                Bars.Low.Lowest(10));

            lineEnd = new ChartPoint(
                Bars.Time[0].AddMinutes(20 * Bars.Info.Resolution.Size),
                Bars.Low.Lowest(10));

            ITrendLineObject lowLine = DrwTrendLine.Create(lineStart, lineEnd);

            lowLine.Color = Color.Red;
            lowLine.Size  = 2;

            // Create a line with both coordinates into the future
            ITrendLineObject futureLine = 
                DrwTrendLine.Create(lowLine.End, highLine.End);

            futureLine.Color = Color.Orange;
            futureLine.Size  = 2;
            futureLine.Style = ETLStyle.ToolDashed;

            plotLinesOnce = true;
        }
    }
}

We begin with defining two attributes. SameAsSymbol set to true displays the indicator on the data series and not in a separate subchart. RecoverDrawings set to false prevents automatic removal of intra-bar drawings (MultiCharts, 2014).

Then we declare a Boolean variable (plotLinesOnce) inside the indicator’s class and initialise it to false. We’ll use this variable later on to ensure the lines are only drawn once.

The CalcBar() method contains an if statement that evaluates two conditions. 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 condition is whether plotLinesOnce is false, tested here with the logical not operator (!). This operator evaluates to the opposite of a value (Liberty & MacDonald, 2009) and so when plotLinesOnce is false, !plotLinesOnce evaluates to true.

The if statement’s code is executed when both conditions evaluate to true. That code block begins with declaring two ChartPoint struct variables named lineStart and lineEnd. We’ll use these to temporarily hold the line’s begin and end coordinates before drawing the line.

Creating a future trend line based on bar numbers

The first trend line we draw has its time coordinates based on bar numbers. For that we first assign lineStart a new ChartPoint value based on two arguments. The first is the current bar number (Bars.FullSymbolData.Current) minus 10 (to start the line ten bars before the current) and corrected for the indicator’s MaxBarsBack value (ExecInfo.MaxBarsBack). That correction for the maximum number of bars a study will reference setting (MaxBarsBack) is needed to calculate the correct future bar number. The second argument is the price value, set to the highest high of the last 10 bars (Bars.High.Highest(10)). And so lineStart holds the chart coordinate of 10 bars ago with the highest high of the last 10 bars.

The lineEnd variable is also assigned a new ChartPoint value. This one is set to the current bar number (Bars.FullSymbolData.Current) plus 20 (to end the line twenty bars away from the current bar) and also corrected for the indicator’s MaxBarsBack value (ExecInfo.MaxBarsBack). The price coordinate is, just like with lineStart, set to the highest high of the last 10 bars.

With both ChartPoint coordinates defined, it’s time to draw a trend line between them. We first declare an ITrendLineObject variable named highLine and assign it the value returned by DrwTrendLine.Create(). Inside this method we pass the lineStart and lineEnd variables to define the line’s begin and end point.

After drawing the line, we use the highLine variable to change the line’s visual appearance by assigning new values to the Color and Size properties.

Creating a trend line into the future with DateTime values

The second trend line we draw uses DateTime values for its begin and end point. For that we set lineStart to a new ChartPoint struct initialised to the time of 10 bars ago (Bars.Time[10], which returns a DateTime value; see MultiCharts, 2014) and the lowest price of the last 10 bars. This latter value is returned by the Bars.Low.Lowest() extension method with the value of 10 passed in as an argument.

The lineEnd variable’s time coordinate is set to the date and time of 20 bars into the future. To determine that DateTime value, we first retrieve the current bar’s date and time (Bars.Time[0]) and then call its AddMinutes() method. That method adds the specified amount of minutes to the DateTime instance and returns a new DateTime value as the result (Albahari & Albahari, 2012). In it, we pass the value of 20 (for twenty bars into the future) and multiply this with the Bars.Info.Resolution.Size property. This property returns the chart’s resolution size, which in this example will be 15 since the script is added to a 15-minute time frame. After that we set the lineEnd variable’s price value to the lowest low of the last 10 bars, like we did with the lineStart ChartPoint variable.

When both ChartPoint variables have a new value we draw the second trend line. For that we call DrwTrendLine.Create() and pass in lineStart and lineEnd to define the line’s begin and end point. The value returned by this method is assigned to the lowLine variable of type ITrendLineObject. That variable is then used to change the line’s appearance by setting its Color and Size properties to different values.

Drawing a trend line with both coordinates into the future

The third line we draw is the vertical line that has both coordinates set to a future point. Because this line connects the end points of the two existing lines, we don’t need to define new ChartPoint structs but instead can retrieve these chart locations from the existing lines.

And so we call the DrwTrendLine.Create() method and pass in lowLine.End as the line’s starting point and highLine.End for the line’s ending point. These trend line End properties return the coordinates of that line’s end point as ChartPoint structs (see PowerLanguage .NET Help, n.d.).

The value returned by DrwTrendLine.Create() is assigned to the futureLine variable. We then use that variable to change the line’s visual look by setting its Color, Size, and Style properties to new values. After that the plotLinesOnce variable is set to true. Since this invalidates the CalcBar()’s if statement, the future trend lines are only drawn once.

For more on trend lines into the future, see extending trend lines, drawing horizontal trend lines and retrieving a trend line’s future price values.

Summary

The DrwTrendLine.Create() method draws trend lines between two ChartPoint coordinates. Not only previous but future DateTime values or bar numbers can also be defined in these coordinates. Drawing a trend line correctly requires that its begin and end point are either defined with DateTime values or bar numbers, but not a combination of both.

Complete MultiCharts .NET indicator example

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

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

        private bool plotLinesOnce = false;

        protected override void CalcBar()
        {
            if (Bars.LastBarOnChart && !plotLinesOnce)
            {
                ChartPoint lineStart, lineEnd;

                // Create a future trend line with bar numbers
                lineStart = new ChartPoint(
                    Bars.FullSymbolData.Current - 10 - ExecInfo.MaxBarsBack,
                    Bars.High.Highest(10));

                lineEnd = new ChartPoint(
                    Bars.FullSymbolData.Current + 20 - ExecInfo.MaxBarsBack,
                    Bars.High.Highest(10));

                ITrendLineObject highLine = DrwTrendLine.Create(lineStart, lineEnd);

                highLine.Color = Color.ForestGreen;
                highLine.Size  = 2;

                // Create a future trend line with DateTime values
                lineStart = new ChartPoint(
                    Bars.Time[10],
                    Bars.Low.Lowest(10));

                lineEnd = new ChartPoint(
                    Bars.Time[0].AddMinutes(20 * Bars.Info.Resolution.Size),
                    Bars.Low.Lowest(10));

                ITrendLineObject lowLine = DrwTrendLine.Create(lineStart, lineEnd);

                lowLine.Color = Color.Red;
                lowLine.Size  = 2;

                // Create a line with both coordinates into the future
                ITrendLineObject futureLine = 
                    DrwTrendLine.Create(lowLine.End, highLine.End);

                futureLine.Color = Color.Orange;
                futureLine.Size  = 2;
                futureLine.Style = ETLStyle.ToolDashed;

                plotLinesOnce = true;
            }
        }
    }
}

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