Situation
You want to know more about working with mouse click locations in MultiCharts .NET.

Programming example

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

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

        protected override void CalcBar() { }

        protected override void OnMouseEvent(MouseClickArgs arg)
        {
            double midpointPrice    = (Environment.HighestScaleValue + Environment.LowestScaleValue) / 2;
            TimeSpan timeRangeChart = Environment.RightScreenTime - Environment.LeftScreenTime;
            DateTime midpointTime   = Environment.LeftScreenTime.AddSeconds(timeRangeChart.TotalSeconds / 2);

            bool upperPartOfChart  = (arg.point.Price >= midpointPrice) ? true : false;
            bool rightPartOfChart  = (arg.point.Time >= midpointTime) ? true : false;

            string clickPrice = arg.point.Price.ToString("F5");

            if (rightPartOfChart && upperPartOfChart)
            {
                Output.WriteLine("Mouse click price {0} is in the upper right.",
                    clickPrice);
            }
            else if (rightPartOfChart && !upperPartOfChart)
            {
                Output.WriteLine("Mouse click @ {0} is in the lower right.",
                    clickPrice);
            }
            else if (!rightPartOfChart && upperPartOfChart)
            {
                Output.WriteLine("Mouse click price {0} is in the upper left.",
                    clickPrice);
            }
            else if (!rightPartOfChart && !upperPartOfChart)
            {
                Output.WriteLine("Mouse click @ {0} is in the lower left.",
                    clickPrice);
            }
        }
    }
}

Output of the programming example

A price chart can be divided into four quadrants like the following (the green lines were added manually to highlight the four areas):

Example of chart quadrants in MultiCharts .NET

Clicking in any of these four areas generates the following output in the Output Window:

Mouse click price 1,32086 is in the upper right.
Mouse click price 1,32058 is in the upper right.
Mouse click @ 1,31853 is in the lower right.
Mouse click @ 1,31910 is in the lower left.
Mouse click price 1,32065 is in the upper left.
Mouse click @ 1,31874 is in the lower right.
Mouse click price 1,32075 is in the upper right.
Mouse click @ 1,31899 is in the lower left.
Mouse click price 1,32085 is in the upper left.
Mouse click @ 1,31868 is in the lower right.

Working with mouse clicks in MultiCharts .NET

One way to control MultiCharts .NET is by programmatically processing mouse clicks, which provide a range of possibilities, including submitting market orders, reloading price data, and turning a script on or off.

For more on mouse clicks, see working with mouse clicks and combining mouse clicks with keyboard keys.

Working with mouse clicks has two requirements:

  • The MouseEvents attribute needs to be set to true;
  • The OnMouseEvent() method, which programmatically deals with mouse clicks on the chart (see PowerLanguage .NET Help, n.d.), needs to be provided in the code.

Because each mouse click also contains information about its price chart location, different actions can be taken depending on the area in which the click occurred.

Chart information: time and price axes in MultiCharts .NET

Four read-only properties return the limits of the x and y-axis in MultiCharts .NET (PowerLanguage .NET Help, n.d.):

  • Environment.HighestScaleValue returns the highest bar price while Environment.LowestScaleValue returns the lowest bar price. Both return a double value for the currently visible chart area;
  • Environment.LeftScreenTime returns the DateTime of the first bar and Environment.RightScreenTime the DateTime of the last bar of the current chart view.

These four properties can be used to divide a price chart into multiple areas, like the four quadrants in the programming example.

MultiCharts .NET programming example

The example begins with setting two MultiCharts .NET attributes:

[MouseEvents(true), SameAsSymbol(true)]

MouseEvents set to true enables mouse click processing, while SameAsSymbol set to true plots the indicator on the main price chart.

Processing mouse clicks in MultiCharts .NET

The OnMouseEvent() method, which is executed with every mouse click on the chart, consists out of several parts: calculating the axis midpoints, determining the click location, and generate a message with the click location. Each part is discussed in turn below.

