Viewing the resource: Propfirm Daily Drawdown Limiter in MQL5

Propfirm Daily Drawdown Limiter in MQL5

Allan Munene Mutiiria 2025-06-25 23:25:56 88 Views
This MQL5 EA monitors daily (5%) and total (12%) drawdowns, limiting trades to one position and halt...

Introduction

Picture managing your trading account with the precision of a vigilant risk controller, ensuring losses stay within strict boundaries to protect your capital. The Propfirm Daily Drawdown Limiter EA is your advanced risk management tool, designed to enforce disciplined trading by monitoring daily and overall account drawdowns. It tracks daily drawdown at 5% ("checkDailyProfit()", "daily_profit_or_drawdown") and total drawdown at 12% ("Acc_E()-initialBalance"), allowing only one trade at a time (0.1 lots, "obj_Trade.Buy()", "obj_Trade.Sell()") with a 70-pip stop loss and take profit ("ask-70*_Point", "ask+70*_Point"), using random signals ("MathRand()") for testing. A dynamic dashboard ("createText()") displays metrics like balance ("Acc_B()"), equity ("Acc_E()"), daily profit, and drawdown percentages, color-coded (green for gains, red for losses). If thresholds are breached, trading halts ("isTradeAllowed"=false). This EA suits prop firm traders or those needing strict risk controls in volatile markets.

This article is crafted with a professional, engaging, and seamless narrative, flowing like a well-calibrated risk management 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 risk manager through a capital protection project. With vivid examples—like monitoring EURUSD—and a polished tone, we’ll explore how the EA initializes, monitors drawdowns, limits trades, displays metrics, and ensures cleanup. Using a precision risk management metaphor, this guide will illuminate the code’s technical rigor, empowering you to safeguard your trading with confidence. Let’s activate the system and begin this risk management expedition!

Strategy Blueprint

Let’s outline the EA’s risk management framework, like drafting specifications for a capital protection system:

  • Drawdown Monitoring: Tracks daily drawdown (5%, "checkDailyProfit()", "daily_profit_or_drawdown") and total drawdown (12%, "Acc_E()-initialBalance") using "HistorySelect()", "HistoryDealGetDouble()".

  • Trade Limitation: Allows one trade (0.1 lots, "obj_Trade.Buy()", "obj_Trade.Sell()") with 70-pip stop loss/take profit, using random signals ("MathRand()") via "PositionsTotal()".

  • Dashboard Display: Shows balance, equity, daily profit, and drawdowns ("createText()") with color-coded updates (e.g., "clrLime" for gains, "clrRed" for losses).

  • Trading Halt: Disables trading ("isTradeAllowed"=false) if thresholds are hit, resetting daily ("dayTime", "dayBalance").

  • Execution: Processes drawdowns and trades on new bars ("iBars()", "totalBars") with "OnTick()".

  • Enhancements: Adding robust entry signals or configurable thresholds could improve applicability. This framework enforces strict risk control with precision, ensuring compliance with drawdown limits.

Code Implementation

Let’s step into the risk management control room and dissect the MQL5 code that powers this Propfirm Daily Drawdown Limiter EA. We’ll guide you through each phase like expert risk managers, ensuring the narrative flows seamlessly with professional clarity and engaging precision that captivates readers. We’ll cover initialization, drawdown monitoring, trade execution, dashboard display, and cleanup, with detailed explanations and examples—like monitoring 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 risk management project. Let’s power up the system and begin!

Phase 1: Constructing the Framework—Initialization

We start by building the risk management system, initializing the dashboard and drawdown tracking.

//+------------------------------------------------------------------+
//|                              PROPFIRM DAILY DRAWDOWN LIMITER.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;

int totalBars = 0;
double initialBalance = 0;
datetime dayTime = 0;
double dayBalance = 0;
bool isTradeAllowed = true;

double Acc_B(){return AccountInfoDouble(ACCOUNT_BALANCE);}
double Acc_E(){return AccountInfoDouble(ACCOUNT_EQUITY);}
string Acc_S(){return AccountInfoString(ACCOUNT_CURRENCY);}

