Trend lines can be drawn on price data or created on indicator values programmatically. But what if we manually want to specify a line’s begin and end point in MultiCharts .NET?

Drawing trend lines with mouse clicks in MultiCharts .NET

The DrwTrendLine.Create() method draws trend lines and returns a reference to the line just created (MultiCharts, 2014; PowerLanguage .NET Help, n.d.). When that returned value is assigned to an ITrendLineObject interface variable, we can access the line’s properties and methods through the variable. That way we can change or retrieve the trend line’s current settings.

Often DrwTrendLine.Create() will draw a line between two programmatically determined points, such as with an instrument’s opening range or between recent highs and lows. But we can also draw trend lines between chart locations where we clicked with the mouse.

To make that possible, we need to set the MouseEvents attribute to true and implement the OnMouseEvent() method. With that latter we programmatically handle how the mouse clicks should be processed (see PowerLanguage .NET Help, n.d.).

Trend lines made with mouse clicks in MultiCharts .NET

When we add the example indicator to an empty E-mini NASDAQ 100 chart, nothing happens yet:

Drawing a trend line with mouse clicks - before

But when we click a few times on the chart while holding the Control or Shift key down, the script draws trend lines like this:

Drawing a trend line with mouse clicks - after

Drawing trend lines programmatically with mouse clicks

The example’s code is the following:

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

    protected override void CalcBar() { }

    private ChartPoint beginPoint, endPoint;

    protected override void OnMouseEvent(MouseClickArgs click)
    {
        // A click with Control stores the line's begin coordinate
        if (click.keys == Keys.Control)
        {
            beginPoint = click.point;
        }
        // A click with Shift draws the trend line
        else if (click.keys == Keys.Shift && beginPoint.Price > 0)
        {
            endPoint = click.point;

            ITrendLineObject mouseClickLine = 
                DrwTrendLine.Create(beginPoint, endPoint);

            // Adjust trend line's appearance
            if ((mouseClickLine.End.Price - 
                mouseClickLine.Begin.Price) > 0)
                mouseClickLine.Color = Color.LimeGreen;
            else
                mouseClickLine.Color = Color.Red;

            mouseClickLine.Size = 2;
        }
    }
}

Three attributes are added to the indicator to begin with. RecoverDrawings set to false makes intra-bar generated drawings persistent (MultiCharts, 2014). With MouseEvents set to true we enable mouse click processing, and SameAsSymbol set to true displays the indicator on the data series.

Then two ChartPoint struct variables (beginPoint and endPoint) are declared. We’ll later assign the mouse click’s location to them and draw the trend line between these two chart locations.

Using mouse clicks for a trend line’s starting point

In the OnMouseEvent() method we process the clicks and use the MouseClickArgs struct variable (named click here) to access the click’s data.

The if/else statement in this method begins with evaluating whether the keyboard key that was pressed during the click (click.keys) equals (==) the control key (Keys.Control). That Keys enumeration is located in the System.Windows.Forms namespace, which we added with a using directive in the top of the indicator’s source code (see full code example below) (Sharp, 2013).

When the Control key was indeed held down during the mouse click, the beginPoint variable is assigned arg.point’s value, which is a ChartPoint struct variable that holds mouse click coordinates (see PowerLanguage .NET Help, n.d.). This way a click with Control sets the starting point for the trend line we’re going to draw.

Setting the end coordinate and drawing the trend line

The line’s ending point is determined in the if/else statement’s else if part. Two conditions needs to be true before this code block is executed. These are that the key held down during the click is the Shift key (Keys.Shift) and that the price coordinate of the begin point (beginPoint.Price) is greater than (>) 0. With this latter we ensure that we don’t draw a trend line without the begin coordinate being assigned a valid chart location.

When both conditions evaluate to true, the endPoint variable is assigned the chart location of the current click (click.point). We then call the DrwTrendLine.Create() method and pass in the beginPoint and endPoint variables to draw a trend line between these two mouse click locations. The value returned by this method is stored in an ITrendLineObject variable named mouseClickLine.

We then use that mouseClickLine variable to access the trend line’s properties. An if/else statement checks if the line has an upward slope by subtracting the line’s begin point (mouseClickLine.Begin.Price) from its ending point (mouseClickLine.End.Price). With trend lines drawn from left to right, this difference is positive for upward pointing lines and so the line’s Color property is set to green. Otherwise, we set the line’s colour to red. Finally, to make the trend line more visible its visual appearance is also changed by setting its Size property to 2.

Other MultiCharts .NET examples of trend lines and mouse clicks are using mouse clicks to lock/unlock a trend line and create ‘snappy’ trend lines on indicator values with mouse clicks.

Summary

The DrwTrendLine.Create() method draws trend lines between two ChartPoint chart coordinates. In the OnMouseEvent() method, the MouseClickArgs struct’s click variable returns a ChartPoint value with the coordinates of the mouse click on the chart. We can use that chart location as one of the two points to draw a trend line between.

Complete MultiCharts .NET indicator example

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

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

        protected override void CalcBar() { }

        private ChartPoint beginPoint, endPoint;

        protected override void OnMouseEvent(MouseClickArgs click)
        {
            // A click with Control stores the line's begin coordinate
            if (click.keys == Keys.Control)
            {
                beginPoint = click.point;
            }
            // A click with Shift draws the trend line
            else if (click.keys == Keys.Shift && beginPoint.Price > 0)
            {
                endPoint = click.point;

                ITrendLineObject mouseClickLine = 
                    DrwTrendLine.Create(beginPoint, endPoint);

                // Adjust trend line's appearance
                if ((mouseClickLine.End.Price - 
                    mouseClickLine.Begin.Price) > 0)
                    mouseClickLine.Color = Color.LimeGreen;
                else
                    mouseClickLine.Color = Color.Red;

                mouseClickLine.Size = 2;
            }
        }
    }
}

References

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

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