Calculating the midpoints of the price chart

First, the center of each axis is calculated:

double midpointPrice    = (Environment.HighestScaleValue + Environment.LowestScaleValue) / 2;
TimeSpan timeRangeChart = Environment.RightScreenTime - Environment.LeftScreenTime;
DateTime midpointTime   = Environment.LeftScreenTime.AddSeconds(timeRangeChart.TotalSeconds / 2);

To determine the middle of the price axis, the highest chart value (Environment.HighestScaleValue) is added to the lowest (Environment.LowestScaleValue) and divided by 2 (line 17).

Calculating the middle of the time axis is done in two steps. First, the time range between the time of the last bar (Environment.RightScreenTime) and the first bar (Environment.LeftScreenTime) is assigned to a TimeSpan structure (line 18).

The total seconds of this time interval (timeRangeChart.TotalSeconds) is then divided by 2 and added to the DateTime of the first bar with the AddSeconds() method to arrive at the middle of the time axis (line 19).

Determining a mouse click location in MultiCharts .NET

Then the mouse click location (arg.point) is evaluated against the calculated midpoints:

bool upperPartOfChart  = (arg.point.Price >= midpointPrice) ? true : false;
bool rightPartOfChart  = (arg.point.Time >= midpointTime) ? true : false;

string clickPrice = arg.point.Price.ToString("F5");

The upperPartOfChart Boolean variable is assigned the value of true when the price location of the mouse click (arg.point.Price) is greater than or equal to the calculated midpoint; otherwise, it is assigned false.

Similarly, the rightPartOfChart Boolean variable is assigned a value of true when the time location of the mouse click (arg.point.Time) is greater than or equal to the middle of the time axis (when it is not, it is assigned false).

Both Boolean variables have their values assigned with the conditional operator, which is a shorthand way to write an if-else statement (see Liberty & MacDonald, 2009).

The clickPrice string variable (line 24) holds the mouse click price location formatted to a string with 5 decimals (ToString("F5")).

The four quadrants of a price chart in MultiCharts .NET

The last part of the OnMouseEvent() method is a cascaded if-else statement to determine in which of the four areas the mouse click took place:

if (rightPartOfChart && upperPartOfChart)
{
    Output.WriteLine("Mouse click price {0} is in the upper right.",
        clickPrice);
}
else if (rightPartOfChart && !upperPartOfChart)
{
    Output.WriteLine("Mouse click @ {0} is in the lower right.",
        clickPrice);
}
else if (!rightPartOfChart && upperPartOfChart)
{
    Output.WriteLine("Mouse click price {0} is in the upper left.",
        clickPrice);
}
else if (!rightPartOfChart && !upperPartOfChart)
{
    Output.WriteLine("Mouse click @ {0} is in the lower left.",
        clickPrice);
}

These expressions with the conditional and operator (&&), and some with the logical not operator (!), are evaluated with the following logic: if the rightPartOfChart variable evaluates to true, the click occurred in one of the two right-hand areas; otherwise, it happened in a left area. And if upperPartOfChart is true, the click took place in one of the upper quadrants; otherwise, in one of the lower parts.

Each of the four chart areas can be identified with these two Boolean variables. Inside the body of the if statements, the Output.WriteLine() method is called with a string and substitution parameter to output a message to the Output Window.

Key points

  • Working with mouse events requires adding the MouseEvents attribute and implementing the OnMouseEvent() method;
  • Environment.HighestScaleValue returns the highest bar price of the current chart window, while Environment.LowestScaleValue returns the lowest bar price;
  • Environment.LeftScreenTime returns the DateTime of the first bar and Environment.RightScreenTime the DateTime of the last bar of the current chart view.
References

Liberty, J. & MacDonald, B. (2009). Learning C# 3.0: Master the Fundamentals of C# 3.0. Sebastopol, CA: O’Reilly Media.

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