OrderSend Error 131: Fix Invalid Volume in MT4
By FXNook Lab team
MT4 OrderSend error 131 means invalid trade volume. The lot size passed to OrderSend does not meet the broker’s minimum, maximum, or lot-step rule for the symbol being traded. Read those limits with MarketInfo, validate the requested lots before the order call, and reject an invalid amount instead of silently rounding it into a different exposure.
Error 131 is different from error 130. Error 130 means invalid stops, such as a stop-loss or take-profit that violates the symbol’s distance rules; error 131 concerns the order volume itself. The relevant MT4 settings are MODE_MINLOT, MODE_MAXLOT, and MODE_LOTSTEP.
What OrderSend error 131 means
OrderSend accepts a volume argument in lots. For example, an EA might request 0.03 lots, but the broker may require at least 0.10 lots, allow only increments of 0.10, or cap the position at a maximum volume. If the requested value falls outside the symbol’s rules, the trade server can reject it with error 131, “invalid trade volume.”
The error can occur even when the EA works on another instrument. Volume rules belong to the symbol, and a broker can set different rules for a major currency pair, a metal, an index, or a share CFD. An EA that reads the limits for the chart symbol but sends an order for a different symbol can therefore validate against the wrong settings.
Error 131 is not a general message that the trade could not be opened. A volume that passes the broker’s rules can still be rejected for another reason, such as invalid stops or insufficient margin. Log the returned error and its context rather than treating every OrderSend failure as a lot-size problem.
For the related stop-distance error, see How to Fix OrderSend Error 130: Invalid Stops in MT4. Keeping volume checks and stop checks separate makes the log easier to interpret.
Check the symbol’s volume rules
In MQL4, MarketInfo returns the trading properties for a symbol. Pass the exact symbol string that will be sent to OrderSend, then read MODE_MINLOT, MODE_MAXLOT, and MODE_LOTSTEP. The corresponding constants are documented in the MQL4 MarketInfo constants reference.
double minLot = MarketInfo(symbol, MODE_MINLOT);
double maxLot = MarketInfo(symbol, MODE_MAXLOT);
double lotStep = MarketInfo(symbol, MODE_LOTSTEP);
MODE_MINLOT is the smallest permitted volume, MODE_MAXLOT is the largest, and MODE_LOTSTEP is the increment the broker accepts. For example, a symbol might allow a minimum of 0.01 lots, a maximum of 50.00 lots, and a step of 0.01 lots. Another symbol or account may use a different combination, so do not hard-code one set of limits for every market.
A requested volume must be within the minimum and maximum and aligned to the permitted step. In the example above, 0.03 is aligned to a 0.01 step, while 0.015 is not. If the minimum is 0.10 and the step is 0.10, a request of 0.05 is below the minimum and a request of 0.15 is off-step.
| Volume problem | Typical cause | Appropriate response |
|---|---|---|
| Below MODE_MINLOT | The EA calculated a smaller volume than the broker permits. | Reject the order or apply an explicit strategy rule for handling the minimum. Do not silently raise the volume if that changes intended risk. |
| Above MODE_MAXLOT | The requested volume exceeds the symbol’s cap, often after a risk calculation or a bad input. | Reject it, or handle it through an explicit design that splits orders only if that behavior is intended and supported. |
| Not aligned to MODE_LOTSTEP | The requested value falls between allowed increments, such as 0.025 with a 0.01 step. | Reject it or use a clearly defined rounding policy and report the resulting volume and risk change. |
| Limits read for the wrong symbol | The EA checks the chart instrument but sends a different symbol. | Read all three properties using the same symbol string passed to OrderSend. |
The values returned by MarketInfo are useful at runtime because they reflect the terminal’s properties for the selected symbol. They do not remove the need to test on the intended broker and account. A demo server, a live server, and a Strategy Tester symbol configuration can expose different trading conditions.
Validate lots before calling OrderSend
The following MQL4 example reads the limits for the order’s symbol, prints the request and limits, and returns without sending an order when the requested volume is invalid. It does not adjust the lot size behind the EA’s back. The submit function is a minimal market-buy example; call it only after the EA’s own entry conditions are met.
bool IsValidLots(string symbol, double lots)
{
double minLot = MarketInfo(symbol, MODE_MINLOT);
double maxLot = MarketInfo(symbol, MODE_MAXLOT);
double lotStep = MarketInfo(symbol, MODE_LOTSTEP);
Print("Volume check: symbol=", symbol,
" requested=", DoubleToString(lots, 8),
" min=", DoubleToString(minLot, 8),
" max=", DoubleToString(maxLot, 8),
" step=", DoubleToString(lotStep, 8));
if(minLot <= 0.0 || maxLot < minLot || lotStep <= 0.0)
{
Print("Volume check failed: invalid symbol volume properties.");
return false;
}
if(lots < minLot || lots > maxLot)
{
Print("Volume check failed: requested lots are outside the min/max range.");
return false;
}
double stepCount = lots / lotStep;
if(MathAbs(stepCount - MathRound(stepCount)) > 0.0000001)
{
Print("Volume check failed: requested lots are not aligned to lot step.");
return false;
}
return true;
}
int SendMarketBuy(string symbol, double lots, int slippage, int magic)
{
if(!IsValidLots(symbol, lots))
return -1;
double ask = MarketInfo(symbol, MODE_ASK);
if(ask <= 0.0)
{
Print("Order not sent: no valid Ask price for ", symbol);
return -1;
}
ResetLastError();
int ticket = OrderSend(symbol, OP_BUY, lots, ask, slippage,
0, 0, "volume preflight", magic, 0, clrNONE);
if(ticket < 0)
{
int err = GetLastError();
Print("OrderSend failed: symbol=", symbol,
" lots=", DoubleToString(lots, 8),
" error=", err);
}
return ticket;
}
In an MQL4 source file, the comparison operators in the code are the usual less-than and greater-than operators; they appear as HTML entities here so the example remains valid HTML. The function checks for missing or inconsistent volume properties before doing the range and step tests. It then sends exactly the requested volume if the checks pass.
The step test compares the requested volume divided by the step with the nearest whole number. That avoids relying on exact floating-point equality, which is unsafe for decimal fractions represented in binary. The tolerance here is for numeric representation only; it is not a reason to accept a volume that is materially off-step.
OrderSend returns a ticket on success and -1 on failure. GetLastError retrieves the terminal error after the failed call, and error 131 points back to invalid volume. For more details on the function parameters and return value, refer to the MQL4 OrderSend reference.
Common causes beyond an incorrect lot input
Symbol-specific rules
One common cause is using limits from Symbol() when the EA is sending an order for another instrument. If an EA loops through several symbols, pass the loop’s symbol name to MarketInfo for all three volume properties and to OrderSend itself. A suffix such as “.a” or “_pro” also matters: the symbol name must match the broker’s name exactly.
EA inputs and defaults
An input such as FixedLots may be valid for one symbol and invalid for another. The same applies when a user changes the input in the EA properties without knowing the broker’s minimum or step. Print the actual runtime value, not only the default shown in the source, because chart settings and saved presets can override it.
Risk-based lot calculations
Risk-based sizing can produce a volume between valid increments. The calculated result might be 0.027 lots while the symbol accepts 0.01 steps, or it might fall below the minimum after a small stop distance or a change in account balance. Check the final calculated value immediately before OrderSend, after all sizing calculations have finished.
Floating-point rounding
Lot calculations often involve division and multiplication, so a value intended as 0.30 can be stored internally as a number very close to 0.30. A tolerance-based step check handles small representation differences. It does not make a genuinely invalid value valid.
NormalizeDouble is not a volume validator
NormalizeDouble rounds a number to a chosen number of decimal places. It does not read the broker’s minimum, maximum, or step, and it cannot determine whether a rounded result is appropriate for the EA’s risk rule. For example, normalizing 0.027 to two decimal places may produce 0.03, but that operation alone does not prove that 0.03 is within the symbol’s allowed range or preserves the intended risk.
Use NormalizeDouble only when you need to control displayed or calculated precision, and still validate the final lots against the symbol’s rules. The order should be rejected when the volume fails the preflight, unless the EA has an explicit and documented policy for selecting a different volume.
If the EA calculates lots from risk
Place the volume validation after the EA has calculated its position size and before OrderSend. A typical sequence is: calculate the intended cash risk, derive the lot amount from the stop distance and symbol properties, apply the EA’s stated rounding policy if there is one, validate the resulting amount, and only then submit the order. Validating an earlier intermediate value is not enough if later code changes the lots.
Rounding down to the nearest allowed step can reduce exposure, but it can also move the actual risk below the requested target. Rounding up can increase exposure. Neither choice is automatically correct for every strategy, so make that policy explicit in the EA and report both the calculated volume and the volume that would be sent.
If the calculated risk-based volume is smaller than MODE_MINLOT, silently replacing it with the minimum can increase the intended risk. If the result is above MODE_MAXLOT, silently clipping it can make the actual risk lower than the target. A conservative implementation can reject the trade and log the requested size, the permitted range, and the reason it was not sent.
For example, an EA may calculate 0.006 lots on a symbol whose minimum is 0.01. The volume check should stop the order and explain that the broker minimum is above the calculated size. The EA should not turn 0.006 into 0.01 without making that exposure change part of its documented sizing rules.
MT4 and MT5 volume checks are different
MT4 reads volume rules with MarketInfo and the MODE_MINLOT, MODE_MAXLOT, and MODE_LOTSTEP constants. MT5 uses symbol properties, commonly retrieved through SymbolInfoDouble with SYMBOL_VOLUME_MIN, SYMBOL_VOLUME_MAX, and SYMBOL_VOLUME_STEP. The selected symbol is still essential: use the properties for the instrument that will receive the trade.
MT5 also has a different trading API and result handling. An EA using the CTrade class can submit an order with methods such as Buy, then inspect the method result and ResultRetcode; MQL5 code can also use OrderCheck before submission to examine a request. MT4’s OrderSend return value and GetLastError workflow are not interchangeable with MT5’s trade request and result structures.
Do not copy an MT4 preflight function into MT5 and expect it to compile or validate the right request. When converting an EA, make sure the volume checks use MT5 symbol properties and that the order logic handles MT5’s position and trade-result model. The MT4 to MT5 converter page explains the broader differences involved in that conversion.
Verify the fix in the log and Strategy Tester
- Log the symbol and requested lots. Include the exact symbol string and the final volume that is about to be submitted, not just an input value from initialization.
- Log the broker limits. Print MODE_MINLOT, MODE_MAXLOT, and MODE_LOTSTEP beside the request so a rejected preflight has an immediate explanation.
- Test the intended instrument. Run the EA on the same symbol name and a comparable account configuration to the one where it is expected to trade.
- Read the order result. A successful OrderSend returns a ticket. If it fails, record GetLastError immediately and distinguish error 131 from errors caused by stops, price, or other trade conditions.
- Compare tester and broker settings. Strategy Tester symbol properties may not match the live broker’s settings, so a passing test does not by itself prove that the live symbol will accept the same lots.
A clean compile only confirms that MetaEditor accepted the source; it does not prove that the volume calculation matches the broker’s rules at runtime. If the EA still does not trade, the Experts and Journal logs can reveal whether the lot preflight rejected it or whether a different entry condition or trade rule stopped the order. For broader checks when an EA does not open trades, see MT4 EA Not Opening Trades: Checks, Causes and Fixes.
If the volume check passes but OrderSend still returns an error, use the logged symbol, volume, and error code to investigate the next cause rather than changing the lot size at random. If you need help tracing an EA’s trade path, the FXNook EA debugger checks the code and explains what is stopping it from trading. The practical next step is to add the preflight log, test it on the target symbol, and make the EA reject any volume that does not match that symbol’s rules.
Questions
What is error 131 in MT4?
Error 131 means the trade server rejected an order because its requested volume is invalid. The lots may be below the symbol’s minimum, above its maximum, or not aligned to its permitted lot step.
How do I find the minimum lot size and lot step in MT4?
Call MarketInfo with the exact symbol name and MODE_MINLOT to read the minimum, then use MODE_LOTSTEP for the permitted increment. MODE_MAXLOT returns the maximum, so log all three values before submitting an order.
Does NormalizeDouble fix OrderSend error 131?
No. NormalizeDouble changes decimal precision but does not check the broker’s minimum, maximum, or volume step. Validate the rounded value against the symbol’s actual rules, and do not round in a way that silently changes intended risk.
What is the difference between MT4 error 131 and error 130?
Error 131 is invalid trade volume, usually because the lots violate the symbol’s minimum, maximum, or step. Error 130 is invalid stops, meaning a stop-loss or take-profit does not meet the broker’s stop requirements.