What it means
The code calls a function whose result says whether it worked, and ignores that result. The program compiles, with warning 83, but if the call fails the EA carries on as if it had succeeded. For OrderSend() that means an EA that thinks it has a position it never opened.
Usual causes
OrderSend(req, res);on its own line. The most common case.- Other trade functions. In MetaEditor build 6275 the warning also appears for
OrderSendAsync(),OrderCheck(),OrderSelect()andOrderCalcMargin()when their result is ignored.
The compiler doesn't warn about every function: PositionSelect(), SymbolSelect() and the standard library's CTrade methods such as trade.Buy() produce no warning when their result is ignored. That doesn't make ignoring it a good idea.
How to detect it
- MetaEditor's Errors tab lists
return value of 'OrderSend' should be checkedwith the line of the call.
Broken code
This script compiles with one warning on line 11, and reports "Bought" whether or not anything was bought.
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.type_filling = ORDER_FILLING_IOC;
OrderSend(req, res);
Print("Bought"); // printed even when the order failed
}Fixed code
The same program, corrected. It compiles in MetaEditor with 0 errors and 0 warnings.
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.type_filling = ORDER_FILLING_IOC;
if(!OrderSend(req, res))
{
PrintFormat("OrderSend failed: error %d, retcode %u (%s)", GetLastError(), res.retcode, res.comment);
return;
}
if(res.retcode == TRADE_RETCODE_DONE)
PrintFormat("Bought %.2f lots, deal #%I64u", res.volume, res.deal);
else
PrintFormat("Not done: retcode %u (%s)", res.retcode, res.comment);
}Why the fix works
The result of OrderSend() now decides what happens next: on false, the script logs the error and the retcode and stops; on true, it still checks the retcode, because true only means the request was accepted. Only a completed request (10009, TRADE_RETCODE_DONE) is reported as a purchase.
Assigning the result to a variable you never read (bool ok = OrderSend(req, res);) also makes the warning disappear, and fixes nothing. The point of the warning is the if.
Questions
Is "return value should be checked" an error?
No, a warning: the program compiles and runs. But it points at a real weakness: if the call fails, the code never finds out.
Why don't I get the warning with CTrade's Buy()?
Because the compiler only flags certain built-in functions. trade.Buy() returns false on failure all the same, so check it and read trade.ResultRetcode().
Isn't OrderSend() returning true enough?
No. True means the request passed the basic checks and was accepted by the server. Read the retcode to know what happened: 10009 for a completed request, 10008 for a placed order, 10010 for a partial fill.
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.