Viewing the resource: Strategy Tester Buttons Trading Panel in MQL5

Strategy Tester Buttons Trading Panel in MQL5

Allan Munene Mutiiria 2025-06-26 10:12:30 89 Views
This MQL5 EA provides an interactive panel with adjustable lot sizes (0.03 default), stop loss/take ...

Introduction

Imagine commanding your trades with the precision of a mission control center, using an interactive panel to execute and manage orders with seamless efficiency. The Strategy Tester Buttons EA is your advanced trading control tool, designed to enhance manual trading on MetaTrader 5 with a customizable panel. It features buttons for adjusting lot sizes ("BTN_LOT", default "init_lot"=0.03), setting stop loss and take profit levels ("HL_SL", "HL_TP", default "sl_tp"=300 pips), executing buy/sell trades ("BTN_BUY", "BTN_SELL", "obj_Trade.Buy/Sell()"), and closing all positions ("BTN_CLOSE"). Traders can fine-tune stop loss and take profit lines visually in slow ("slow_pts"=10) or fast ("fast_pts"=100) increments, with confirmation buttons ("BTN_YES", "BTN_NO") to finalize or cancel trades. The panel, managed via "OnTick()" and "createBtn()", "createHL()", supports dynamic risk setting and instant position closure, making it ideal for traders seeking flexible manual control in volatile markets, requiring external signal strategies for entries.

This article is crafted with a professional, engaging, and seamless narrative, flowing like a well-calibrated trading control system, designed to inform and captivate readers. Tailored for both novice and experienced traders, we’ll dissect each code component with clear, precise explanations, as if guiding an apprentice commander through a trade execution project. With vivid examples—like trading EURUSD—and a polished tone, we’ll explore how the EA initializes, creates the panel, handles interactions, executes trades, and ensures cleanup. Using a precision trading control metaphor, this guide will illuminate the code’s technical rigor, empowering you to manage trades with confidence. Let’s activate the system and begin this trading expedition!

Strategy Blueprint

Let’s outline the EA’s trading control framework, like drafting specifications for a command console:

  • Panel Creation: Displays a panel with buttons for lot size adjustment ("BTN_LOT", "BTN_P", "BTN_M"), buy/sell execution ("BTN_BUY", "BTN_SELL"), position closure ("BTN_CLOSE"), and stop loss/take profit setting ("BTN_SL", "BTN_TP", etc.) using "createBtn()", "createHL()".

  • Lot Size Adjustment: Increments/decrements lot sizes ("GetValue(BTN_LOT)") by the symbol’s step ("SYMBOL_VOLUME_STEP", "BTN_P", "BTN_M") with validation.

  • Risk Setting: Sets visual stop loss/take profit lines ("HL_SL", "HL_TP") adjustable in slow/fast steps ("slow_pts", "fast_pts") with confirmation ("BTN_YES", "BTN_NO").

  • Trade Execution: Opens buy/sell trades ("obj_Trade.Buy/Sell()") with user-defined lot and risk levels, or closes all positions ("closeAllPositions()") via a panic button.

  • Execution: Processes interactions on each tick ("OnTick()") with price data from "SymbolInfoDouble()", state management via "GetState()", "GetValue()", "GetValueHL()".

  • Enhancements: Adding a magic number, signal-based entries, or error logging could improve control and reliability. This framework streamlines manual trading with precision, offering a flexible interface for order management.

Code Implementation

Let’s step into the trading control command center and dissect the MQL5 code that powers this Strategy Tester Buttons EA. We’ll guide you through each phase like expert commanders, ensuring the narrative flows seamlessly with professional clarity and engaging precision that captivates readers. We’ll cover initialization, panel creation, interaction handling, trade execution, and cleanup, with detailed explanations and examples—like trading EURUSD—to make it accessible for beginners. Each phase will build on the last, crafting a cohesive technical narrative that transforms code into a compelling trading control project. Let’s power up the system and begin!

Phase 1: Constructing the Framework—Initialization

We start by building the control system, initializing the interactive panel.

//+------------------------------------------------------------------+
//|                                      STRATEGY TESTER BUTTONS.mq5 |
//|                           Copyright 2025, Allan Munene Mutiiria. |
//|                                   https://t.me/Forex_Algo_Trader |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Allan Munene Mutiiria."
#property link      "https://t.me/Forex_Algo_Trader"
#property version   "1.00"

#include <Trade/Trade.mqh>
CTrade obj_Trade;

bool tradeInAction = false;
bool isHaveTradeLevels = false;

