🚀 AI One-Click Generation of mql4 Strategy Code

How to Create and Handle Clickable Buttons on Your Mql4 Chart (OBJ_BUTTON & OnChartEvent)

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

Problem Description

How can I add a clickable button to my chart that executes a specific action when pressed?

Solution

To add a clickable button in MQL4, you need to utilize the Event Handling system. Specifically, you will create an object of type OBJ_BUTTON and then listen for the CHARTEVENT_OBJECT_CLICK event within the OnChartEvent() function.

Here is the complete, copy-pasteable code for an Expert Advisor (EA) that creates a button. When clicked, it triggers a specific action (in this example, printing a message and sending an alert).

MQL4 Code: Clickable Button Example

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

//--- Input Parameters for Button Customization
input string   ButtonName  = "MyActionBtn";  // Unique Object Name
input string   ButtonText  = "Execute";      // Text on Button
input color    BtnColor    = clrCornflowerBlue; // Background Color
input color    TextColor   = clrWhite;       // Text Color
input int      BtnX        = 50;             // X Distance from corner
input int      BtnY        = 50;             // Y Distance from corner
input int      BtnWidth    = 100;            // Button Width
input int      BtnHeight   = 30;             // Button Height
input ENUM_BASE_CORNER BtnCorner = CORNER_LEFT_UPPER; // Chart Corner

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Create the button when the EA is loaded
   if(!CreateButton())
   {
      Print("Failed to create button!");
      return(INIT_FAILED);
   }
   
   // Force chart redraw to show button immediately
   ChartRedraw();
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Remove the button when the EA is removed to keep the chart clean
   ObjectDelete(0, ButtonName);
   ChartRedraw();
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Standard OnTick logic goes here
   // We don't need this for the button to work, as buttons use Event handling
}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//| This function listens for mouse clicks and keystrokes            |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   // Check if the event is an object click
   if(id == CHARTEVENT_OBJECT_CLICK)
   {
      // Check if the clicked object is OUR button
      if(sparam == ButtonName)
      {
         // --- EXECUTE SPECIFIC ACTION HERE ---
         ExecuteMyAction();
         
         // Reset the button state (unpress it)
         // If we don't do this, the button stays "pressed" in
         ObjectSetInteger(0, ButtonName, OBJPROP_STATE, false);
         
         // Redraw chart to reflect the unpressed state
         ChartRedraw();
      }
   }
}

//+------------------------------------------------------------------+
//| Custom Function: The Action to Perform                           |
//+------------------------------------------------------------------+
void ExecuteMyAction()
{
   // Example actions:
   Print("Button was clicked at: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS));
   Alert("Action Executed Successfully!");
   
   // You can place trade logic here, e.g., OrderSend(...)
}

//+------------------------------------------------------------------+
//| Helper Function: Create the Button Object                        |
//+------------------------------------------------------------------+
bool CreateButton()
{
   // Check if object already exists
   if(ObjectFind(0, ButtonName) >= 0)
   {
      // If it exists, delete it to recreate with new inputs
      ObjectDelete(0, ButtonName);
   }

   // Create the Object
   if(!ObjectCreate(0, ButtonName, OBJ_BUTTON, 0, 0, 0))
   {
      return(false);
   }

   // Set Properties
   ObjectSetInteger(0, ButtonName, OBJPROP_XDISTANCE, BtnX);
   ObjectSetInteger(0, ButtonName, OBJPROP_YDISTANCE, BtnY);
   ObjectSetInteger(0, ButtonName, OBJPROP_XSIZE, BtnWidth);
   ObjectSetInteger(0, ButtonName, OBJPROP_YSIZE, BtnHeight);
   ObjectSetInteger(0, ButtonName, OBJPROP_CORNER, BtnCorner);
   
   // Styling
   ObjectSetString(0, ButtonName, OBJPROP_TEXT, ButtonText);
   ObjectSetString(0, ButtonName, OBJPROP_FONT, "Arial");
   ObjectSetInteger(0, ButtonName, OBJPROP_FONTSIZE, 10);
   ObjectSetInteger(0, ButtonName, OBJPROP_COLOR, TextColor);
   ObjectSetInteger(0, ButtonName, OBJPROP_BGCOLOR, BtnColor);
   ObjectSetInteger(0, ButtonName, OBJPROP_BORDER_COLOR, clrBlack);
   
   // Interaction settings
   ObjectSetInteger(0, ButtonName, OBJPROP_BACK, false);     // Foreground
   ObjectSetInteger(0, ButtonName, OBJPROP_STATE, false);    // Default state: unpressed
   ObjectSetInteger(0, ButtonName, OBJPROP_SELECTABLE, false); // Prevent manual selection
   ObjectSetInteger(0, ButtonName, OBJPROP_ZORDER, 0);       // Z-Order

   return(true);
}

Key Components Explained

  1. OnInit(): This is where we call the CreateButton() helper function. It ensures the button appears as soon as you attach the EA to the chart.
  2. OnDeinit(): It is crucial to call ObjectDelete here. If you don't, the button will remain stuck on the chart even after you remove the EA.
  3. OnChartEvent(): This is the most important part.
    • id == CHARTEVENT_OBJECT_CLICK: Filters the events to only listen for mouse clicks on objects.
    • sparam == ButtonName: sparam contains the name of the object that was clicked. We verify it matches our button's name.
    • ObjectSetInteger(..., OBJPROP_STATE, false): Buttons in MT4 are "sticky" by default (toggle switches). To make it act like a momentary push-button, we programmatically set its state back to false (unpressed) immediately after the click.
  4. CreateButton(): This helper function handles the verbose setup of OBJ_BUTTON, setting coordinates, size, colors, and anchoring corners.

How to Use This

  1. Open MetaEditor in MT4.
  2. Create a new Expert Advisor.
  3. Paste the code above into the file, replacing everything.
  4. Compile the code (F7).
  5. Drag the EA onto a chart. You will see a blue button labeled "Execute".
  6. Click the button to see the Alert and Print log messages.

Q&A: MQL4 Chart Buttons

Q: Can I use this code in a Custom Indicator instead of an Expert Advisor?
A: Yes. The OnChartEvent function works exactly the same way in Indicators. However, ensure you manage OnDeinit carefully, as indicators are re-initialized more frequently than EAs.

Q: Why does the button stay pressed down when I click it?
A: OBJ_BUTTON has a boolean state (On/Off). If you want it to act like a trigger (click and release), you must manually reset the state in your code using ObjectSetInteger(0, ButtonName, OBJPROP_STATE, false); inside the click event.

Q: How do I place the button in the bottom-right corner?
A: Change the input parameter BtnCorner to CORNER_RIGHT_LOWER. The X and Y coordinates will then be calculated relative to that specific corner.

Q: Can I add an image to the button?
A: OBJ_BUTTON only supports text and background colors. If you need an image, you should use OBJ_BITMAP_LABEL. However, OBJ_BITMAP_LABEL requires handling CHARTEVENT_CLICK (coordinates) rather than CHARTEVENT_OBJECT_CLICK, or using OBJ_BITMAP_LABEL with OnChartEvent logic to detect if the click coordinates fall within the image boundaries.