MT4 · code and request checks
MT4 error 4051 invalid function parameter value
If your EA calls OrderSelect as a switch and you see 4051, here is what my test shows. Selecting position 0 in an empty trade pool returned false and error 4051 in the native MT4 tester.

Arnold Holm · 2026-11-04
What the error means
An EA is a program that applies your trading rules in MT4. The trade pool is the list of open market and pending orders on your account. OrderSelect picks one entry from that list. Error 4051 means one argument was invalid. The original question uses OrderSelect(0, SELECT_BY_POS, MODE_TRADES) as an early return. When the pool holds zero orders there is no position 0 to pick. I ran a small native check in MT4 4.0.0.1491. It ran in the Strategy Tester on EURUSD H4 with offline supplied history and a fixed 20 point spread. It compiled with zero errors and zero warnings. The pool held zero orders. Selecting position 0 returned false and set 4051. A separate invalid symbol property also returned 4051. The valid spread query returned 20 points and error 0. The run made zero order calls. See the OrderSelect documentation for the call shape and the OrdersTotal documentation for the count. The empty pool returned 4051 at position 0. An unrelated invalid symbol property also returned 4051. So the number alone does not tell you which call failed. The call name with its inputs does. I log the failing call and its inputs before changing order logic.
Three code paths to check
1. There is no position 0 to select
A position index only exists while there is an order at that position. An empty pool has no position 0.
2. The symbol property is invalid
An unrelated invalid symbol property also returned 4051. The valid spread query returned 20 points and error 0.
3. The logged error may belong to another call
Other calls may change the error. I log the failing call and its inputs before changing order logic.
A read-only MT4 tester fixture
This check is read only and places no orders. Reset the error right before the suspected selection. Then save the return value and the immediate error before you log anything else. Other calls may change the error. Test once with an empty pool and compare with a run that holds an order.
#property strict
int LookupSpread(int property, long &spread, bool &ok)
{
ResetLastError();
ok = SymbolInfoInteger(Symbol(), (ENUM_SYMBOL_INFO_INTEGER)property, spread);
return GetLastError();
}
int OnInit()
{
if(!IsTesting())
return INIT_FAILED;
const int openOrders = OrdersTotal();
ResetLastError();
bool emptySelection = OrderSelect(0, SELECT_BY_POS, MODE_TRADES);
int selectError = GetLastError();
Print("FIX28 empty pool orders=", openOrders,
" select=", emptySelection, " error=", selectError);
long spread = -1;
bool good = false;
bool bad = false;
int badError = LookupSpread(-1, spread, bad);
int goodError = LookupSpread(SYMBOL_SPREAD, spread, good);
Print("FIX28 bad property accepted=", bad, " error=", badError);
Print("FIX28 spread accepted=", good, " error=", goodError, " points=", spread);
if(openOrders == 0 && !emptySelection && !bad && badError == 4051 && good && goodError == 0 && spread >= 0)
Print("FIX28 RESULT PASS order_calls=0");
else
Print("FIX28 RESULT FAIL order_calls=0");
return INIT_SUCCEEDED;
}
void OnTick() {}
This check runs only in the MT4 Strategy Tester. It never places an order.
How you know it is fixed
Count orders before selecting
If you only want to know if the account holds any open market or pending orders, check the count first. OrdersTotal gives you that count across the account. If any open or pending order should block a new entry, return when OrdersTotal() is greater than zero. If it is zero, do not select position 0 and continue to other entry checks.
Filter positions for your EA
A nonzero count is only a start when your EA must find its own open market positions. Loop through the valid positions from 0 up to the count minus one. Require each selection to succeed before you read the order. Then keep only orders that match your symbol and your magic number and that are market types OP_BUY or OP_SELL. A magic number is a label your EA puts on its own orders so it can find them later. A symbol is the chart name like EURUSD. OP_BUY and OP_SELL mark open buy and sell positions. This scan comes from the docs. It was outside my three tested cases and it places no live orders by itself.
Save the error immediately
Log OrdersTotal, the requested index, the return value and the immediate error on the same line.
Your own source
Find the next line to check
Start with the free EA-Check. Your code stays in your browser. It highlights patterns with line numbers; it does not prove the broker accepts an order.
Want one small change shown on your own case?
DEMO0: send the problem and try a free compiled demo first. R49: one authorised, reproducible MT4/MT5 defect in readable source up to 500 lines, with three agreed cases. 49 USD fixed. Delivery within 48 hours after source review and funding. The exact case is agreed before funded work.
Send the expected and actual behaviourRelated checks
Common questions
Does 4051 mean my broker rejected an order?
No. In my run the pool held zero orders and no order calls were made. Error 4051 flagged an invalid argument in the test call.
Will OrdersTotal find only my EA orders?
No. It counts all market and pending orders on the account. To find only your own open market positions, scan the valid positions and filter by symbol, magic number and OP_BUY or OP_SELL after successful selection.
What did your test not cover?
My receipt covers the empty pool, one invalid symbol property and one valid spread property. It says nothing about live trading or your strategy.
Sources and limits
These public questions explain the error; use your own EA log to check whether the same cause applies.