Orders and reliability

Why an MT5 Trade Can Fail Even When Your API Request Is Correct

Market closed, invalid volume, invalid stops, no margin, wrong symbol: five reasons a broker refuses a valid MT5 order, and how to read and prevent each.

The fxapis team3 min read

In short

  • A well-formed request can still be refused by the broker, because the broker applies its own rules to every order.
  • The five common causes: the market is closed, the volume breaks the symbol's rules, the stops are invalid, there is not enough margin, or the symbol is named differently at this broker.
  • Read the result, not just the status. fxapis returns ORDER_REJECTED with the broker's reason, its MT5 return code, and whether retrying can help.
  • Most rejections can be prevented by checking market hours, the symbol's volume rules and the margin before you send.
On this page
  1. Reading the result first
  2. The five common causes
  3. The cheat sheet
  4. Not every failure is a rejection
  5. Next steps

Your request is valid JSON, your key is right, the account is online — and the order is still refused. The API accepted your request; the broker declined the trade. Brokers check every order against their own rules, and those rules can say no to a request that is perfectly formed.

Reading the result first

With fxapis, a broker refusal comes back as 422 ORDER_REJECTED, with the reason and a retryable flag:

JSON
{
  "error": {
    "code": "ORDER_REJECTED",
    "message": "The broker rejected the order: No money",
    "details": [{ "orderId": "…", "state": "rejected", "retryable": false }]
  }
}

GET /v1/orders/{id} shows the broker's own MT5 return code — 10019 here — exactly as the broker sent it. Nothing executed. The fix depends on the cause.

The five common causes

1. The market is closed

Return code 10018. Forex closes at the weekend, gold takes a daily break, indices follow their exchange's hours — and each broker sets its own hours for each symbol.

Prevent it: check the account's market hours before sending. GET /v1/accounts/{id}/sessions?instrument=XAUUSD returns openNow and nextOpen, read from that broker.

2. The volume breaks the symbol's rules

Return code 10014. Each symbol has a minimum volume, a maximum, and a step. 0.015 lots is invalid where the step is 0.01; 0.01 is invalid where the minimum is 0.1.

Prevent it: read the rules from the account's broker — GET /v1/accounts/{id}/symbols?search=EURUSD returns volumeMin, volumeStep and volumeMax — and round sizes to the step before sending. Send volumes as strings, "0.10", so nothing is rounded on the way.

3. The stops are invalid

Return code 10016. A buy's stop loss must be below the price and its take profit above it (a sell's, the reverse), and brokers often require a minimum distance from the price.

Prevent it: stops are absolute prices, not distances in pips — compute them from the current price, and keep them outside the broker's minimum distance. fxapis refuses a stop on the obviously wrong side before anything is sent.

4. Not enough margin

Return code 10019. The account cannot fund the position at its leverage — common when one signal is sized the same on accounts with very different balances.

Prevent it: POST /v1/accounts/{id}/calculate with "kind": "margin" returns the margin an order needs without opening anything. On multi-account orders, size each account to its balance with weights.

5. The symbol is named differently

Gold is XAUUSD at one broker, XAUUSD.a or GOLD at another. Sending another broker's name fails before it can trade.

Prevent it: send instrument instead of symbol — "instrument": "XAUUSD" — and fxapis trades each account's own symbol for it. If a broker has no match, or two plausible ones, the order is refused before anything is sent, with INSTRUMENT_NOT_OFFERED or INSTRUMENT_AMBIGUOUS.

The cheat sheet

CauseMT5 codeRetry as is?Prevent it with
Market closed10018NoGET …/sessions
Invalid volume10014NoGET …/symbols volume rules
Invalid stops10016NoStops from the current price
Not enough money10019NoPOST …/calculate
Symbol mismatch—Noinstrument instead of symbol
Requote, price moved, no quotes10004, 10020, 10021As a new orderCheck the new price first

Not every failure is a rejection

Two other failures look similar and mean something else:

  • SEND_FAILED (503) — the order provably never reached the broker. Safe to resend, with the same idempotency key.
  • ORDER_UNRESOLVED (503) — nobody knows yet whether it executed. Do not resend. Poll the order; fxapis confirms it against the broker's records.

Next steps

FAQ

Questions people also ask

What does MT5 error 10019 mean?

10019 is TRADE_RETCODE_NO_MONEY: there is not enough free margin on the account to open the order. Reduce the volume or check the margin first; retrying the same order collects the same rejection.

What does MT5 error 10014 invalid volume mean?

The volume breaks the symbol's rules at that broker: below its minimum, above its maximum, or not a multiple of its volume step. Each broker sets these per symbol.

What does MT5 error 10016 invalid stops mean?

The stop loss or take profit is on the wrong side of the price, or closer to it than the broker allows.

Should I retry a rejected MT5 order?

Only when the rejection is transient, such as a requote or a moved price; fxapis marks those retryable. Send it as a new order with a new idempotency key, after looking at the new price. Other rejections will repeat until you change the order.

All in this topic
Orders and reliability

Market Orders vs Pending Orders in an MT5 API

A market order trades now; a pending order waits at the broker for your price. How each behaves in an MT5 API, with one example and a comparison table.

2 min read
> Connect. Execute. Scale.

Trade MT5 from your own code.

Connect accounts by login, password and server, and place orders over HTTPS. We run MetaTrader 5; you install nothing.