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 MqlTradeRequest and 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

  1. Open MetaEditorFile → New → Expert Advisor (template) and name it OrderCheckExample.
  2. Paste the code above and press F7 to compile.
  3. Attach the EA to a chart with a trading-enabled symbol and enable AutoTrading.
  4. Watch the Experts tab for the OrderCheck() retcode and details (normalized volume, price, margin, comment).
  5. 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