int OnInit(){
   initialBalance = Acc_B();
   createText("0","*** PROP FIRM PROGRESS DASHBOARD ***",30,30,clrAqua,13);
   createText("00","______________________________________",30,30,clrAqua,13);
   createText("1","DrawDown Limiter is Active.",70,50,clrWhite,11);
   createText("2","Counters will be Reset on Next Day Start.",70,65,clrWhite,10);
   createText("3","From: ",70,80,clrWhite,10);
   createText("4","Time Here",120,80,clrGray,10);
   createText("5","To: ",70,95,clrWhite,10);
   createText("6","Time Here",120,95,clrGray,10);
   createText("7","Current: ",70,110,clrWhite,10);
   createText("8","Time Here",120,110,clrGray,10);
   createText("9","ACCOUNT DRAWDOWN ============",70,130,clrPeru,11);
   createText("10","Account Initial Balance: ",70,145,clrWhite,10);
   createText("11",DoubleToString(initialBalance,2)+" "+Acc_S(),250,145,clrWhite,10);
   createText("12","Torelated DrawDown: ",70,160,clrWhite,10);
   createText("13","12.00 %",250,160,clrAqua,10);
   createText("14","Current Account Equity: ",70,175,clrWhite,10);
   createText("15",DoubleToString(Acc_E(),2)+" "+Acc_S(),250,175,clrWhite,10);
   createText("16","Current Balance Variation: ",70,190,clrWhite,10);
   createText("17",DoubleToString((Acc_E()-Acc_B())/Acc_B()*100,2)+" %",250,190,clrGray,10);
   createText("18","DAILY DRAWDOWN ================",70,210,clrPeru,11);
   createText("19","Starting Balance: ",70,225,clrWhite,10);
   createText("20",DoubleToString(Acc_B(),2)+" "+Acc_S(),270,225,clrWhite,10);
   createText("21","DrawDowm Maximum Threshold: ",70,240,clrWhite,10);
   createText("22","5.00 %"+" "+Acc_S(),270,240,clrAqua,10);
   createText("23","DrawDown Maximum Amount: ",70,255,clrWhite,10);
   createText("24","-"+DoubleToString(Acc_B()*5/100,2)+" "+Acc_S(),270,255,clrYellow,10);
   createText("25","Current Closed Daily Profit: ",70,270,clrWhite,10);
   createText("26","0.00"+" "+Acc_S(),270,270,clrGray,10);
   createText("27","Current DrawDown Percent: ",70,285,clrWhite,10);
   createText("28","0.00"+" %",270,285,clrGray,10);
   createText("29",">>> Initializing The Program, Get Ready To Trade.",70,300,clrYellow,10);
   return(INIT_SUCCEEDED);
}

The system begins with the #property header, establishing copyright and contact details, like calibrating a risk management system’s core. The "OnInit()" function initializes the setup, including "Trade/Trade.mqh" for trading via "obj_Trade". It sets the initial balance ("initialBalance", "Acc_B()", "AccountInfoDouble()") and creates a dashboard with 29 text labels ("createText()", "OBJ_LABEL") for headers, time ranges, and metrics like balance, equity, and drawdowns, styled with colors ("clrAqua", "clrWhite", etc.). Variables track state ("totalBars", "dayTime", "dayBalance", "isTradeAllowed"=true). Returning INIT_SUCCEEDED signals, “System is ready, let’s manage risk!” This primes the EA for drawdown control, like a risk shield poised for action.

Phase 2: Monitoring Drawdowns—Tracking Risk Limits

With the system active, we monitor daily and account drawdowns, like scanning for risk breaches.

