Advertisement IC Markets

Simulating a broker outage in your EA testing

Share, develop, and backtest custom MQL4/MQL5 Expert Advisors, Python data-scraping scripts, trading bots, and automated market alert systems.
PTScalper
Site Admin
Posts: 7647
Joined: Mon Jul 20, 2026 1:28 pm

Re: Simulating a broker outage in your EA testing

Post by PTScalper »

Phase 4: Weekend / Market-Closed Initialization

Many traders deploy EAs on Friday evening or Sunday before markets open, only to find errors or crashes when the market finally opens because the initialization sequence failed while prices were static.

How to Simulate: Attach your EA to a live or demo chart on a Sunday when markets are completely closed, or during a scheduled maintenance window.

What to Look For:

Does the EA handle missing tick data, zero spreads, or stale bid/ask prices gracefully during OnInit()?

Does it crash or throw array-out-of-range errors when calculating technical indicators (like moving averages or ATR) when historical bar data is incomplete?

Verification: Inspect the journal tab for initialization errors and ensure your EA checks for valid pricing data (SymbolInfoDouble(Symbol(), SYMBOL_BID) > 0) before executing any calculations on startup.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 7647
Joined: Mon Jul 20, 2026 1:28 pm

Re: Simulating a broker outage in your EA testing

Post by PTScalper »

To build an Expert Advisor that survives real-world chaos, network dropouts, and broker restarts, you need code structures that do not rely on volatile run-time memory alone.

Below are robust MQL5 code snippets demonstrating dynamic state recovery on startup (OnInit), safe broker error handling, and a throttled retry loop to prevent server spamming.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7647
Joined: Mon Jul 20, 2026 1:28 pm

Re: Simulating a broker outage in your EA testing

Post by PTScalper »

1. Dynamic State Recovery on Startup (OnInit)

Instead of losing track of your states when MetaTrader restarts or your VPS reboots, force your EA to query the broker server immediately upon initialization (OnInit) to map all active positions back into local tracking variables.

Code: Select all

//--- Input parameters
input long MagicNumber = 123456;