#define BTN_BUY "BTN BUY"
#define BTN_SELL "BTN SELL"
#define BTN_CLOSE "BTN CLOSE"
#define BTN_LOT "BTN LOT"
#define BTN_P "BTN P"
#define BTN_M "BTN M"

#define BTN_SL "BTN SL"
#define BTN_SL1M "BTN SL1M"
#define BTN_SL2M "BTN SL2M"
#define BTN_SL2P "BTN SL2P"
#define BTN_SL1P "BTN SL1P"

#define BTN_TP "BTN TP"
#define BTN_TP1M "BTN TP1M"
#define BTN_TP2M "BTN TP2M"
#define BTN_TP2P "BTN TP2P"
#define BTN_TP1P "BTN TP1P"

#define HL_SL "HL SL"
#define HL_TP "HL TP"

#define BTN_YES "BTN YES"
#define BTN_NO "BTN NO"
#define BTN_IDLE "BTN IDLE"

input double init_lot = 0.03;
input int sl_tp = 300;
input int slow_pts = 10;
input int fast_pts = 100;

int GetState(string Name){return (int)ObjectGetInteger(0,Name,OBJPROP_STATE);}
string GetValue(string Name){return ObjectGetString(0,Name,OBJPROP_TEXT);}
double GetValueHL(string Name){return NormalizeDouble(ObjectGetDouble(0,Name,OBJPROP_PRICE),_Digits);}

int OnInit(){
   createBtn(BTN_P,150,45,40,25,CharToString(217),15,clrBlack,clrWhite,clrGray,"Wingdings");
   createBtn(BTN_LOT,190,45,60,25,string(init_lot),12,clrWhite,clrNONE,clrWhite);
   createBtn(BTN_M,250,45,40,25,CharToString(218),15,clrBlack,clrWhite,clrGray,"Wingdings");
   createBtn(BTN_BUY,110,70,110,30,"BUY",15,clrWhite,clrGreen,clrWhite);
   createBtn(BTN_SELL,220,70,110,30,"SELL",15,clrWhite,clrRed,clrWhite);
   createBtn(BTN_CLOSE,110,100,220,30,"PANIC BUTTON (X)",15,clrWhite,clrBlack,clrWhite);
   return(INIT_SUCCEEDED);
}

The system begins with the #property header, establishing copyright and contact details, like calibrating a trading control system’s core. The "OnInit()" function initializes the setup, including "Trade/Trade.mqh" for trading via "obj_Trade". It defines constants for button names ("BTN_BUY", "BTN_SELL", etc.), horizontal lines ("HL_SL", "HL_TP"), and inputs ("init_lot"=0.03, "sl_tp"=300, "slow_pts"=10, "fast_pts"=100). It creates six initial buttons using "createBtn()": lot size adjusters ("BTN_P", "BTN_M", Wingdings arrows), lot display ("BTN_LOT"), buy ("BTN_BUY", green), sell ("BTN_SELL", red), and panic close ("BTN_CLOSE", black). State variables ("tradeInAction", "isHaveTradeLevels") and helper functions ("GetState()", "GetValue()", "GetValueHL()") manage interactions. Returning INIT_SUCCEEDED signals, “System is ready, let’s control trades!” This primes the EA for manual trading, like a command console poised for action.

Phase 2: Designing the Interface—Creating Trade Levels

When a trade is initiated, we create additional buttons and lines for risk setting, like expanding a control panel.

void createTradeLevels(){
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   string level_Sl, level_TP;
   if (GetState(BTN_BUY)==true){
      level_Sl = string(Bid-sl_tp*_Point);
      level_TP = string(Bid+sl_tp*_Point);
   }
   else if (GetState(BTN_SELL)==true){
      level_Sl = string(Ask+sl_tp*_Point);
      level_TP = string(Ask-sl_tp*_Point);
   }
   createHL(HL_SL,0,double(level_Sl),clrRed);
   createHL(HL_TP,0,double(level_TP),clrLime);
   createBtn(BTN_SL,110,135,110,23,"SL: "+string(GetValueHL(HL_SL)),13,clrRed,clrWhite,clrRed);
   createBtn(BTN_TP,220,135,110,23,"TP: "+string(GetValueHL(HL_TP)),13,clrGreen,clrWhite,clrGreen);
   createBtn(BTN_SL1M,110,158,27,20,"-",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_SL2M,137,158,27,20,"--",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_SL2P,164,158,27,20,"++",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_SL1P,191,158,27,20,"+",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_TP1P,222,158,27,20,"+",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_TP2P,249,158,27,20,"++",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_TP2M,276,158,27,20,"--",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_TP1M,303,158,27,20,"-",17,clrBlack,clrWhite,clrGray);
   createBtn(BTN_YES,110,178,70,30,CharToString(254),20,clrWhite,clrDarkGreen,clrWhite,"Wingdings");
   createBtn(BTN_NO,260,178,70,30,CharToString(253),20,clrWhite,clrDarkRed,clrWhite,"Wingdings");
   createBtn(BTN_IDLE,180,183,80,25,CharToString(40),20,clrWhite,clrBlack,clrWhite,"Wingdings");
}

