Re: Your Plan Should Include an "If This, Then That" Contingency Section
Posted: Wed Sep 23, 2026 9:12 am
2. The MT5 Implementation (MQL5)
In MT5, the structure is more modern. We use HistorySelect() to fetch the account's historical "Deals" rather than looping through a generic order pool, and we utilize the built-in CTrade library to easily kill open positions.
In MT5, the structure is more modern. We use HistorySelect() to fetch the account's historical "Deals" rather than looping through a generic order pool, and we utilize the built-in CTrade library to easily kill open positions.
Code: Select all
//+------------------------------------------------------------------+
//| RiskManager_MT5.mq5 |
//+------------------------------------------------------------------+
#property strict
#include <Trade\Trade.mqh>
input double DailyLossLimit = 500.0;
input double BaseLotSize = 0.1;
input int NewsHourStart = 13;
input int NewsMinuteStart = 45;
input int NewsHourEnd = 14;
input int NewsMinuteEnd = 15;
datetime timeoutEndTime = 0;
CTrade trade;
void OnTick()
{
// SCENARIO 1: Daily Loss Limit
if(IsDailyLossReached())
{
CloseAllPositions();
return; // Halt trading for the day
}
// SCENARIO 3: News Blackout
if(IsNewsBlackout())
{
CloseAllPositions();
return; // Halt trading during news
}
// SCENARIO 2: Penalty Box (Three Consecutive Losses)
if(TimeCurrent() < timeoutEndTime) return; // In 60-min timeout
CheckConsecutiveLosses();
// Cut lot size by 50% if currently on a losing streak of 3 or more
double currentLotSize = BaseLotSize;
if(GetConsecutiveLosses() >= 3) currentLotSize = BaseLotSize / 2.0;
// --- YOUR STRATEGY LOGIC GOES HERE ---
// Example: if(BuySignal) trade.Buy(currentLotSize);
}
// =====================================================================
// HELPER FUNCTIONS
// =====================================================================
bool IsDailyLossReached()
{
double todayRealized = 0.0;
// Get midnight of the current day safely
MqlDateTime dt; TimeToStruct(TimeCurrent(), dt);
dt.hour = 0; dt.min = 0; dt.sec = 0;
datetime startOfDay = StructToTime(dt);
// Pull history for today
HistorySelect(startOfDay, TimeCurrent());
for(int i = 0; i < HistoryDealsTotal(); i++)
{
ulong ticket = HistoryDealGetTicket(i);
long entryType = HistoryDealGetInteger(ticket, DEAL_ENTRY);
// Only count realized profits (trades exiting the market)
if(entryType == DEAL_ENTRY_OUT || entryType == DEAL_ENTRY_INOUT)
{
todayRealized += HistoryDealGetDouble(ticket, DEAL_PROFIT) +
HistoryDealGetDouble(ticket, DEAL_SWAP) +
HistoryDealGetDouble(ticket, DEAL_COMMISSION);
}
}
double floatingProfit = AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE);
return ((todayRealized + floatingProfit) <= -DailyLossLimit);
}
bool IsNewsBlackout()
{
MqlDateTime dt; TimeToStruct(TimeCurrent(), dt);
int currentMinutes = dt.hour * 60 + dt.min;
int startMinutes = NewsHourStart * 60 + NewsMinuteStart;
int endMinutes = NewsHourEnd * 60 + NewsMinuteEnd;
return (currentMinutes >= startMinutes && currentMinutes <= endMinutes);
}
int GetConsecutiveLosses()
{
int lossCount = 0;
HistorySelect(0, TimeCurrent()); // Load full history
// Loop backwards through closed deals
for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
{
ulong ticket = HistoryDealGetTicket(i);
long entryType = HistoryDealGetInteger(ticket, DEAL_ENTRY);
if(entryType == DEAL_ENTRY_OUT || entryType == DEAL_ENTRY_INOUT)
{
double pnl = HistoryDealGetDouble(ticket, DEAL_PROFIT) +
HistoryDealGetDouble(ticket, DEAL_SWAP) +
HistoryDealGetDouble(ticket, DEAL_COMMISSION);
if(pnl < 0) lossCount++;
else if(pnl > 0) break; // Streak broken
}
}
return lossCount;
}
void CheckConsecutiveLosses()
{
static int lastHistoryCount = 0;
HistorySelect(0, TimeCurrent());
int currentHistoryCount = HistoryDealsTotal();
if(currentHistoryCount > lastHistoryCount)
{
if(GetConsecutiveLosses() >= 3) timeoutEndTime = TimeCurrent() + 3600;
lastHistoryCount = currentHistoryCount;
}
}
void CloseAllPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket > 0) trade.PositionClose(ticket);
}
}