Blog
MQL5 Unsupported Filling Mode (10030): FOK, IOC, Return
Quick Answer
TRADE_RETCODE_INVALID_FILL (10030) means the filling type in your order request is not supported by the symbol on your broker. An EA that works on one broker can fail on another because each symbol allows a different set of filling modes.
Read SYMBOL_FILLING_MODE, choose a type the symbol supports (FOK, IOC or Return), and set it with trade.SetTypeFilling() before you send the order.
Key Facts
| Item | Detail |
|---|---|
| Return code | TRADE_RETCODE_INVALID_FILL = 10030 |
| Filling types | ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_RETURN |
| Where to check support | SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE) |
| Request field | MqlTradeRequest.type_filling |
| CTrade setter | trade.SetTypeFilling(...) |
| Why it varies | Symbol, account type and execution mode differ between brokers |
What Filling Mode Controls
The filling mode tells the server what to do when the requested volume cannot be filled completely at the requested price.
| Mode | Behavior | |---|---| | FOK (Fill or Kill) | The whole volume must be filled, or the order is cancelled. | | IOC (Immediate or Cancel) | Fill as much as is available right away, and cancel the rest. | | Return | The unfilled part can stay as an order in the market. Availability depends on the symbol's execution mode and the order type. |
For most retail forex accounts the full volume fills at once, so you rarely notice the difference. The mode still has to be one that the symbol accepts, or the order is rejected.
Why the Error Happens
- The EA hard-codes one filling type, and the symbol on this broker does not allow it.
- You moved the EA to another broker, account type or symbol, such as from forex to metals or indices.
- The execution mode of the symbol differs from the one you tested on.
- You rely on the library default and never check what the symbol supports.
The standard CTrade class has a default filling type that was fine for the broker the author tested on. It is not guaranteed to be valid everywhere, so set it explicitly.
Check Which Modes a Symbol Supports
SYMBOL_FILLING_MODE returns flags. Test them with SYMBOL_FILLING_FOK and SYMBOL_FILLING_IOC:
void PrintFillingModes(const string symbol)
{
long modes = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
bool fok = ((modes & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK);
bool ioc = ((modes & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC);
PrintFormat("%s supports FOK: %s, IOC: %s",
symbol,
fok ? "yes" : "no",
ioc ? "yes" : "no");
}
You can also print the execution mode with SymbolInfoInteger(symbol, SYMBOL_TRADE_EXEMODE). It helps explain why two brokers behave differently.
Pick a Supported Mode Automatically
This helper returns a filling type the symbol reports as supported. It tries FOK first, then IOC, then falls back to Return.
ENUM_ORDER_TYPE_FILLING GetFillingMode(const string symbol)
{
long modes = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
if((modes & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK)
return ORDER_FILLING_FOK;
if((modes & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC)
return ORDER_FILLING_IOC;
return ORDER_FILLING_RETURN;
}
The order of preference is your choice. If you would rather accept partial fills than lose an order, check IOC before FOK.
Using It With CTrade
#include <Trade\Trade.mqh>
CTrade trade;
int OnInit()
{
trade.SetTypeFilling(GetFillingMode(_Symbol));
return INIT_SUCCEEDED;
}
void OpenBuy(double lots)
{
if(!trade.Buy(lots, _Symbol))
{
PrintFormat("Buy failed. Retcode: %u, %s",
trade.ResultRetcode(),
trade.ResultRetcodeDescription());
}
}
If your EA trades several symbols, call SetTypeFilling() again for each symbol before you send its order, because supported modes are per symbol. The standard library also has SetTypeFillingBySymbol(). Check its behavior in your build before you depend on it.
Using a Raw MqlTradeRequest
If you build the request yourself, set the field directly:
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.type_filling = GetFillingMode(_Symbol);
if(!OrderSend(request, result))
PrintFormat("OrderSend failed. Retcode: %u", result.retcode);
Test the Request Before Sending
OrderCheck() validates a request without sending it, and it fills a MqlTradeCheckResult. If the filling type is wrong, the check reports it:
MqlTradeCheckResult check;
if(!OrderCheck(request, check))
PrintFormat("OrderCheck failed. Retcode: %u, %s", check.retcode, check.comment);
This is useful while you port an EA to a new broker. For the other return codes you may meet, see the MQL5 trade retcodes guide. If the order is rejected for its stop levels instead, read how to fix invalid stops (10016).
Common Mistakes
- Hard-coding
ORDER_FILLING_FOKand shipping the EA to every broker. - Setting the filling type once in
OnInit()for the chart symbol, then trading other symbols. - Not logging
ResultRetcode(), so the failure looks like "the EA did nothing". - Testing on a demo account and assuming a live account has the same symbol settings.
- Assuming Return is available for market orders on every symbol.
Why This Matters When You Convert a Strategy
A Pine Script strategy has no filling mode, because the platform simulates fills for you. Once the logic moves to MQL5, the order goes to a real server, and the filling mode becomes a setting you have to choose. This is one more reason results can differ between platforms. Our guide on why a Pine Script strategy gives different results in MQL5 covers the wider list of differences.
FAQ
What does error 10030 mean in MQL5?
It is TRADE_RETCODE_INVALID_FILL. The filling type in your request is not supported for that symbol.
Which filling mode should I use?
Use one the symbol reports as supported. FOK requires the full volume to fill. IOC accepts a partial fill and cancels the rest. Return can leave the unfilled volume in the market where the execution mode allows it.
Why does my EA work on one broker but not another?
Brokers configure filling modes per symbol and per account type, so a hard-coded mode can be valid in one place and rejected in another. Read SYMBOL_FILLING_MODE at run time.
Does the Strategy Tester use the same filling rules?
The tester uses the symbol's settings, but they can differ from your live account. Test with the same broker and symbol you plan to use, and still log the retcode.
Get Order Handling You Can Review
Filling mode, stop validation and retcode checks are easy to forget when you port a strategy by hand. CodeFlowOS generates MQL5 code you can review before you test it in the MT5 Strategy Tester. You can try it on the converter page.
This article is educational. It does not describe trading performance and is not financial advice. Always compile and test code in MetaEditor and the Strategy Tester before using it on a live account.