void createBtn(string objName,int xD, int yD,int xS,int yS,string txt,
               int fs=13,color clrTxt=clrWhite,color clrBg=clrBlack,
               color clrBd=clrBlack,string font="Calibri"){
   ObjectCreate(0,objName,OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,objName,OBJPROP_XDISTANCE,xD);
   ObjectSetInteger(0,objName,OBJPROP_YDISTANCE,yD);
   ObjectSetInteger(0,objName,OBJPROP_XSIZE,xS);
   ObjectSetInteger(0,objName,OBJPROP_YSIZE,yS);
   ObjectSetInteger(0,objName,OBJPROP_CORNER,CORNER_LEFT_UPPER);
   ObjectSetString(0,objName,OBJPROP_TEXT,txt);
   ObjectSetInteger(0,objName,OBJPROP_FONTSIZE,fs);
   ObjectSetInteger(0,objName,OBJPROP_COLOR,clrTxt);
   ObjectSetInteger(0,objName,OBJPROP_BGCOLOR,clrBg);
   ObjectSetInteger(0,objName,OBJPROP_BORDER_COLOR,clrBd);
   ObjectSetString(0,objName,OBJPROP_FONT,font);
   ChartRedraw(0);
}

void createHL(string objName,datetime time1, double price1, color clr){
   if (ObjectFind(0,objName) < 0){
      ObjectCreate(0,objName,OBJ_HLINE,0,time1,price1);
      ObjectSetInteger(0,objName,OBJPROP_TIME,time1);
      ObjectSetDouble(0,objName,OBJPROP_PRICE,price1);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,objName,OBJPROP_STYLE,STYLE_DASHDOTDOT);
      ChartRedraw(0);
   }
}

In the interface design hub, "createTradeLevels()" is called when "BTN_BUY" or "BTN_SELL" is clicked ("GetState()", "tradeInAction"=true, "isHaveTradeLevels"=false). It fetches ask/bid prices ("SymbolInfoDouble()", "NormalizeDouble()") and sets stop loss ("level_Sl") and take profit ("level_TP") at ±300 pips ("sl_tp") from bid (buy) or ask (sell). It creates horizontal lines ("createHL()", "HL_SL", red; "HL_TP", lime) and buttons for stop loss adjustment ("BTN_SL", "BTN_SL1M/P", "BTN_SL2M/P", slow/fast increments), take profit adjustment ("BTN_TP", "BTN_TP1M/P", "BTN_TP2M/P"), and confirmation ("BTN_YES", green check; "BTN_NO", red cross; "BTN_IDLE", neutral). The "createBtn()" function uses "ObjectCreate()", "ObjectSetInteger()", "ObjectSetString()", and "ChartRedraw()"; "createHL()" uses "OBJ_HLINE". For example, on EURUSD H1, clicking “BUY” at bid=1.2005 creates SL at 1.1705 and TP at 1.2305, like expanding a command panel.

Phase 3: Handling Interactions—Processing User Inputs

With the panel active, we process user interactions to adjust settings and execute trades, like operating a control console.