//--- Global tracking variables
bool   g_hasOpenPosition = false;
ulong  g_activeTicket    = 0;
double g_entryPrice      = 0.0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // 1. Check if the terminal is actually connected to the broker server
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
   {
      Print("Initialization Warning: Terminal is currently disconnected from the broker!");
      // Do not fail entirely; allow it to load so it can recover once connection resumes
   }

   // 2. Perform state recovery: scan open positions on the broker server
   RecoverEAState();

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Scan broker server to rebuild internal EA state                  |
//+------------------------------------------------------------------+
void RecoverEAState()
{
   g_hasOpenPosition = false;
   g_activeTicket    = 0;

   int totalPositions = PositionsTotal();
   for(int i = 0; i < totalPositions; i++)
   {
      ulong ticket = PositionGetTicket(i);
      if(ticket > 0)
      {
         // Filter by symbol and Magic Number to manage only this EA's trades
         if(PositionGetString(POSITION_SYMBOL) == _Symbol && 
            PositionGetInteger(POSITION_MAGIC) == MagicNumber)
         {
            g_hasOpenPosition = true;
            g_activeTicket    = ticket;
            g_entryPrice      = PositionGetDouble(POSITION_PRICE_OPEN);
            
            Print("State Recovery Successful: Re-attached to active ticket #", ticket, " at price: ", g_entryPrice);
            break; // Assuming single-position EA for this example
         }
      }
   }
   
   if(!g_hasOpenPosition)
   {
      Print("State Recovery: No active positions found on broker server for Magic Number: ", MagicNumber);
   }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7647
Joined: Mon Jul 20, 2026 1:28 pm

Re: Simulating a broker outage in your EA testing

Post by PTScalper »

2. Safe Error Handling & Throttled Retry Loop

When a broker returns a temporary error (such as TRADE_RETCODE_CONNECTION or TRADE_RETCODE_BUSY), an EA shouldn't hammer the server in a tight loop. It needs a measured back-off mechanism and a way to parse fatal errors vs. retryable errors.

Code: Select all

//+------------------------------------------------------------------+
//| Safe function to send trade requests with error management       |
//+------------------------------------------------------------------+
bool SendOrderWithRetry(MqlTradeRequest &request, MqlTradeResult &result)
{
   int maxRetries = 3;
   int retryDelayMs = 1000; // 1 second back-off
   
   for(int attempt = 1; attempt <= maxRetries; attempt++)
   {
      ResetLastError();
      bool success = OrderSend(request, result);
      
      // If execution was successful at the network/API level, check return code
      if(success)
      {
         switch(result.retcode)
         {
            case TRADE_RETCODE_DONE:
            case TRADE_RETCODE_DONE_PARTIAL:
               Print("Order executed successfully. Ticket: ", result.deal);
               return true;
               
            // Temporary errors where a retry makes sense
            case TRADE_RETCODE_REQUOTE:
            case TRADE_RETCODE_PRICE_OFF:
            case TRADE_RETCODE_CONNECTION:
            case TRADE_RETCODE_BUSY:
               Print("Attempt ", attempt, " failed with temporary broker error: ", result.retcode, ". Retrying in ", retryDelayMs, "ms...");
               Sleep(retryDelayMs);
               retryDelayMs *= 2; // Exponential back-off
               continue;
               
            // Fatal errors where retrying will achieve nothing (e.g., bad stops, insufficient funds)
            case TRADE_RETCODE_INVALID_STOPS:
            case TRADE_RETCODE_INVALID_VOLUME:
            case TRADE_RETCODE_NO_MONEY:
               Print(ErrorDescription(result.retcode), " (Code: ", result.retcode, "). Aborting request—manual fix required.");
               return false;
               
            default:
               Print("Unclassified trade return code: ", result.retcode);
               return false;
         }
      }
      else
      {
         // MQL system-level failure (e.g., trade context busy)
         uint err = GetLastError();
         Print("OrderSend system failure. Error code: ", err, ". Attempt ", attempt, " of ", maxRetries);
         Sleep(retryDelayMs);
      }
   }
   
   Print("Critical: Order placement failed completely after ", maxRetries, " attempts.");
   return false;
}

// Simple helper string mapping for standard retcodes
string ErrorDescription(uint retcode)
{
   switch(retcode)
   {
      case 10013: return "ERR_INVALID_STOPS (Stop loss/Take profit too close)";
      case 10014: return "ERR_INVALID_TRADE_VOLUME (Invalid lot size)";
      case 10019: return "ERR_NO_MONEY (Insufficient margin)";
      default:    return "FATAL_TRADE_ERROR";
   }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7647
Joined: Mon Jul 20, 2026 1:28 pm

Re: Simulating a broker outage in your EA testing

Post by PTScalper »

Best Practices Checklist for Robust EAs

Never rely on global run-time variables to remember if a partial close or a trailing adjustment happened. Query the broker's ticket properties (PositionGetInteger) on every tick or use persistent files (FileWrite / FileRead) if complex local states must survive a full platform crash.

Always validate pricing data inside OnInit() and the beginning of OnTick() using SymbolInfoDouble(_Symbol, SYMBOL_BID) > 0 to prevent zero-divide crashes when attached on weekends or during server freezes.

Log critical state transitions to your local terminal file using Print() so you can cross-reference the exact microsecond a disconnection or recovery occurred during post-mortem debugging.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Fairman
Posts: 6757
Joined: Tue Jul 21, 2026 7:11 am
Location: Abuja

Re: Simulating a broker outage in your EA testing

Post by Fairman »

Thanks. If I had to pick one test from that list, it's the restart with an open trade, because that is where I've found real bugs. My first EA kept its trailing level in a variable. After a reboot it forgot it, saw a 40 pip winner with no trail and happily tried to manage it from scratch, moving the stop back to the original 15 pips. On a 0.6 lot position that was about 150 dollars of locked profit handed back for nothing.

The fix was to store state somewhere that survives a restart, either global variables or a small file, and on init to scan open positions by magic number and rebuild the state from them. Then I added a rule that on startup it never opens anything for the first 30 seconds, only reconciles.

One more test I'd add is a duplicate-order check. Pull the cable right after sending an order, reconnect, and see whether the EA resends because it never saw a confirmation.

Do you give each EA its own magic number scheme, or share one across strategies? And what does yours do when a modify request keeps failing?
It’s Fairman :geek:
Post Reply