Edgoro
MQL5 errors

MQL5 errors: causes and fixes

The errors MetaTrader 5 developers meet most: why an Expert Advisor's order is refused, what stops it at run time, and what MetaEditor means when the build fails. Every page has a program that shows the problem and a fixed version that compiles in MetaEditor.

Trade server return codes

The order was refused. The reason is a number from 10004 up, in MqlTradeResult.retcode or CTrade's ResultRetcode().

Runtime errors

Codes from GetLastError(), and the critical errors that stop an EA on the spot: indicator data, permissions, arrays, division.

Compiler errors and warnings

What MetaEditor prints in the Errors tab when you compile, very often after moving MQL4 code to MQL5.

Retcode or GetLastError()?

When an order fails, MQL5 gives you two different numbers, and reading the wrong one is the most common reason an error stays a mystery:

  • The trade server return code (10004 and up) is in the retcode field of MqlTradeResult, or trade.ResultRetcode() with the CTrade class. It says why the order was refused: invalid stops, no money, market closed.
  • The runtime error (4000s and 5000s) comes from GetLastError(). After a failed order it's usually 4756, which only says that the request failed. Call ResetLastError() before the call you want to check.
  • Critical errors such as array out of range and zero divide have no code to read: MetaTrader stops the program and prints the file, line and column in the Experts tab.

And OrderSend() returning true isn't a fill: it means the request was accepted. The retcode then says what happened, 10009 (TRADE_RETCODE_DONE) for a completed market order or 10008 (TRADE_RETCODE_PLACED) for a pending order. This script reads both numbers:

It sends a real order of the symbol's minimum volume when you run it: try it on a demo account.

MQL5
void OnStart()
  {
   MqlTradeRequest req = {};
   MqlTradeResult  res = {};
   req.action       = TRADE_ACTION_DEAL;
   req.symbol       = _Symbol;
   req.volume       = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   req.type         = ORDER_TYPE_BUY;
   req.price        = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   req.deviation    = 10;
   req.type_filling = ORDER_FILLING_IOC;   // check the symbol's filling modes first (error 10030)

   ResetLastError();
   if(!OrderSend(req, res))
     {
      // GetLastError() says THAT it failed (4756), the retcode says WHY
      PrintFormat("OrderSend failed: error %d, retcode %u (%s)", GetLastError(), res.retcode, res.comment);
      return;
     }
   // true only means the request was accepted: check what the server did with it
   if(res.retcode == TRADE_RETCODE_DONE || res.retcode == TRADE_RETCODE_PLACED)
      PrintFormat("Done: deal #%I64u at %s", res.deal, DoubleToString(res.price, _Digits));
   else
      PrintFormat("Not filled: retcode %u (%s)", res.retcode, res.comment);
  }

The full lists are in MetaQuotes' MQL5 Reference: trade server return codes, runtime errors and compilation errors. For a longer walk through the order errors, read MQL5 OrderSend errors explained.

To see the checks at work in complete programs, from opening an order with CTrade to a partial close or a pending order with an expiry, browse the MQL5 code examples: each one compiles in MetaEditor and links the errors it is written to avoid.

Codes, constants and descriptions were checked against MetaQuotes' MQL5 Reference on November 11, 2026. Compiler messages are the ones MetaEditor 5 (build 6275) prints for each page's broken program, and every fixed program, like the script above, compiles in MetaEditor with 0 errors and 0 warnings.

Rather not write the error handling yourself?

Edgoro's MT5 EA generator writes complete MQL5 Expert Advisors from plain English, with prices rounded, volumes kept within the broker's limits, stops beyond the stops level and return codes logged, and compiles each one in MetaEditor before you get it. A clean build proves the code compiles, not that a strategy works: test it on a demo account.