void OnTick(){
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   if (GetState(BTN_BUY)==true || GetState(BTN_SELL)==true){
      tradeInAction = true;
      if (!isHaveTradeLevels){
         createTradeLevels();
         isHaveTradeLevels = true;
      }
      if (tradeInAction){
         if (GetState(BTN_SL1M)){
            ObjectSetDouble(0,HL_SL,OBJPROP_PRICE,GetValueHL(HL_SL)-slow_pts*_Point);
            ObjectSetString(0,BTN_SL,OBJPROP_TEXT,"SL: "+string(GetValueHL(HL_SL)));
            ObjectSetInteger(0,BTN_SL1M,OBJPROP_STATE,false);
            ChartRedraw(0);
         }
         // ... (similar logic for BTN_SL2M, BTN_SL2P, BTN_SL1P, BTN_TP1M, BTN_TP2M, BTN_TP1P, BTN_TP2P)
         if (GetState(BTN_BUY) && GetState(BTN_YES)){
            obj_Trade.Buy(double(GetValue(BTN_LOT)),_Symbol,Ask,GetValueHL(HL_SL),GetValueHL(HL_TP));
            DeleteObjects_SLTP();
            isHaveTradeLevels = false;
            tradeInAction = false;
            ObjectSetInteger(0,BTN_YES,OBJPROP_STATE,false);
            ObjectSetInteger(0,BTN_BUY,OBJPROP_STATE,false);
            ChartRedraw(0);
         }
         else if (GetState(BTN_SELL) && GetState(BTN_YES)){
            obj_Trade.Sell(double(GetValue(BTN_LOT)),_Symbol,Bid,GetValueHL(HL_SL),GetValueHL(HL_TP));
            DeleteObjects_SLTP();
            isHaveTradeLevels = false;
            tradeInAction = false;
            ObjectSetInteger(0,BTN_YES,OBJPROP_STATE,false);
            ObjectSetInteger(0,BTN_SELL,OBJPROP_STATE,false);
            ChartRedraw(0);
         }
         else if (GetState(BTN_NO)){
            DeleteObjects_SLTP();
            isHaveTradeLevels = false;
            tradeInAction = false;
            ObjectSetInteger(0,BTN_NO,OBJPROP_STATE,false);
            ObjectSetInteger(0,BTN_BUY,OBJPROP_STATE,false);
            ObjectSetInteger(0,BTN_SELL,OBJPROP_STATE,false);
            ChartRedraw(0);
         }
      }
   }
   if (GetState(BTN_P)==true){
      double newLot = (double)GetValue(BTN_LOT);
      double lotStep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
      newLot += lotStep;
      newLot = NormalizeDouble(newLot,2);
      newLot = newLot > 0.11 ? lotStep : newLot;
      ObjectSetString(0,BTN_LOT,OBJPROP_TEXT,string(newLot));
      ObjectSetInteger(0,BTN_P,OBJPROP_STATE,false);
      ChartRedraw(0);
   }
   if (GetState(BTN_M)==true){
      double newLot = (double)GetValue(BTN_LOT);
      double lotStep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
      newLot -= lotStep;
      newLot = NormalizeDouble(newLot,2);
      newLot = newLot <= 0.00 ? lotStep : newLot;
      ObjectSetString(0,BTN_LOT,OBJPROP_TEXT,string(newLot));
      ObjectSetInteger(0,BTN_M,OBJPROP_STATE,false);
      ChartRedraw(0);
   }
}

In the interaction hub, "OnTick()" processes button clicks. Clicking "BTN_BUY" or "BTN_SELL" sets "tradeInAction"=true and calls "createTradeLevels()" if "isHaveTradeLevels"=false. Stop loss adjustments ("BTN_SL1M/P", "BTN_SL2M/P") move the SL line ("HL_SL", "ObjectSetDouble()", "GetValueHL()") by ±10 or ±100 pips, updating "BTN_SL" text ("ObjectSetString()") and resetting button state ("OBJPROP_STATE", "ChartRedraw()"). Take profit adjustments ("BTN_TP1M/P", "BTN_TP2M/P") work similarly. Clicking "BTN_YES" with "BTN_BUY" opens a buy ("obj_Trade.Buy()") at ask ("Ask") with user-defined lot size ("GetValue(BTN_LOT)") and SL/TP ("GetValueHL()"), clearing levels ("DeleteObjects_SLTP()") and resetting states. "BTN_SELL" with "BTN_YES" opens a sell. "BTN_NO" cancels the trade, clearing levels. Lot size adjusts via "BTN_P"/"BTN_M", incrementing/decrementing by "SYMBOL_VOLUME_STEP", capped at 0.01–0.11 ("NormalizeDouble()", "ObjectSetString()"). For example, on EURUSD H1, adjusting SL to 1.1725 and clicking “YES” opens a buy at 1.2007 with SL=1.1725, TP=1.2307, like executing a precise command.

Phase 4: Executing Trades and Closures—Managing Orders

With interactions processed, we execute trades or close positions, like launching or aborting missions.

void closeAllPositions(){
   for (int i=PositionsTotal()-1; i>=0; i--){
      ulong ticket = PositionGetTicket(i);
      if (ticket > 0){
         if (PositionSelectByTicket(ticket)){
            if (PositionGetString(POSITION_SYMBOL)==_Symbol){
               obj_Trade.PositionClose(ticket);
            }
         }
      }
   }
}