void checkDailyProfit(){
   double total_day_Profit = 0;
   datetime end = TimeCurrent();
   string sdate = TimeToString(TimeCurrent(),TIME_DATE);
   datetime start = StringToTime(sdate);
   datetime to = start + (1*24*60*60);
   if (dayTime < to){
      dayTime = to;
      dayBalance = Acc_B();
   }
   HistorySelect(start,end);
   int TotalDeals = HistoryDealsTotal();
   for (int i=0; i<TotalDeals; i++){
      ulong Ticket = HistoryDealGetTicket(i);
      if (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT){
         double Latest_Day_Profit = (HistoryDealGetDouble(Ticket,DEAL_PROFIT)
                               +HistoryDealGetDouble(Ticket,DEAL_COMMISSION)
                               +HistoryDealGetDouble(Ticket,DEAL_SWAP));
         total_day_Profit += Latest_Day_Profit;
      }
   }
   double startingBalance = AccountInfoDouble(ACCOUNT_BALANCE) - total_day_Profit;
   double daily_profit_or_drawdown = NormalizeDouble((total_day_Profit*100/startingBalance),2);
   string daily_profit_in_Text_Format = DoubleToString(daily_profit_or_drawdown,2)+" %";

In the drawdown monitoring hub, "checkDailyProfit()" calculates daily profit/loss ("total_day_Profit") using "HistorySelect()", "HistoryDealGetTicket()", and "HistoryDealGetDouble()" for closed deals ("DEAL_ENTRY_OUT", including "DEAL_PROFIT", "DEAL_COMMISSION", "DEAL_SWAP"). It resets daily balance ("dayBalance", "Acc_B()") at the start of each day ("dayTime", "TimeCurrent()", "StringToTime()") and computes daily drawdown percentage ("daily_profit_or_drawdown"). For example, on EURUSD, a daily loss of $500 on a $10,000 balance yields a -5% drawdown, like detecting a risk threshold breach.

Phase 3: Limiting Trades—Executing Controlled Trades

With drawdowns monitored, we execute trades with strict limits, like enforcing risk boundaries.

void OnTick(){
   checkDailyProfit();
   if (!isTradeAllowed) return;
   double ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   int bars = iBars(_Symbol,_Period);
   if (totalBars == bars) return;
   totalBars = bars;
   if (PositionsTotal() > 1) return;
   int number = MathRand()%2;
   if (number == 0){
      obj_Trade.Buy(0.1,_Symbol,ask,ask-70*_Point,ask+70*_Point);
   }
   else if (number == 1){
      obj_Trade.Sell(0.1,_Symbol,bid,bid+70*_Point,bid-70*_Point);
   }
}

In the trade execution hub, "OnTick()" calls "checkDailyProfit()" and exits if "isTradeAllowed"=false. It checks for new bars ("iBars()", "totalBars") and limits to one position ("PositionsTotal() > 1"). It randomly selects buy or sell ("MathRand()") and opens a 0.1-lot trade ("obj_Trade.Buy()", "obj_Trade.Sell()") with a 70-pip stop loss and take profit ("ask-70*_Point", "ask+70*_Point") using "SymbolInfoDouble()", "NormalizeDouble()". For example, on EURUSD H1, a random buy at ask=1.2007 sets stop loss at 1.1937 and take profit at 1.2077, like a controlled trade within risk limits.

Phase 4: Displaying Metrics—Updating the Dashboard

With trades active, we update the dashboard with real-time metrics, like visualizing risk status.

void checkDailyProfit(){
   // ... (drawdown calculation)
   createText("4",TimeToString(start),120,80,clrYellow,10);
   createText("6",TimeToString(to),120,95,clrYellow,10);
   createText("8",TimeToString(end),120,110,clrWhite,10);
   if (Acc_E() > initialBalance){
      createText("15",DoubleToString(Acc_E(),2)+" "+Acc_S(),250,175,clrLime,10);
      createText("17",DoubleToString((Acc_E()-initialBalance)/initialBalance*100,2)+" %",250,190,clrLime,10);
   }
   else if (Acc_E() < initialBalance){
      createText("15",DoubleToString(Acc_E(),2)+" "+Acc_S(),250,175,clrRed,10);
      createText("17",DoubleToString((Acc_E()-initialBalance)/initialBalance*100,2)+" %",250,190,clrRed,10);
   }
   if (Acc_E() == initialBalance){
      createText("15",DoubleToString(Acc_E(),2)+" "+Acc_S(),250,175,clrWhite,10);
      createText("17",DoubleToString((Acc_E()-initialBalance)/initialBalance*100,2)+" %",250,190,clrWhite,10);
   }
   createText("20",DoubleToString(dayBalance,2)+" "+Acc_S(),270,225,clrWhite,10);
   createText("24","-"+DoubleToString(dayBalance*5/100,2)+" "+Acc_S(),270,255,clrYellow,10);
   if (Acc_B() > dayBalance){
      createText("26",DoubleToString(total_day_Profit,2)+" "+Acc_S(),270,270,clrLime,10);
      createText("28",daily_profit_in_Text_Format,270,285,clrLime,10);
   }
   else if (Acc_B() < dayBalance){
      createText("26",DoubleToString(total_day_Profit,2)+" "+Acc_S(),270,270,clrRed,10);
      createText("28",daily_profit_in_Text_Format,270,285,clrRed,10);
   }
   else if (Acc_B() == dayBalance){
      createText("26",DoubleToString(total_day_Profit,2)+" "+Acc_S(),270,270,clrGray,10);
      createText("28",daily_profit_in_Text_Format,270,285,clrGray,10);
   }
   if (daily_profit_or_drawdown <= -5.00 || ((Acc_E()-initialBalance)/initialBalance*100) < -12.00){
      createText("29",">>> Maximum Threshold Hit, Can't Trade.",70,300,clrRed,10);
      isTradeAllowed = false;
   }
   else {
      createText("29",">>> Maximum Threshold Not Hit, Can Trade.",70,300,clrLime,10);
      isTradeAllowed = true;
   }
}

bool createText(string objName,string text,int x, int y,color clrTxt,int fontSize){
   ResetLastError();
   if (!ObjectCreate(0,objName,OBJ_LABEL,0,0,0)){
      Print(__FUNCTION__,": failed to create the Label! Error Code = ",GetLastError());
      return (false);
   }
   ObjectSetInteger(0,objName,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,objName,OBJPROP_YDISTANCE,y);
   ObjectSetInteger(0,objName,OBJPROP_CORNER,CORNER_LEFT_UPPER);
   ObjectSetString(0,objName,OBJPROP_TEXT,text);
   ObjectSetInteger(0,objName,OBJPROP_COLOR,clrTxt);
   ObjectSetInteger(0,objName,OBJPROP_FONTSIZE,fontSize);
   ChartRedraw(0);
   return (true);
}

In the dashboard hub, "checkDailyProfit()" updates labels with "createText()", "ObjectCreate()", "ObjectSetInteger()", "ObjectSetString()", and "ChartRedraw()". It displays time ranges ("start", "to", "end", "TimeToString()") in yellow, equity ("Acc_E()") and total drawdown in lime (gains), red (losses), or white (neutral), and daily metrics ("dayBalance", "total_day_Profit") with 5% threshold ("dayBalance*5/100") in similar colors. If daily drawdown reaches -5% ("daily_profit_or_drawdown <= -5.00") or total drawdown hits -12% ("(Acc_E()-initialBalance)/initialBalance*100 < -12.00"), it sets "isTradeAllowed"=false and shows a red warning. For example, on EURUSD, a -6% daily drawdown displays “Can’t Trade” in red, halting trading, like a risk alert on a control panel.

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 dashboard labels ("OBJ_LABEL") on the chart, like an active risk panel. Adding cleanup would ensure a clean slate:

ObjectsDeleteAll(0, -1, -1);

This would remove all objects with "ObjectsDeleteAll()", like dismantling a risk management system, ready for the next task.

Why This EA is a Risk Management Triumph

The Propfirm Daily Drawdown Limiter EA is a risk control triumph, enforcing strict drawdown limits with precision, like a master-crafted protective shield. Its robust monitoring ("checkDailyProfit()", "HistorySelect()") and dynamic dashboard ("createText()") offer clarity, with potential for real entry signals or configurable thresholds. Picture a EURUSD trade halted at -5% daily drawdown with a red dashboard warning—strategic brilliance! Beginners will value the clear metrics, while experts can refine its framework, making it essential for prop firm traders or those prioritizing capital safety.

Putting It All Together

To deploy this EA:

  1. Open MetaEditor in MetaTrader 5, like entering your risk management control room.

  2. Copy the code, compile with F5, and verify no errors—no risk manager wants a faulty system!

  3. Attach the EA to your chart, enable AutoTrading, and watch it monitor drawdowns and execute test trades.

  4. Monitor logs (e.g., “failed to create the Label! Error Code =”) and the dashboard for risk tracking, like control diagnostics.

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

Conclusion

We’ve engineered a Propfirm Daily Drawdown Limiter that enforces risk control with precision, like a master-crafted protective system. 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 discipline. Whether you’re a novice risk manager or a seasoned market strategist, this EA empowers you to safeguard your capital with confidence. Ready to protect? Watch our video guide on the website for a step-by-step creation process. Now, secure your trading future 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!