In automated algorithmic Forex trading on MetaTrader 5, few occurrences are more maddening for quantitative developers than watching an Expert Advisor (EA) identify a perfect market setup, only to fail at trade dispatch with a cryptic error in the Experts log:
OrderSend error 10030: Unsupported filling mode
TRADE_RETCODE_UNSUPPORTED_FILLING_MODE
Or conversely, an EA fires a market order during a volatile breakout, and due to misconfigured execution parameters, the order suffers 6 pips of severe negative slippage—wiping out the profit target before the trade even matures.
In MetaTrader 4, order execution was comparatively primitive. MT5, however, was engineered to mirror real interbank exchange standards, introducing strict Order Fill Policies (ENUM_ORDER_TYPE_FILLING) and granular Price Deviation (request.deviation) limits.
If your EA hardcodes the wrong fill policy for your broker’s liquidity model (STP, ECN, or Market Maker), your orders will be instantly rejected by the broker trade server.
In this deep-dive quantitative engineering guide, we dissect the three MT5 order fill policies, explain how to write dynamic broker-adaptive execution functions in MQL5, and demonstrate how to optimize execution certainty on a low-latency Windows Server VPS.
🔬 The 3 MQL5 Order Fill Policies Explained
When your EA dispatches a trade via OrderSend(), the MqlTradeRequest structure requires you to specify the type_filling field. This instructs the broker’s matching engine how to handle situations where the requested volume is not fully available at the requested price:
1. ORDER_FILLING_FOK (Fill or Kill):
"Give me my entire requested volume at this exact price, or cancel the whole order!"
[ Requested: 5.0 Lots ] ──> [ Available: 3.5 Lots at Price ] ──> ORDER REJECTED!
2. ORDER_FILLING_IOC (Immediate or Cancel):
"Fill as much volume as you have right now at this price; cancel the rest!"
[ Requested: 5.0 Lots ] ──> [ Available: 3.5 Lots at Price ] ──> 3.5 Lots Filled, 1.5 Lots Cancelled.
3. ORDER_FILLING_RETURN (Partial Fill & Remainder Pending):
"Fill what you can right now; keep the remaining volume active as a pending order!"
[ Requested: 5.0 Lots ] ──> [ Available: 3.5 Lots at Price ] ──> 3.5 Lots Filled, 1.5 Lots Placed on Book.
Why Brokers Reject Hardcoded Policies
Different broker accounts enforce different rules:
- ECN / Interbank Accounts: Typically demand
ORDER_FILLING_IOCorORDER_FILLING_RETURN. If your EA hardcodesORDER_FILLING_FOK, the trade server rejects the order with Error 10030! - Standard Retail STP Accounts: Frequently mandate
ORDER_FILLING_FOK. If your EA sendsORDER_FILLING_IOC, it fails!
An EA that does not dynamically detect the broker’s supported fill policy at runtime will fail the moment you switch brokers or change account tiers.
🛠️ Step 1: Dynamic Broker Fill Policy Detection in MQL5
To build a universal, crash-proof Expert Advisor, query the broker’s supported filling modes using the SYMBOL_FILLING_MODE bitmask:
//+------------------------------------------------------------------+
//| Universal Dynamic Fill Policy Selector for MetaTrader 5 |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE_FILLING GetOptimalFillPolicy(string symbol)
{
// 1. Query the broker's supported fill modes bitmask
uint fillingMode = (uint)SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
// 2. Check for Fill or Kill (FOK) support (Bit 1)
if ((fillingMode & SYMBOL_FILLING_FOK) != 0) {
return ORDER_FILLING_FOK;
}
// 3. Check for Immediate or Cancel (IOC) support (Bit 2)
if ((fillingMode & SYMBOL_FILLING_IOC) != 0) {
return ORDER_FILLING_IOC;
}
// 4. Default fallback: Return (Exchange mode)
return ORDER_FILLING_RETURN;
}
⚡ Step 2: Controlling Slippage with request.deviation
In fast-moving markets, the price quote displayed on your chart can change in milliseconds before your order arrives at the broker’s matching engine in London (LD4) or New York (NY4).
The deviation parameter defines the maximum acceptable price difference (in points) that your EA is willing to accept:
MqlTradeRequest request;
ZeroMemory(request);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 1.0;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.type_filling = GetOptimalFillPolicy(_Symbol); // Dynamic policy!
// -----------------------------------------------------------------
// SLIPPAGE TOLERANCE (DEVIATION):
// For a 5-digit broker, 10 points = 1.0 pip.
// Setting deviation = 20 allows maximum 2.0 pips of slippage.
// -----------------------------------------------------------------
request.deviation = 20;
The Slippage Dilemma: Tight vs Loose Deviation
- Setting
deviation = 0(Zero Tolerance): If the price moves by even 0.1 pip while the packet is in flight, the broker will reject the trade withTRADE_RETCODE_REQUOTE(Error 10004). During high-volatility news breakouts, you will get zero trade fills! - Setting
deviation = 50(5.0 pips): Virtually 100% of your orders will be accepted, but during sudden news spikes, you may enter at an abysmal price. - The Quantitative Sweet Spot:
For standard scalping EAs, set
deviationbetween 10 and 25 points (1.0 to 2.5 pips), combined with hosting on a sub-millisecond low-latency VPS.
🕒 Step 3: Complete Production-Grade Execution Function
Here is a turnkey, battle-tested execution function incorporating dynamic fill policy selection, slippage bounds, and robust error handling:
bool ExecuteMarketOrder(ENUM_ORDER_TYPE orderType, double volume, int maxSlippagePips)
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = volume;
request.type = orderType;
request.price = (orderType == ORDER_TYPE_BUY) ?
SymbolInfoDouble(_Symbol, SYMBOL_ASK) :
SymbolInfoDouble(_Symbol, SYMBOL_BID);
// Automatically bind the broker's legal fill policy
request.type_filling = GetOptimalFillPolicy(_Symbol);
// Convert pips to points (assuming 5-digit broker)
request.deviation = (ulong)(maxSlippagePips * 10);
request.magic = 991823; // Unique EA Magic Number
// Dispatch order to server
if (!OrderSend(request, result)) {
PrintFormat("❌ OrderSend Failed! Error Code: %d", GetLastError());
return false;
}
if (result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED) {
PrintFormat("✅ Order #%d Executed Successfully! Price: %.5f", result.order, result.price);
return true;
} else {
PrintFormat("⚠️ Trade Rejected by Broker! Retcode: %d (%s)", result.retcode, result.comment);
return false;
}
}
🏆 Maximize Execution Certainty on Nextgen Low-Latency VPS
Even the most sophisticated fill logic cannot overcome poor physical network latency. If your VPS takes 150ms to reach the broker server, prices will change constantly in flight, triggering rejections or deviation traps:
- For retail algorithmic traders and proprietary desks in Pakistan, Nextgen Cloud VPS in Pakistan offers high-frequency NVMe drives, dedicated CPU cores, and ultra-reliable Windows Server environments with 99.99% uptime guarantees.
- For high-volume multi-terminal trading operations requiring dedicated 10Gbps cross-connects, bare-metal hardware isolation, and sub-millisecond execution to London (LD4) and New York (NY4), deploy on Nextgen bare-metal Dedicated Servers in Pakistan and international Dedicated Servers.
📚 Related Forex VPS, Windows & Algorithmic Trading Guides
- Bare-Metal Dedicated Server vs Hyper-V VPS for Forex Trading – Benchmark DPC latency and hypervisor stutters.
- Forex Copy-Trading Architecture: Sub-Millisecond Master-Slave VPS – Eliminate copy slippage with local loopback sockets.
- Forex EA Tick Volume & Spread Spike Detection – Protect capital against rollover widening.
Deploy Algorithmic Trading Bots on Low-Latency Windows VPS
Say goodbye to Error 10030 execution rejections, broker requotes, and order slippage. Nextgen delivers low-latency Windows Server Cloud VPS and Bare-Metal Dedicated Servers engineered specifically for quantitative MetaTrader 5 algorithmic trading.
