ERR_NO_MONEY in MQL5: Fix 'Not Enough Money' (134 & 10019)
Contents
- What ERR_NO_MONEY means (134 vs 10019)
- ① ERR_NO_MONEY = 134 (runtime error from `GetLastError()`)
- ② TRADE_RETCODE_NO_MONEY = 10019 (return code from `OrderSend()`)
- 30-second triage
- Causes & fixes (6 patterns)
- ① You genuinely ran out of margin
- ② Lot size is too big for the balance
- ③ Low leverage, or capped on weekends/events
- ④ Margin locked up by existing positions
- ⑤ Bonus/credit counted into margin
- ⑥ Account-type contract size (standard vs cent/micro)
- Broker-specific notes
- MQL5 code to prevent it (for EA developers)
- Check required margin before ordering
- Round the lot to "the largest you can open"
- Always inspect the OrderSend retcode
- Emergency stop on margin level
- Priority checklist
- Summary
- FAQ
- Q: My balance is fine, why ERR_NO_MONEY?
- Q: What's the difference between 134 and 10019?
- Q: It works in backtest but fails live.
- Q: Grid/martingale EAs throw ERR_NO_MONEY as levels deepen.
- Q: Can my EA avoid it automatically?
- Q: What's a comfortable minimum to start with?
ERR_NO_MONEY in MQL5
When your Expert Advisor logs ERR_NO_MONEY or not enough money in the Experts/Journal tab, the natural panic is "am I out of funds?" — but this error fires even when your balance still has plenty in it. The cause is rarely "zero money": it's usually lot sizing, leverage, or margin locked up by existing positions.
This is a single, complete reference for ERR_NO_MONEY aimed at both MT5 users running EAs and MQL5 developers writing them — what it really means, the 6 root causes, instant fixes, and the code to prevent it permanently. For the full list of error codes, see the MQL5 / MT5 error code guide.
This article targets MT5 (build 4xxx) as of June 2026. Exact figures and panel names vary slightly by broker and build.
What ERR_NO_MONEY means (134 vs 10019)
In MQL5 there are two distinct values for "not enough money", depending on where you read it. Confusing them sends you down the wrong debugging path.
① ERR_NO_MONEY = 134 (runtime error from GetLastError())
This is a runtime error code returned by GetLastError(). It's set by calculation functions such as OrderCalcMargin() / OrderCalcProfit(), or older-style code, when "required margin exceeds free margin" is detected.
Meaning: not enough money for the trade operation
Constant: ERR_NO_MONEY
Value : 134
② TRADE_RETCODE_NO_MONEY = 10019 (return code from OrderSend())
The result of an actual OrderSend() lands in MqlTradeResult.retcode. When the server rejects the order for insufficient funds, the code is not 134 but 10019 (TRADE_RETCODE_NO_MONEY).
Meaning: There is not enough money to complete the request
Constant: TRADE_RETCODE_NO_MONEY
Value : 10019
How to tell them apart:
| Source | Value | When it appears |
|---|---|---|
GetLastError() | 134 (ERR_NO_MONEY) | OrderCalcMargin etc., internal checks |
MqlTradeResult.retcode | 10019 (TRADE_RETCODE_NO_MONEY) | OrderSend rejected by the server |
CTrade.ResultRetcode() | 10019 | order placed via CTrade rejected |
A 134 in the log points to the calculation/internal-check stage; 10019 or a server-side not enough money points to the order-rejection stage. The root cause is identical (required margin > usable margin), so the fixes are shared.
30-second triage
Open MT5 → Toolbox → Trade tab and read these three numbers:
Balance : cash in the account
Equity : balance ± floating P/L
Free Margin : margin available for a NEW position ← this is what counts
Margin Level %: Equity / Margin × 100
- If Free Margin is smaller than the margin needed for one new position, you get ERR_NO_MONEY 100% of the time.
- If balance looks fine but it still fires, it's one of "②oversized lot", "④margin locked by open positions", or "⑥account-type contract size" below.
Check the margin for one lot in MT5: Market Watch → right-click symbol → Specification (Margin per lot). The rough formula:
Required margin ≈ (lots × contract size × price) / leverage
Causes & fixes (6 patterns)
① You genuinely ran out of margin
Symptom: floating losses grew and Free Margin dropped below what a new position needs. Common after a losing streak or deep grid/martingale levels.
Fix:
- Deposit more funds, or
- Manually close part of your open positions to free margin
- Lower the EA's
RiskPercentso future lots are smaller
If this repeats, the lot size is simply too large for the account → ②.
② Lot size is too big for the balance
Symptom: balance is there, but ERR_NO_MONEY on the very first order. Common with fixed-lot setups.
Cause: FixedLot isn't matched to balance and leverage. Trying 0.1 lot XAUUSD on a ~$670 account can require more margin than the balance, depending on leverage.
Fix:
- Drop to the minimum lot (0.01) and see if it opens
- Switch to risk-percent auto sizing (
UseFixedLot=false/RiskPercent) - If even 0.01 won't open, leverage or funds are short → ③ / ⑥
Rule of thumb: a sound baseline is 0.01 minimum lot on a ~$670 standard account. Below that, or if you want to run smaller and safer, use a cent/micro account (next section).
③ Low leverage, or capped on weekends/events
Symptom: the same EA/lot opens on another account but throws ERR_NO_MONEY on this one — or the error clusters Friday evening to Monday morning.
Cause: low leverage (e.g. 1:30 EU-regulated vs 1:1000 offshore) changes required margin by tens of times. Brokers also cut leverage around weekends and major news (XM caps leverage to 200:1 over the weekend), so required margin can jump while a position is open. Gold and crypto may have per-symbol leverage caps too.
Fix:
- Check the account leverage (broker portal / MT5 account info)
- Check the per-symbol margin rate in Specification (some symbols are capped lower)
- Use a weekend-flat setting (
CloseAllBeforeWeekend=true) or a broker without weekend caps - Use a higher-leverage account or reduce the lot
④ Margin locked up by existing positions
Symptom: the first position opens, but the 2nd / a grid add-on throws ERR_NO_MONEY.
Cause: open positions already lock margin, so Free Margin dropped below the new requirement. Common when several pairs or several EAs share one account.
Fix:
- Check used Margin vs Free Margin in the Trade tab
- Make sure multiple EAs aren't eating each other's margin on one account
- Grid/martingale EAs consume margin fast as levels deepen → review max levels, lot multiplier, and emergency-close settings
⑤ Bonus/credit counted into margin
Symptom: "balance + bonus" should be enough, yet ERR_NO_MONEY.
Cause: some brokers exclude credit (bonus) from margin calculations, or count only part of it. The displayed balance and the margin the server actually uses diverge.
Fix: check the broker's bonus terms for whether credit counts toward margin. If not, size the lot to fit the real deposit only.
⑥ Account-type contract size (standard vs cent/micro)
Symptom: the same "0.01 lot" suddenly throws ERR_NO_MONEY after switching accounts (or becomes oversized).
Cause: cent/micro and standard accounts differ in contract size by ~100×. A cent account's 0.01 has ~1/100 the real exposure. An EA that uses a fixed lot without distinguishing account type will hit insufficient margin on one of them.
Fix:
- For small/safe operation, use a cent/micro account so the minimum lot isn't over-risked
- Don't hardcode account type — let the EA read actual required margin via
OrderCalcMargin()and size from it (next section)
Broker-specific notes
| Broker | Trait | ERR_NO_MONEY frequency |
|---|---|---|
| XM | weekend leverage cap · Stop Out 20% | medium (higher on weekends) |
| Exness | unlimited-leverage accounts · Stop Out 0% | low |
| HFM / FXGT etc. | high-leverage accounts | low |
Exness unlimited-leverage accounts (Pro/Raw Spread) often let new orders through even with near-zero free margin, so this error is rare there — but the flip side is that stop-out barely triggers, so losses can balloon. See the broker comparison for trade-offs.
MQL5 code to prevent it (for EA developers)
Don't just "fix" ERR_NO_MONEY — swallow it before OrderSend in the EA itself. The principle: compute required margin before ordering, and either skip or shrink the lot if it won't fit.
Check required margin before ordering
// Pre-trade gate: confirm required margin <= free margin before OrderSend
bool HasEnoughMargin(ENUM_ORDER_TYPE type, double lots)
{
double price = (type == ORDER_TYPE_BUY)
? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
: SymbolInfoDouble(_Symbol, SYMBOL_BID);
double margin = 0.0;
if(!OrderCalcMargin(type, _Symbol, lots, price, margin))
{
Print("OrderCalcMargin failed: ", GetLastError()); // 134 etc.
return false;
}
double freeMargin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
if(margin > freeMargin)
{
PrintFormat("Skip: need %.2f > free %.2f (ERR_NO_MONEY guard)", margin, freeMargin);
return false; // don't open = ERR_NO_MONEY never happens
}
return true;
}
Round the lot to "the largest you can open"
If a risk-percent lot exceeds available margin, shrinking it (rather than skipping) reduces missed entries. Normalizing to min lot and lot step is mandatory too — unnormalized lots are a classic rejection cause.
double NormalizeLot(double lots)
{
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lots = MathFloor(lots / step) * step; // snap to step
lots = MathMax(minLot, MathMin(maxLot, lots)); // clamp min..max
return NormalizeDouble(lots, 2);
}
Always inspect the OrderSend retcode
Don't trust only the boolean return of OrderSend() — read result.retcode and handle 10019 (TRADE_RETCODE_NO_MONEY) explicitly.
MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);
// ... build req ...
if(!OrderSend(req, res) || res.retcode != TRADE_RETCODE_DONE)
{
if(res.retcode == TRADE_RETCODE_NO_MONEY) // 10019
Print("Not enough money. Shrink the lot or deposit funds.");
else
PrintFormat("OrderSend failed: retcode=%d, lastError=%d", res.retcode, GetLastError());
}
With CTrade, check trade.ResultRetcode() for 10019, or trade.ResultRetcodeDescription().
Emergency stop on margin level
Halting new entries (or closing all) when margin level drops below a threshold prevents both ERR_NO_MONEY storms and account blow-ups.
double level = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL); // margin level %
if(level > 0 && level < EmergencyMarginLevel) // e.g. 150%
{
// stop new entries / optionally close part of the book
}
The EAs distributed by FXEA365 ship with risk-percent auto lots, a pre-trade margin check, and a margin-level emergency stop (UseMarginEmergencyClose) built in, so they run comfortably from a small starting balance.
Priority checklist
| Priority | Check | Fix |
|---|---|---|
| 🚨 first | Free Margin < required margin | deposit / partial close / lower lot |
| 🚨 first | fixed lot too big for balance | go 0.01 / risk-percent auto |
| ⚠️ next | account leverage too low | higher-leverage account / lower lot |
| ⚠️ next | margin locked by other positions/EAs | tidy positions on the account |
| ✅ check | cent vs standard contract size | size to the account type |
| 🛠 dev | guard with OrderCalcMargin before ordering | implement the code above |
Summary
ERR_NO_MONEYhas two faces — 134 (GetLastError) and 10019 (OrderSend retcode = TRADE_RETCODE_NO_MONEY) — but both come down to "required margin > usable margin".- It fires even with funds present, due to oversized lots, low leverage, margin locked by open positions, or account-type mismatch.
- Traders prevent it with risk-percent auto lots and the right account type; developers fix it for good with a pre-trade
OrderCalcMargingate, lot normalization, and explicit handling of retcode 10019.
For all error codes, see the MQL5 / MT5 error code guide; for free EAs sized to run on a small balance, see the EA list.
FAQ
Q: My balance is fine, why ERR_NO_MONEY?
Sizing is judged on Free Margin, not Balance. Floating losses or margin locked by open positions reduce Free Margin, so a healthy balance can still fail to open a new position. Check Free Margin in the Trade tab.
Q: What's the difference between 134 and 10019?
134 (ERR_NO_MONEY) is a runtime error from GetLastError(); 10019 (TRADE_RETCODE_NO_MONEY) is the result code from OrderSend(). Only the source differs — the cause (insufficient funds) is the same.
Q: It works in backtest but fails live.
The live account's leverage, account type (cent/standard), and existing positions differ from your test setup. Leverage and contract-size differences dominate.
Q: Grid/martingale EAs throw ERR_NO_MONEY as levels deepen.
That's one step before normal margin exhaustion. Each added level consumes margin faster. Lower the max levels and lot multiplier, always enable an emergency close like UseMarginEmergencyClose, and only trade money you can afford to lose.
Q: Can my EA avoid it automatically?
Yes. Before ordering, compute required margin with OrderCalcMargin() and skip (or shrink the lot) if it exceeds AccountInfoDouble(ACCOUNT_MARGIN_FREE). See the code above.
Q: What's a comfortable minimum to start with?
A ~$670 standard account at the 0.01 minimum lot is a sound baseline. For smaller or safer operation, a cent/micro account gives the minimum lot far less real exposure, making ERR_NO_MONEY easy to avoid.
Related
2026-05-18
MQL5 / MT5 Error Codes Explained — ERR_NO_MONEY, ERR_TRADE_DISABLED & More
2026-06-19
MT5 EA Not Working or Not Placing Trades — Won't Start vs Won't Trade, Fixed
2026-05-22
How to Read an MT5 Backtest Report [2026 Guide] — Every Metric Explained
2026-05-18
How to Structure Your EA Demo Testing Period — What to Verify in 3 Months
5-Day Email Course (Free)
Get one email a day covering the essentials of FX automated trading, how to read backtests correctly, and tips for choosing a broker.
* Privacy strictly protected. You can unsubscribe at any time.