Summary: Advanced deep dive into MQL4 OrderSend function for EA development. Covers each parameter in detail, error handling patterns, slippage calculation, and ticket verification with production-ready code.




`OrderSend()` is the core trade execution function in MQL4. Moving beyond basic usage requires understanding its six parameters, return value nuances, and failure handling patterns that distinguish professional EA code from amateur scripts.

1. Function Signature and Parameter Breakdown

```cpp
int OrderSend(
string symbol, // symbol name
int cmd, // trade operation type
double volume, // lot size
double price, // order price
int slippage, // allowed slippage in points
double stoploss, // stop loss level
double takeprofit, // take profit level
string comment, // order comment
int magic, // EA identifier
datetime expiration, // pending order expiration
color arrow_color // chart arrow color
);
```

2. Slippage Calculation: Points vs Pips

Common mistake: using fixed slippage without market context. Correct approach:

```cpp
double GetDynamicSlippage() {
double spread = MarketInfo(Symbol(), MODE_SPREAD);
double atr = iATR(Symbol(), PERIOD_M5, 14, 1);
// slippage = max(3 spreads, 0.5% of ATR in points)
int minSlippage = (int)MathMax(spread * 3, atr * 0.005 / Point);
return MathMin(minSlippage, 50); // cap at 50 points
}

int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, GetDynamicSlippage(), 0, 0, "EA", magic, 0, Blue);
```

3. Ticket Validation Pattern

`OrderSend()` returns `-1` on failure. Always verify immediately:

```cpp
int SendOrderWithValidation(double lot, double sl, double tp) {
double price = (cmd == OP_BUY) ? Ask : Bid;
int ticket = OrderSend(Symbol(), cmd, lot, price, slippage, sl, tp, comment, magic, 0, clrNONE);

if(ticket < 0) {
int error = GetLastError();
string errMsg = StringFormat("OrderSend failed | Error: %d | Lot: %.2f | Price: %g", error, lot, price);
Print(errMsg);
SendNotification(errMsg); // mobile alert for critical failures
return -1;
}

// Verify order actually exists in pool (defensive programming)
if(!OrderSelect(ticket, SELECT_BY_TICKET)) {
Print("Ticket ", ticket, " not found after OrderSend");
return -2;
}

return ticket;
}
```

4. Managing Magic Numbers for Multi-Strategy EAs

```cpp
#define MAGIC_BASE 202406
#define MAGIC_TREND (MAGIC_BASE + 1)
#define MAGIC_MEAN_REV (MAGIC_BASE + 2)
#define MAGIC_GRID (MAGIC_BASE + 3)

// Group order counting by magic
int CountOpenOrdersByMagic(int magicFilter) {
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magicFilter)
count++;
}
}
return count;
}
```

5. Handling Partial Fills and Re-quote Scenarios

In volatile markets, `OrderSend()` may reject due to price changes. Implement retry logic:

```cpp
int OrderSendWithRetry(int cmd, double lot, int maxRetries = 3) {
for(int attempt = 1; attempt <= maxRetries; attempt++) {
RefreshRates(); // critical: update Ask/Bid before each attempt
double price = (cmd == OP_BUY) ? Ask : Bid;
int ticket = OrderSend(Symbol(), cmd, lot, price, slippage, 0, 0, "", magic, 0, clrNONE);

if(ticket > 0) return ticket;

int error = GetLastError();
if(error == ERR_REQUOTE || error == ERR_PRICE_CHANGED) {
Print("Re-quote, retry ", attempt, "/", maxRetries);
Sleep(50 * attempt); // exponential backoff
continue;
}
break; // non-retryable error
}
return -1;
}
```

6. Complete Production-Ready Order Function

```cpp
bool OpenMarketOrder(int direction, double lotPercent, double riskReward = 2.0) {
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double riskPerTrade = 0.02; // 2% risk
double lot = NormalizeDouble((equity * riskPerTrade) / 10000, 2);
lot = MathMin(MathMax(lot, MarketInfo(Symbol(), MODE_MINLOT)), MarketInfo(Symbol(), MODE_MAXLOT));

double sl = 0, tp = 0;
if(direction == OP_BUY) {
double entry = Ask;
sl = entry - (riskPerTrade * entry);
tp = entry + (riskReward * (entry - sl));
} else {
double entry = Bid;
sl = entry + (riskPerTrade * entry);
tp = entry - (riskReward * (sl - entry));
}

int ticket = OrderSendWithValidation(direction, lot, sl, tp);
return (ticket > 0);
}
```

Reference: MQL4 Documentation, "OrderSend" (docs.mql4.com/trading/OrderSend); Elder, Alexander. "The New Trading for a Living." Wiley, 2023.