Overview
Before you call OrderSend() in MQL5, you must prepare a valid trade request and verify the trading environment. This includes checking terminal permissions, symbol settings, volume constraints, filling mode, and prices. Use OrderCheck() to validate a request and review the broker’s response before sending a live order.
Ad
What You Will Be Able to Do
- Build a proper
MqlTradeRequestand understand each key field. - Validate the request with
OrderCheck()and read the check result. - Confirm environment readiness: trading permissions, volume limits, filling mode, and price data.
- Identify common rejection causes and fix them before calling
OrderSend().
Code Example
//+------------------------------------------------------------------+
//| OrderCheckExample.mq5
//+------------------------------------------------------------------+
#property version "1.00"
#property strict
input double Lots = 0.10;
input int Deviation = 10; // max slippage (points) for market order
//--- helper: pick supported filling mode
ENUM_ORDER_TYPE_FILLING GetFillingMode(const string sym)
{
int fm = (int)SymbolInfoInteger(sym, SYMBOL_FILLING_MODE);
if(fm == ORDER_FILLING_FOK || fm == ORDER_FILLING_IOC || fm == ORDER_FILLING_RETURN)
return((ENUM_ORDER_TYPE_FILLING)fm);
return(ORDER_FILLING_FOK);
}
int OnInit()
{
Print("OrderCheckExample initialized on ", _Symbol);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
Print("OrderCheckExample stopped.");
}
void OnTick()
{
// run once for demonstration
static bool done = false;
if(done) return;
done = true;
string sym = _Symbol;
// 1) Environment checks
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQL5InfoInteger(MQL5_TRADE_ALLOWED))
{ Print("Trading not allowed in terminal or MQL5 settings."); return; }
if(!SymbolInfoInteger(sym, SYMBOL_TRADING_ALLOWED))
{ Print("Trading not allowed for symbol: ", sym); return; }
// 2) Volume checks and normalization
double vol_min = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
double vol_max = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
double vol_step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
double volume = MathMax(vol_min, MathMin(Lots, vol_max));
volume = MathRound(volume/vol_step) * vol_step;
if(volume < vol_min || volume > vol_max)
{ Print("Volume out of range after normalization. vol=", DoubleToString(volume, 2)); return; }
// 3) Price and digits
double ask = 0.0;
if(!SymbolInfoDouble(sym, SYMBOL_ASK, ask) || ask <= 0.0)
{ Print("Failed to read ASK price for ", sym); return; }
int digits = (int)SymbolInfoInteger(sym, SYMBOL_DIGITS);
double point = SymbolInfoDouble(sym, SYMBOL_POINT);
// 4) Prepare request
MqlTradeRequest req; ZeroMemory(req);
MqlTradeResult res; ZeroMemory(res);
MqlTradeCheckResult chk; ZeroMemory(chk);
req.action = TRADE_ACTION_DEAL; // market order
req.symbol = sym;
req.type = ORDER_TYPE_BUY; // example: Buy at market
req.volume = volume;
req.price = ask;
req.deviation = Deviation;
req.type_filling= GetFillingMode(sym); // FOK / IOC / RETURN
req.type_time = ORDER_TIME_GTC; // good-till-cancelled
req.sl = 0.0; // set later if needed
req.tp = 0.0; // set later if needed
req.comment = "Pre-check only";
// 5) Validate
if(!OrderCheck(req, chk))
{
Print("OrderCheck() call failed: retcode=", chk.retcode);
return;
}
// 6) Inspect check result
Print("Check retcode=", chk.retcode, " volume=", DoubleToString(chk.volume, 2),
" price=", DoubleToString(chk.price, digits),
" margin_free=", DoubleToString(chk.margin_free, 2));
if(chk.retcode == TRADE_RETCODE_DONE || chk.retcode == TRADE_RETCODE_DONE_PARTIAL)
{
Print("Check succeeded. Request is likely valid on broker side.");
// Safety: do NOT send in this example. Uncomment to place an order:
// if(OrderSend(req, res))
// Print("OrderSend OK: order=", res.order, " deal=", res.deal);
// else
// Print("OrderSend failed: retcode=", res.retcode);
}
else
{
Print("Check rejected: ", chk.comment, " retcode=", chk.retcode);
}
}
Ad
Execution Steps
- Open MetaEditor → File → New → Expert Advisor (template) and name it
OrderCheckExample. - Paste the code above and press F7 to compile.
- Attach the EA to a chart with a trading-enabled symbol and enable AutoTrading.
- Watch the Experts tab for the
OrderCheck()retcode and details (normalized volume, price, margin, comment). - Only after successful checks should you consider uncommenting
OrderSend()for live or demo execution.
Key Point
Validate first, trade second. Always normalize volume, confirm symbol settings, pick a supported filling mode, and run OrderCheck(). Proper pre-trade checks prevent most rejections and improve EA reliability.
Ad
Next Section
→ Next: Running in the Strategy Tester


