I don't see your variable declarations
extern string __LossControl__ = "***Loss Control***"; extern bool TodayLossControl = true; enum FixedVsBalancePercentage_enum {FixedMoney, BalancePercentage}; extern FixedVsBalancePercentage_enum TodayCutLossType = BalancePercentage; extern double TodayMaxLoss = 1; extern int continueTradeLoss = 5; int ConsecutiveLoss = 0; bool TodayLossEAPaused = false, ConsecutiveLossPaused = false; datetime TodayDate; datetime LastResetDay = 0, lastCountedCloseTime = 0; int OnInit() { TodayDate = StrToTime(TimeToString(TimeCurrent(), TIME_DATE)); return(INIT_SUCCEEDED); }
TimeLocal() returns GMT in the Tester. TimeCurrent() returns GMT+/- per the historic data timestamps during bactesting.
Is i am doing correct?
This is not a very correct question. Either your code works as you expect, or it doesn't.
// ================================ // 1. Calculate start of current day // ================================ datetime nowDayStart = StrToTime(TimeToString(TimeCurrent(), TIME_DATE));
This is not quite on topic, but it catches the eye. I personally calculate the start time of the day like this:
#define _secsInDay 86400 #define _calculDayStartDt(a) (((a) / _secsInDay) * _secsInDay) void OnStart() { datetime timeCurrent = TimeCurrent(); datetime dayStartDt = _calculDayStartDt(timeCurrent); }
I am trying to add Loss control to my EA.
1. it will stop taking new trade ones it hit X amount in loss Today and will restart taking new trade tomorrow.
void TodayLossControling() { int totalHistory = OrdersHistoryTotal(); for(int i = totalHistory - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
2. It will stop taking new trade after X loss trade in sequence
void CheckConsecutiveLossControl() { for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
The second thing that immediately catches my eye is that you have two different functions that analyze the entire order history. Perhaps it makes sense to prepare all the necessary information from the order history once, instead of looping through the entire order history several times per tick.
The second thing that immediately catches my eye is that you have two different functions that analyze the entire order history. Perhaps it makes sense to prepare all the necessary information from the order history once, instead of looping through the entire order history several times per tick.
The second thing that immediately catches my eye is that you have two different functions that analyze the entire order history. Perhaps it makes sense to prepare all the necessary information from the order history once, instead of looping through the entire order history several times per tick.
Here is updated code from your suggestion, i am looping one time per tick (order history) and i am using #define like you mentioned
//+------------------------------------------------------------------+ //| LOSS CONTROL SYSTEM | //+------------------------------------------------------------------+ // ---- INPUTS ---- extern string __LossControl__ = "***Loss Control***"; extern bool TodayLossControl = true; enum FixedVsBalancePercentage_enum {FixedMoney, BalancePercentage}; extern FixedVsBalancePercentage_enum TodayCutLossType = BalancePercentage; extern double TodayMaxLoss = 1; // % or fixed money extern int ConsecutiveTradeLoss = 5; // max consecutive losing trades extern int Magic = 12345; // ---- INTERNAL VARIABLES ---- int ConsecutiveLoss = 0; bool TodayLossEAPaused = false; bool ConsecutiveLossPaused = false; datetime TodayDate; datetime LastResetDay = 0; datetime lastCountedCloseTime = 0; double gTodayLossPL = 0; // ---- DAY START MACRO (FAST) ---- #define _secsInDay 86400 #define DayStart(a) (((a) / _secsInDay) * _secsInDay) //+------------------------------------------------------------------+ //| STRUCT TO STORE HISTORY RESULTS | //+------------------------------------------------------------------+ struct HistoryInfo { double todayPL; int consecutiveLoss; datetime lastCloseTime; }; HistoryInfo hist; //+------------------------------------------------------------------+ //| INITIALIZATION | //+------------------------------------------------------------------+ int OnInit() { TodayDate = DayStart(TimeCurrent()); LastResetDay = TodayDate; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| ONE PASS ORDER HISTORY ANALYSIS | //+------------------------------------------------------------------+ void AnalyzeOrderHistory() { hist.todayPL = 0; hist.consecutiveLoss = ConsecutiveLoss; // keep old value hist.lastCloseTime = lastCountedCloseTime; datetime now = TimeCurrent(); datetime todayStart = DayStart(now); int losses = ConsecutiveLoss; datetime lastTime = lastCountedCloseTime; for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if(OrderMagicNumber() != Magic) continue; datetime closeTime = OrderCloseTime(); // ---- Today P/L ---- if(closeTime >= todayStart) hist.todayPL += OrderProfit() + OrderSwap() + OrderCommission(); // ---- Consecutive Loss Tracking ---- if(closeTime > lastTime) // new order detected { if(closeTime > LastResetDay) { if(OrderProfit() < 0) losses++; else losses = 0; } lastTime = closeTime; } } // Update struct outputs hist.consecutiveLoss = losses; hist.lastCloseTime = lastTime; } //+------------------------------------------------------------------+ //| TODAY LOSS CONTROL | //+------------------------------------------------------------------+ void TodayLossControlling() { if(TodayMaxLoss <= 0) return; datetime nowDayStart = DayStart(TimeCurrent()); // --- New Day Reset --- if(nowDayStart != TodayDate) { TodayDate = nowDayStart; TodayLossEAPaused = false; } double todayPL = hist.todayPL; // Determine loss threshold if(TodayCutLossType == BalancePercentage) gTodayLossPL = AccountBalance() * (TodayMaxLoss * 0.01); else gTodayLossPL = TodayMaxLoss; // Pause EA if loss reached if(!TodayLossEAPaused && todayPL <= -MathAbs(gTodayLossPL)) TodayLossEAPaused = true; } //+------------------------------------------------------------------+ //| CONSECUTIVE LOSS CONTROL | //+------------------------------------------------------------------+ void CheckConsecutiveLossControl() { if(ConsecutiveTradeLoss <= 0) return; datetime today = DayStart(TimeCurrent()); // ---- Reset on New Day ---- if(today != LastResetDay) { ConsecutiveLoss = 0; ConsecutiveLossPaused = false; LastResetDay = today; lastCountedCloseTime = 0; } // Update counters from history scan ConsecutiveLoss = hist.consecutiveLoss; lastCountedCloseTime = hist.lastCloseTime; // Pause if limit exceeded if(!ConsecutiveLossPaused && ConsecutiveLoss >= ConsecutiveTradeLoss) ConsecutiveLossPaused = true; } //+------------------------------------------------------------------+ //| MAIN RUNTIME | //+------------------------------------------------------------------+ void OnTick() { // Analyze history ONCE per tick AnalyzeOrderHistory(); // Apply risk controls TodayLossControlling(); CheckConsecutiveLossControl(); // --- Check blocking conditions before placing trades --- if(TodayLossEAPaused || ConsecutiveLossPaused) { return; } }
It is better to avoid even a single analysis of the entire history (with each tick).
Then what is the solution?. How to add Risk Management like Consecutive Loss Orders and Maximum today loss can be taken?
Consecutive Loss Orders
It will stop taking new trade after X loss trade in sequence
When analyzing your order history, you should collect all of today's orders into an array of structures (or classes) sorted by order close time. The structure/class must contain at least 2 fields (order closing time and profit):
class CHistOrder { public: datetime orderCloseTime; double orderProfit; };[edit] You can then identify X losses in a row simply by looking at the profit value for the last X elements of the array (which is not at all difficult if you have a sorted array ready).
Let me clarify.
anuj71 #:
for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if(OrderMagicNumber() != Magic) continue; datetime closeTime = OrderCloseTime(); // ---- Today P/L ---- if(closeTime >= todayStart) hist.todayPL += OrderProfit() + OrderSwap() + OrderCommission(); // ---- Consecutive Loss Tracking ---- if(closeTime > lastTime) // new order detected { if(closeTime > LastResetDay) { if(OrderProfit() < 0) losses++; else losses = 0; } lastTime = closeTime; } } // Update struct outputs hist.consecutiveLoss = losses; hist.lastCloseTime = lastTime; }
In theory, such code might work somewhat, but only on the condition that the orders in the terminal history are sorted by closing time (I have not tested your specific code).
I don't know how orders are sorted in MT4 history. If I need a specific sorting, I don't rely on the defaults and sort the orders myself.
When analyzing your order history, you should collect all of today's orders into an array of structures (or classes) sorted by order close time. The structure/class must contain at least 2 fields (order closing time and profit):
I don't know how orders are sorted in MT4 history. If I need a specific sorting, I don't rely on the defaults and sort the orders myself.
Add Class and sorting by close time
//+------------------------------------------------------------------+ //| LOSS CONTROL SYSTEM | //+------------------------------------------------------------------+ extern string __LossControl__ = "***Loss Control***"; extern bool TodayLossControl = true; enum FixedVsBalancePercentage_enum {FixedMoney, BalancePercentage}; extern FixedVsBalancePercentage_enum TodayCutLossType = BalancePercentage; extern double TodayMaxLoss = 1; extern int ConsecutiveTradeLoss = 5; extern int Magic = 12345; // ---- Internal ---- bool TodayLossEAPaused = false; bool ConsecutiveLossPaused = false; datetime TodayDate; datetime LastResetDay = 0; double gTodayLossPL = 0; // ---- Day start ---- #define _secsInDay 86400 #define DayStart(a) (((a) / _secsInDay) * _secsInDay) //==================================================== // Order Structure //==================================================== class CHistOrder { public: datetime orderCloseTime; double orderProfit; }; // Sorting comparator int sortByCloseTime(const CHistOrder &a, const CHistOrder &b) { if(a.orderCloseTime < b.orderCloseTime) return -1; if(a.orderCloseTime > b.orderCloseTime) return 1; return 0; } //+------------------------------------------------------------------+ //| INITIALIZATION | //+------------------------------------------------------------------+ int OnInit() { TodayDate = DayStart(TimeCurrent()); LastResetDay = TodayDate; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| SCAN HISTORY → BUILD SORTED ARRAY | //+------------------------------------------------------------------+ void BuildTodayOrdersArray(CHistOrder &arr[]) { ArrayResize(arr, 0); datetime todayStart = DayStart(TimeCurrent()); int count = 0; for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if(OrderMagicNumber() != Magic) continue; datetime ct = OrderCloseTime(); if(ct < todayStart) continue; // Add order CHistOrder o; o.orderCloseTime = ct; o.orderProfit = OrderProfit() + OrderSwap() + OrderCommission(); ArrayResize(arr, count + 1); arr[count] = o; count++; } // Sort by close time if(count > 1) ArraySort(arr, WHOLE_ARRAY, 0, SORT_CUSTOM, sortByCloseTime); } //+------------------------------------------------------------------+ //| TODAY LOSS CONTROL | //+------------------------------------------------------------------+ void TodayLossControlling(double todayPL) { if(TodayMaxLoss <= 0) return; datetime nowDayStart = DayStart(TimeCurrent()); // New Day → reset if(nowDayStart != TodayDate) { TodayDate = nowDayStart; TodayLossEAPaused = false; } // daily limit if(TodayCutLossType == BalancePercentage) gTodayLossPL = AccountBalance() * (TodayMaxLoss * 0.01); else gTodayLossPL = TodayMaxLoss; // Pause EA if(!TodayLossEAPaused && todayPL <= -MathAbs(gTodayLossPL)) TodayLossEAPaused = true; } //+------------------------------------------------------------------+ //| CONSECUTIVE LOSS CONTROL | //+------------------------------------------------------------------+ void CheckConsecutiveLossControl(CHistOrder &arr[]) { if(ConsecutiveTradeLoss <= 0) return; datetime today = DayStart(TimeCurrent()); // New day reset if(today != LastResetDay) { ConsecutiveLossPaused = false; LastResetDay = today; } // Count losses in a row from END int lossCount = 0; int total = ArraySize(arr); for(int i = total - 1; i >= 0; i--) { if(arr[i].orderProfit < 0) lossCount++; else break; } if(!ConsecutiveLossPaused && lossCount >= ConsecutiveTradeLoss) ConsecutiveLossPaused = true; } //+------------------------------------------------------------------+ //| MAIN LOOP | //+------------------------------------------------------------------+ void OnTick() { CHistOrder todaysOrders[]; BuildTodayOrdersArray(todaysOrders); // compute today's PL double todayPL = 0; for(int i=0; i < ArraySize(todaysOrders); i++) todayPL += todaysOrders[i].orderProfit; // Apply risk controls TodayLossControlling(todayPL); CheckConsecutiveLossControl(todaysOrders); // BLOCK trading if needed if(TodayLossEAPaused || ConsecutiveLossPaused) return; }
You should understand what you are doing.

You have a simple task - to collect today's orders into an array of structures/classes, sorted by the order closing price time.
Forum on trading, automated trading systems and testing trading strategies
Stop Trading Today when Loss or Consecutive Loss
Vladislav Boyko, 2025.12.01 11:13
class CHistOrder { public: datetime orderCloseTime; double orderProfit; };
Do your own research on this and show your attempt. If you use AI assistance, make sure the generated code compiles and performs its task correctly.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am trying to add Loss control to my EA.
1. it will stop taking new trade ones it hit X amount in loss Today and will restart taking new trade tomorrow.
2. It will stop taking new trade after X loss trade in sequence
Is i am doing correct?