🚀 AI One-Click Generation of mql4 Strategy Code

How to Build an Interactive On-Chart Control Panel for your Mql4 EA

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

Problem Description

I want to create a small panel on my chart with buttons to enable or disable my trading strategy. How can I do that?

Solution

To create a control panel on your chart in MQL4, you need to utilize the Event Handling system (OnChartEvent) to detect mouse clicks and Object Functions to draw the button.

Here is a complete, copy-paste ready solution. This Expert Advisor (EA) creates a button in the top-right corner. Clicking it toggles a boolean flag that allows or blocks the execution of your trading logic in OnTick.

MQL4 Code: Trading Control Panel

//+------------------------------------------------------------------+
//|                                            TradeControlPanel.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

//--- Input Parameters for Button Styling
input int      UI_Corner      = CORNER_RIGHT_UPPER; // Panel Corner
input int      UI_X_Offset    = 20;                 // X Distance
input int      UI_Y_Offset    = 20;                 // Y Distance
input int      UI_Width       = 120;                // Button Width
input int      UI_Height      = 40;                 // Button Height
input color    UI_ColorOn     = clrForestGreen;     // Color when Active
input color    UI_ColorOff    = clrFireBrick;       // Color when Inactive
input color    UI_TextColor   = clrWhite;           // Text Color
input int      UI_FontSize    = 10;                 // Font Size

//--- Global Variables
string g_ButtonName = "Btn_StrategyToggle";
bool   g_IsTradingEnabled = false; // Default state: Trading Disabled

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Create the button interface
   CreateButton();
   
   // Update the button visual state based on default
   UpdateButtonState();
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up: Remove the button when removing the EA
   ObjectDelete(0, g_ButtonName);
   Comment(""); // Clear chart comments
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Check if trading is enabled via the panel
   if(!g_IsTradingEnabled)
   {
      Comment("Strategy Status: STOPPED (Click button to enable)");
      return; // EXIT function immediately, do not execute strategy
   }

   // 2. If we are here, trading is enabled
   Comment("Strategy Status: RUNNING...");

   // --- INSERT YOUR STRATEGY LOGIC BELOW ---
   // Example:
   // if(SignalBuy()) OrderSend(...);
   
   // ----------------------------------------
}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//| Handles mouse clicks and object interactions                     |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   // Check if the event is a mouse click on an object
   if(id == CHARTEVENT_OBJECT_CLICK)
   {
      // Check if the clicked object is our button
      if(sparam == g_ButtonName)
      {
         // Toggle the trading state
         g_IsTradingEnabled = !g_IsTradingEnabled;
         
         // Update the visual appearance of the button
         UpdateButtonState();
         
         // Force chart redraw to make UI snappy
         ChartRedraw();
      }
   }
}

//+------------------------------------------------------------------+
//| Helper: Create the Button Object                                 |
//+------------------------------------------------------------------+
void CreateButton()
{
   // Check if object exists, if not create it
   if(ObjectFind(0, g_ButtonName) < 0)
   {
      ObjectCreate(0, g_ButtonName, OBJ_BUTTON, 0, 0, 0);
   }
   
   // Set Button Properties
   ObjectSetInteger(0, g_ButtonName, OBJPROP_CORNER, UI_Corner);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_XDISTANCE, UI_X_Offset);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_YDISTANCE, UI_Y_Offset);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_XSIZE, UI_Width);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_YSIZE, UI_Height);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_FONTSIZE, UI_FontSize);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_COLOR, UI_TextColor);
   ObjectSetString(0, g_ButtonName, OBJPROP_FONT, "Arial");
   
   // Ensure the button stays pressed/unpressed correctly
   ObjectSetInteger(0, g_ButtonName, OBJPROP_STATE, false); 
   ObjectSetInteger(0, g_ButtonName, OBJPROP_SELECTABLE, false);
   ObjectSetInteger(0, g_ButtonName, OBJPROP_HIDDEN, true); // Hide from object list
   ObjectSetInteger(0, g_ButtonName, OBJPROP_ZORDER, 10);   // Bring to front
}

//+------------------------------------------------------------------+
//| Helper: Update Button Text and Color                             |
//+------------------------------------------------------------------+
void UpdateButtonState()
{
   if(g_IsTradingEnabled)
   {
      // State: ON
      ObjectSetString(0, g_ButtonName, OBJPROP_TEXT, "Trading: ON");
      ObjectSetInteger(0, g_ButtonName, OBJPROP_BGCOLOR, UI_ColorOn);
      // Keep the button visually "depressed" if you prefer, or flat
      ObjectSetInteger(0, g_ButtonName, OBJPROP_STATE, true); 
   }
   else
   {
      // State: OFF
      ObjectSetString(0, g_ButtonName, OBJPROP_TEXT, "Trading: OFF");
      ObjectSetInteger(0, g_ButtonName, OBJPROP_BGCOLOR, UI_ColorOff);
      ObjectSetInteger(0, g_ButtonName, OBJPROP_STATE, false);
   }
}

How It Works

  1. OnInit(): Calls CreateButton() to draw an OBJ_BUTTON on the chart. It sets the initial state (Disabled by default in this code for safety).
  2. OnChartEvent(): This is the critical function. It listens for CHARTEVENT_OBJECT_CLICK. If the object clicked matches our button's name (g_ButtonName), it toggles the boolean variable g_IsTradingEnabled from true to false (or vice versa).
  3. UpdateButtonState(): Changes the button's background color (Green/Red) and text ("Trading: ON"/"Trading: OFF") to reflect the current state.
  4. OnTick(): This is where your strategy lives. The very first line checks if(!g_IsTradingEnabled) return;. If the button is set to OFF, the code stops there, preventing any trade logic from executing.

Integration Instructions

  1. Copy the code above into your MetaEditor.
  2. Locate the OnTick() function in the code.
  3. Paste your existing trading logic (indicator calculations, OrderSend functions, etc.) into the section marked // --- INSERT YOUR STRATEGY LOGIC BELOW ---.
  4. Compile and run. You will see a button in the top-right corner that controls the execution flow.

Q&A

Q: Can I add more buttons?
A: Yes. You would create unique names for each button (e.g., Btn_CloseAll, Btn_BuyOnly), create them in OnInit, and add additional if(sparam == "Btn_Name") checks inside OnChartEvent.

Q: Will the button state be saved if I restart the terminal?
A: No, in this specific code, the state resets to false (OFF) when the EA re-initializes. To save the state across restarts, you would need to use GlobalVariableSet and GlobalVariableGet (Terminal Global Variables) instead of a simple bool variable.

Q: Why does the button sometimes feel slow to react?
A: MQL4 charts update on ticks. We added ChartRedraw() inside the click event to force an immediate visual update, ensuring the button feels responsive even if the market is moving slowly.