Blog / Fix MT5 errors · Trade errors · MQL5 · Risk management
“Not Enough Money” in MT5: How to Validate Lot Size Before Sending an Order
Prevent the MT5 not enough money error by validating lot size, calculating required margin and checking trade requests in MQL5.
· 6 min read
What Does "Not Enough Money" Mean in MT5?
The MT5 "Not enough money" error occurs when an account cannot support a requested trade with its available margin.
The corresponding trade-server return code is TRADE_RETCODE_NO_MONEY (10019).
For example, an EA may attempt to open a 1.00-lot EURUSD position when the account has insufficient free margin. The trade server rejects the request because the account cannot support the required margin.
The problem is not always an excessively large lot size. Existing positions, pending orders, leverage, instrument specifications and changing market conditions can also affect available margin.
To prevent unnecessary rejections, an EA should validate the requested volume and check the account's margin before submitting an order.
Why Does an EA Get the Not Enough Money Error?
These are the main causes:
1. The Requested Lot Size Is Too Large
Larger positions generally require more margin.
An EA using a fixed lot size may work on a well-funded account but fail on a smaller account.
For example, a 1.00-lot trade may be affordable on one account but exceed the available margin on another.
Fix: Calculate the required margin for the actual symbol and proposed volume instead of assuming a fixed lot size is always affordable.
2. Existing Trades Have Consumed Available Margin
Free margin is the amount currently available to support additional trades.
An account can have a substantial balance but little free margin remaining if existing positions are already using most of its available funds.
This is particularly important for grid and martingale EAs, which may continue opening positions as exposure increases.
Fix: Check ACCOUNT_MARGIN_FREE and evaluate the proposed trade against the account's existing exposure.
3. Leverage or Instrument Requirements Increase Margin
Leverage affects the margin required to open a position. Other conditions, including the instrument, account type and position size, can also affect the calculation.
A 0.10-lot forex trade and a 0.10-lot index or cryptocurrency trade may require very different amounts of margin.
Fix: Calculate margin for the actual symbol and proposed order. Avoid relying on a universal margin formula.
4. The EA Calculates an Invalid Volume
An EA may calculate a lot size that exceeds the symbol's maximum volume or does not follow its permitted volume step.
This is technically different from insufficient margin, but both problems can cause trade requests to fail.
Fix: Validate the requested volume against the symbol's trading specifications before checking margin.
Step 1: Validate the Requested Lot Size
MT5 symbols have volume specifications that determine which trade sizes are permitted.
| Property | Meaning |
|---|---|
SYMBOL_VOLUME_MIN |
Minimum permitted volume |
SYMBOL_VOLUME_MAX |
Maximum permitted volume |
SYMBOL_VOLUME_STEP |
Permitted volume increment |
For example, a symbol might have a minimum volume of 0.01 lots, a maximum of 100 lots and a volume step of 0.01.
If an EA calculates 0.037 lots, it cannot submit that volume when the permitted increment is 0.01. It must adjust the volume or reject the calculation.
MQL5 example: Normalising volume
The following function checks the symbol's volume limits and rounds the requested volume down to the nearest permitted step. Lot size normalization in MT5 explains the three limits in more detail.
bool NormalizeVolume(
string symbol,
double requested_volume,
double &normalized_volume
)
{
double min_volume = SymbolInfoDouble(
symbol,
SYMBOL_VOLUME_MIN
);
double max_volume = SymbolInfoDouble(
symbol,
SYMBOL_VOLUME_MAX
);
double volume_step = SymbolInfoDouble(
symbol,
SYMBOL_VOLUME_STEP
);
if(!MathIsValidNumber(requested_volume) ||
requested_volume <= 0 ||
min_volume <= 0 ||
max_volume <= 0 ||
volume_step <= 0)
{
Print("Invalid volume or symbol specifications.");
return false;
}
if(requested_volume < min_volume ||
requested_volume > max_volume)
{
Print("Requested volume is outside permitted limits.");
return false;
}
double steps = MathFloor(
requested_volume / volume_step + 1e-8
);
normalized_volume = NormalizeDouble(
steps * volume_step,
8
);
if(normalized_volume < min_volume ||
normalized_volume > max_volume)
{
Print("Normalized volume is outside permitted limits.");
return false;
}
return true;
}For example, if the volume step is 0.01, a requested volume of 0.037 becomes 0.03.
Rounding down prevents the EA from unintentionally increasing its original position size. If the resulting volume falls below the minimum permitted size, the EA should reject the trade.
This function validates individual trade volume. A production EA should also consider SYMBOL_VOLUME_LIMIT where the broker imposes an aggregate directional volume limit.
Step 2: Calculate the Required Margin
Once the volume is valid, the EA can estimate how much margin the proposed trade requires.
MQL5 provides OrderCalcMargin() for this purpose.
bool CheckRequiredMargin(
string symbol,
ENUM_ORDER_TYPE order_type,
double lots
)
{
MqlTick tick;
if(!SymbolInfoTick(symbol, tick))
{
Print("Unable to retrieve current market prices.");
return false;
}
double price = (order_type == ORDER_TYPE_BUY)
? tick.ask
: tick.bid;
double required_margin = 0.0;
if(!OrderCalcMargin(
order_type,
symbol,
lots,
price,
required_margin
))
{
Print(
"Margin calculation failed. Error: ",
GetLastError()
);
return false;
}
double free_margin = AccountInfoDouble(
ACCOUNT_MARGIN_FREE
);
PrintFormat(
"Required margin: %.2f | Available free margin: %.2f",
required_margin,
free_margin
);
if(required_margin > free_margin)
{
Print("Insufficient free margin for this trade.");
return false;
}
return true;
}The function retrieves the current Bid or Ask price, estimates the required margin and compares it with the account's available free margin.
If the estimated requirement exceeds free margin, the EA rejects the trade before submitting it.
Important limitation: OrderCalcMargin() calculates the proposed trade as if the account had no existing positions or pending orders. Its result is an estimate, not a complete assessment of the account's resulting margin.
That is why a final check using OrderCheck() is also important.
Step 3: Check the Trade Request with OrderCheck()
OrderCheck() evaluates a prepared trade request and returns information about the account's projected state after the proposed operation.
Its result is stored in an MqlTradeCheckResult structure, which includes:
retcode: The check's return code.margin: Projected margin.margin_free: Projected free margin.margin_level: Projected margin level.comment: Description of the check result.
For example:
MqlTradeRequest request = {};
MqlTradeCheckResult check = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
{
Print("Unable to retrieve current prices.");
return;
}
request.price = tick.ask;
ResetLastError();
if(!OrderCheck(request, check))
{
PrintFormat(
"Order check failed. Error: %d | Retcode: %u | Comment: %s",
GetLastError(),
check.retcode,
check.comment
);
return;
}
PrintFormat(
"Order check completed. Required margin: %.2f | Free margin after check: %.2f",
check.margin,
check.margin_free
);This is a simplified market Buy request for demonstrating the margin check. A production request must also include any other fields required by its execution mode and broker, such as the appropriate filling policy.
If the check fails, the EA should inspect the returned information rather than sending the request anyway.
Passing OrderCheck() does not guarantee execution. Prices, margin requirements and account conditions can change before the trade reaches the server.
Step 4: Inspect the Actual Trade Result
Even after volume validation and margin checks, the EA must inspect the final response.
For a market order sent using OrderSend(), check both its function result and the server return code.
MqlTradeResult result = {};
ResetLastError();
if(!OrderSend(request, result))
{
PrintFormat(
"OrderSend failed. Error: %d | Retcode: %u | Comment: %s",
GetLastError(),
result.retcode,
result.comment
);
return;
}
PrintFormat(
"Trade response: Retcode=%u | Comment=%s",
result.retcode,
result.comment
);A successful OrderSend() return value does not necessarily mean the trade was executed. The EA must inspect result.retcode and handle the response appropriately.
For a market deal, TRADE_RETCODE_DONE (10009) indicates completion, while TRADE_RETCODE_DONE_PARTIAL (10010) indicates partial execution.
If the server returns TRADE_RETCODE_NO_MONEY (10019), the account could not support the requested operation when it was processed.
What Should an EA Do When the Requested Lot Size Exceeds Available Margin?
The EA needs a clear rule for handling an unaffordable trade.
There are two practical approaches.
1. Reject the Trade
This is the simplest approach.
If the requested volume requires more margin than the account can support, the EA should log the reason and skip the trade.
This is particularly important when the strategy uses a fixed risk model and must not change its intended exposure automatically.
2. Recalculate the Volume Within Defined Limits
Some EAs are designed to reduce position size when the original volume is unaffordable.
However, the EA should not repeatedly reduce the lot size until the broker accepts the trade.
Any adjusted volume must still satisfy:
- The symbol's minimum and maximum volume.
- The permitted volume step.
- The strategy's risk-management rules.
- The account's margin requirements.
If the minimum valid volume is still unaffordable, the EA should skip the trade.
Reducing volume also changes the strategy's intended exposure. It should only happen when the EA's risk-management design explicitly allows it.
Margin Validation Is Not the Same as Risk Management
Passing a margin check does not mean a position is appropriately sized.
Margin determines whether the account can support a trade. Risk-based position sizing determines how much the trader is prepared to lose if the market moves against the position.
An EA needs both controls.
For example, a 0.50-lot trade might be affordable based on available margin but still expose the account to more risk than the strategy permits.
The EA should therefore calculate position size according to its risk rules before checking whether the resulting trade is affordable.
Can PositionAlpha Help Fix Lot Size and Margin Errors?
If an EA repeatedly attempts to open positions that the account cannot support, the problem may involve its position-sizing formula, margin validation or order-submission logic.
With PositionAlpha's Fix an EA, you paste or upload the EA and describe the problem. The AI returns the complete updated .mq4 or .mq5 file and explains the problems it found and each change it made. Compile the result in MetaEditor and test it in the Strategy Tester and on a demo account before you rely on it.
Conclusion
The MT5 not enough money error occurs when an account cannot support a requested trade with its available margin.
Preventing it requires more than checking the account balance. An EA should validate the requested volume, estimate the required margin, check the prepared request and inspect the final server response.
MQL5 functions such as OrderCalcMargin() and OrderCheck() make these checks possible.
By combining volume validation, margin checks and risk-based position sizing, developers can reduce avoidable trade rejections and make their Expert Advisors more reliable.
Build a bot from your idea
Describe your trading idea and the AI writes MT4 or MT5 code for you to review and test, with a plain-English explanation and setup steps. Your first bot is free.