Edgoro
Runtime error 4756 · MQL5

MQL5 error 4756: trade request sending failed (fix)

MQL5 error 4756 only says OrderSend() failed. How to read the real reason from the retcode, with CTrade or MqlTradeResult, and fix the usual causes.

Runtime error · GetLastError()
4756 ERR_TRADE_SEND_FAILED
“Trade request sending failed”

What it means

OrderSend(), or a CTrade method that calls it, returned false. That's all 4756 tells you: the request was refused. The reason is a second number, the trade server return code in MqlTradeResult.retcode. Code that only prints GetLastError() never sees it.

Usual causes

4756 comes with a retcode. The ones EAs meet most:

How to detect it

  • With raw OrderSend(req, res): print res.retcode and res.comment (by default the broker fills the comment with the retcode's description).
  • With CTrade: trade.ResultRetcode(), trade.ResultRetcodeDescription() and trade.ResultComment(). CTrade also prints the failed request in the Experts tab.
  • Call ResetLastError() before the trade call, so the GetLastError() you read belongs to it.

Broken code

This script compiles, and tries to open a minimum-volume buy when run. It fails, and the log only says "error 4756".

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.sl           = req.price;            // a stop at the entry price: refused
   req.type_filling = ORDER_FILLING_IOC;
   if(!OrderSend(req, res))
      Print("OrderSend failed, error ", GetLastError());   // prints 4756, never the reason
  }

Fixed code

The same program with the check that prevents the error. It compiles in MetaEditor with 0 errors and 0 warnings.

MQL5
void OnStart()
  {
   MqlTick tick;
   if(!SymbolInfoTick(_Symbol, tick))
      return;
   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        = tick.ask;
   req.sl           = NormalizeDouble(tick.bid - 300 * _Point, _Digits);
   req.deviation    = 10;
   req.type_filling = ORDER_FILLING_IOC;

   ResetLastError();
   if(!OrderSend(req, res))
     {
      // 4756 says it failed; the retcode says why
      PrintFormat("OrderSend failed: error %d, retcode %u (%s), bid %s ask %s sl %s, stops level %d",
                  GetLastError(), res.retcode, res.comment,
                  DoubleToString(tick.bid, _Digits), DoubleToString(tick.ask, _Digits), DoubleToString(req.sl, _Digits),
                  (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL));
      return;
     }
   if(res.retcode != TRADE_RETCODE_DONE && res.retcode != TRADE_RETCODE_PLACED)
      PrintFormat("Accepted but not done: retcode %u (%s)", res.retcode, res.comment);
  }

Why the fix works

The fixed script logs the retcode and the broker's comment along with 4756, plus the prices and the stops level, which is everything you need to diagnose the failure from one line of the journal. The stop is also measured from the Bid and placed 300 points away, instead of at the entry price.

Note the last check: OrderSend() returning true only means the request passed the basic checks and was accepted. The retcode still says what happened: 10009 (TRADE_RETCODE_DONE) for a completed request, 10008 (TRADE_RETCODE_PLACED) for a placed order, 10010 when only part of the volume was filled. The fixed script still uses IOC as its filling policy; choose it from the symbol's flags as shown for error 10030.

Questions

Is error 4756 a broker problem?

Not by itself. 4756 means the request was refused, by the terminal or the server; the retcode tells you which rule it broke. Most of them (stops, volume, filling mode, margin) are fixed in the EA's code.

What does 4756 with retcode 10013 mean?

10013 is "Invalid request": the server couldn't accept the request as built, typically because a field that the action needs is missing or doesn't fit the action. Check each field against the MqlTradeRequest fields listed for that action in MetaQuotes' reference.

Should I read GetLastError() or the retcode?

Both, but the retcode first. GetLastError() tells you that the call failed (4756), or that the program isn't allowed to trade (4752). The retcode in MqlTradeResult, or trade.ResultRetcode(), tells you why the server refused it.

The programs on this page are minimal examples written to show the error and its fix, not trading systems. Some of them send orders when they run: try them on a demo account. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

Rather not write the error handling yourself?

Edgoro's MT5 EA generator writes complete MQL5 Expert Advisors from plain English 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.