void DeleteObjects_SLTP(){
   ObjectDelete(0,HL_SL);
   ObjectDelete(0,HL_TP);
   ObjectDelete(0,BTN_SL);
   ObjectDelete(0,BTN_TP);
   ObjectDelete(0,BTN_SL1M);
   ObjectDelete(0,BTN_SL2M);
   ObjectDelete(0,BTN_SL1P);
   ObjectDelete(0,BTN_SL2P);
   ObjectDelete(0,BTN_TP1M);
   ObjectDelete(0,BTN_TP2M);
   ObjectDelete(0,BTN_TP1P);
   ObjectDelete(0,BTN_TP2P);
   ObjectDelete(0,BTN_YES);
   ObjectDelete(0,BTN_NO);
   ObjectDelete(0,BTN_IDLE);
   ChartRedraw(0);
}

In the execution hub, "obj_Trade.Buy/Sell()" opens trades with user-defined parameters (lot, SL, TP). The "closeAllPositions()" function, triggered by "BTN_CLOSE", loops through positions ("PositionsTotal()", "PositionGetTicket()") and closes those matching the symbol ("PositionGetString()", "_Symbol", "obj_Trade.PositionClose()"). The "DeleteObjects_SLTP()" function removes all risk-setting objects ("ObjectDelete()") after trade execution or cancellation. For example, on EURUSD, clicking “PANIC BUTTON (X)” closes all positions, like aborting active missions.

Phase 5: Shutting Down the System—Cleaning Up Resources

As our expedition concludes, we shut down the system, ensuring resources are cleared.

void OnDeinit(const int reason){
}

In the shutdown control room, "OnDeinit()" is empty, leaving buttons and lines on the chart, like an active command console. Adding cleanup would ensure a clean slate:

ObjectsDeleteAll(0, -1, -1);

This would remove all objects ("ObjectsDeleteAll()") like "BTN_BUY", "HL_SL", ensuring a clean chart, ready for the next task.

Why This EA is a Trading Control Triumph

The Strategy Tester Buttons EA is a trading control triumph, streamlining manual order execution with precision, like a master-crafted command console. Its interactive panel ("createBtn()", "createHL()") and robust risk management ("GetValueHL()", "BTN_YES") offer flexibility, with potential for magic numbers or signal integration. Picture opening a 0.03-lot EURUSD buy at 1.2007 with custom SL/TP—strategic brilliance! Beginners will value the intuitive interface, while experts can enhance its functionality, making it essential for manual traders seeking precise control.

Putting It All Together

To deploy this EA:

  1. Open MetaEditor in MetaTrader 5, like entering your trading control command center.

  2. Copy the code, compile with F5, and verify no errors—no commander wants a faulty console!

  3. Attach the EA to your chart and interact with the panel to adjust lot sizes, set SL/TP, and execute trades.

  4. Monitor trades and panel interactions, as no specific logging is implemented, like control diagnostics.

  5. Test on a demo account first—real capital deserves a trial run!

Conclusion

We’ve engineered a Strategy Tester Buttons system that streamlines manual trading with precision, like a master-crafted command console. This MQL5 code is your strategic tool, brought to life with a seamless, professional narrative packed with clear explanations and vivid examples to fuel your trading confidence. Whether you’re a novice trader or a seasoned market commander, this EA empowers you to execute orders with ease. Ready to command? Watch our video guide on the website for a step-by-step creation process. Now, control your trading with precision! 🔍

Disclaimer: Trading is like navigating complex markets—challenging and risky. Losses can exceed deposits. Test strategies on a demo account before going live.

Disclaimer: The ideas and strategies presented in this resource are solely those of the author and are intended for informational and educational purposes only. They do not constitute financial advice, and past performance is not indicative of future results. All materials, including but not limited to text, images, files, and any downloadable content, are protected by copyright and intellectual property laws and are the exclusive property of Forex Algo-Trader or its licensors. Reproduction, distribution, modification, or commercial use of these materials without prior written consent from Forex Algo-Trader is strictly prohibited and may result in legal action. Users are advised to exercise extreme caution, perform thorough independent research, and consult with qualified financial professionals before implementing any trading strategies or decisions based on this resource, as trading in financial markets involves significant risk of loss.

Recent Comments

Go to discussion to Comment or View other Comments

No comments yet. Be the first to comment!