🚀 AI One-Click Generation of mql4 Strategy Code

Build Interactive Mql4 Tools: From Mouse Clicks to Chart Coordinates

mql4 | Published on: 2025/12/4
The following content is generated by EasyQuant .

Problem Description

How do I get the price and time from a mouse click on the chart?

Solution

To get the price and time from a mouse click in MQL4, you must utilize the OnChartEvent function to detect the click and the ChartXYToTimePrice function to convert the pixel coordinates (X, Y) into chart coordinates (Time, Price).

Key Functions Used

  1. OnChartEvent: The event handler that captures user interactions. We specifically look for the CHARTEVENT_CLICK event ID.
  2. lparam: In a click event, this parameter holds the X coordinate (pixels).
  3. dparam: In a click event, this parameter holds the Y coordinate (pixels).
  4. ChartXYToTimePrice: Converts the X and Y pixel coordinates into a datetime and double (price).

MQL4 Implementation

Here is a complete Expert Advisor (EA) script. When you attach this to a chart and click anywhere, it will print the coordinates in the "Experts" tab and draw a crosshair at that location.

//+------------------------------------------------------------------+
//|                                       MouseClickPriceTime.mq4    |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Enable chart events to detect mouse clicks
   ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
   Print("Click anywhere on the chart to get Price and Time.");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up objects created by the EA
   ObjectDelete(0, "ClickVLine");
   ObjectDelete(0, "ClickHLine");
}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   // Check if the event is a mouse click
   if(id == CHARTEVENT_CLICK)
   {
      // 1. Extract X and Y coordinates from event parameters
      int x = (int)lparam;
      int y = (int)dparam;
      
      // 2. Prepare variables to store the result
      datetime clicked_time;
      double clicked_price;
      int window = 0; // 0 is the main chart window
      
      // 3. Convert X/Y pixels to Time/Price
      if(ChartXYToTimePrice(0, x, y, window, clicked_time, clicked_price))
      {
         // 4. Output the results to the Experts log
         Print("Mouse Click Detected:");
         Print("   X: ", x, " Y: ", y);
         Print("   Time: ", TimeToString(clicked_time));
         Print("   Price: ", DoubleToString(clicked_price, _Digits));
         
         // 5. Visual Feedback: Draw a crosshair at the clicked point
         DrawCrosshair(clicked_time, clicked_price);
      }
      else
      {
         Print("Failed to convert coordinates. Error: ", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+
//| Helper function to draw visual lines on click                    |
//+------------------------------------------------------------------+
void DrawCrosshair(datetime time, double price)
{
   // Create or Move Vertical Line
   if(ObjectFind(0, "ClickVLine") == -1)
      ObjectCreate(0, "ClickVLine", OBJ_VLINE, 0, time, 0);
   else
      ObjectMove(0, "ClickVLine", 0, time, 0);
      
   // Set VLine properties
   ObjectSetInteger(0, "ClickVLine", OBJPROP_COLOR, clrRed);
   ObjectSetInteger(0, "ClickVLine", OBJPROP_STYLE, STYLE_DOT);

   // Create or Move Horizontal Line
   if(ObjectFind(0, "ClickHLine") == -1)
      ObjectCreate(0, "ClickHLine", OBJ_HLINE, 0, 0, price);
   else
      ObjectMove(0, "ClickHLine", 0, 0, price);
      
   // Set HLine properties
   ObjectSetInteger(0, "ClickHLine", OBJPROP_COLOR, clrRed);
   ObjectSetInteger(0, "ClickHLine", OBJPROP_STYLE, STYLE_DOT);
   
   // Force chart redraw to show changes immediately
   ChartRedraw(0);
}
//+------------------------------------------------------------------+

Detailed Explanation

  1. ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true): While CHARTEVENT_CLICK often works without this, enabling mouse move events ensures the chart is listening for detailed mouse interactions.
  2. id == CHARTEVENT_CLICK: This filter ensures the code only runs when you actually click the mouse, ignoring other events like key presses or object creation.
  3. ChartXYToTimePrice:
    • Input 1 (0): The Chart ID (0 means the current chart).
    • Input 2 (x): The horizontal pixel position (lparam).
    • Input 3 (y): The vertical pixel position (dparam).
    • Output 1 (window): Returns the subwindow number (0 for main chart, 1+ for indicator windows like RSI).
    • Output 2 (clicked_time): The variable where the function stores the calculated time.
    • Output 3 (clicked_price): The variable where the function stores the calculated price.

Common Issues

  • Subwindows: If you click in an indicator subwindow (like MACD), window will return a number greater than 0. The clicked_price will correspond to the indicator's value scale, not the chart's Bid/Ask price.
  • Empty Space: If you click to the right of the current price (in the future), clicked_time will return the theoretical time of that future bar.

Q&A

Q: Can I use this in a Custom Indicator instead of an Expert Advisor?
A: Yes, the OnChartEvent function works exactly the same way in Custom Indicators.

Q: Why does the price returned not match the current Bid or Ask?
A: ChartXYToTimePrice returns the price at the specific height of your mouse cursor. If you click at the top of the screen, it returns the high price visible on the scale; if you click at the bottom, it returns the low price. It does not snap to the current market price.

Q: How do I detect if the user clicked a specific object (like a button)?
A: Instead of CHARTEVENT_CLICK, you should check for CHARTEVENT_OBJECT_CLICK. In that case, the sparam parameter will contain the name of the object that was clicked.