Trade
Order Lifecycle
Base URL https://trade-api.yellowboxmarkets.com. Conventions, signing and error format:
General Info.
Every endpoint on this page takes a mandatory login — the MT5 account the call applies to.
See the login parameter model.
| Endpoint | Security | Weight | Counts against ORDERS |
|---|---|---|---|
POST /v1/order |
TRADE |
1 | 1 |
PUT /v1/order |
TRADE |
1 | 1 |
DELETE /v1/order |
TRADE |
1 | 1 |
GET /v1/order |
USER_DATA |
1 | — |
GET /v1/openOrders |
USER_DATA |
1 | — |
GET /v1/allOrders |
USER_DATA |
5 | — |
GET /v1/positions |
USER_DATA |
1 | — |
PUT /v1/position |
TRADE |
1 | 1 |
DELETE /v1/position |
TRADE |
1 | 1 |
DELETE /v1/allOpenPositions |
TRADE |
5 | 1 |
POST /v1/batchOrders |
TRADE |
1 per item | 1 per item |
Every TRADE endpoint answers -1017 while the trading surface is switched off, and -5015 when
the execution path is not running — both before anything is queued and before the ORDERS bucket
is charged. The USER_DATA reads on this page stay available in both cases.
Order lifecycle
Read this before writing any order code. The execution model is the one part of this API that has no Binance equivalent.
How an order reaches the market
An order is not executed inside the HTTP request. The API validates it, assigns it a client order id, and writes it to a durable queue. A trade executor drains that queue and issues the operation against the MT5 trade server. The fill is confirmed from the deal record the trade server produces.
That means the HTTP response tells you how far the order got by the time we answered — not necessarily its final state.
newOrderRespType
| Value | Behaviour |
|---|---|
ACK |
Default. Recommended. Returns as soon as the order is durably queued. status is ACCEPTED for a market order and NEW for a pending order. |
RESULT |
Waits up to 5 seconds for the trade server's answer, then returns the terminal state if it arrived. |
newOrderRespType is accepted by POST /v1/order, DELETE /v1/position and POST /v1/batchOrders
only; any other value than ACK or RESULT is -1130. PUT /v1/order, DELETE /v1/order and
PUT /v1/position take no newOrderRespType and always behave like RESULT — they wait up to 5
seconds and then answer with whatever status the operation has reached. DELETE /v1/allOpenPositions
always behaves like ACK.
With RESULT there are three outcomes:
| Outcome | HTTP | Body |
|---|---|---|
| The server filled it | 200 |
status: "FILLED" with dealId, orderId, positionId, price, executedVolume. |
| The server rejected it | 4XX |
The error envelope plus status: "REJECTED", clientOrderId, login, and mt5RetCode. |
| No answer within 5 s | 200 |
status: "ACCEPTED". The order has very likely executed. Confirm on the user data stream or with GET /v1/order. |
Use ACK for bursts. One signal fanned across many accounts should be POST /v1/batchOrders with
ACK; the fills arrive as DEAL and POSITION_UPDATE events.
Status values
Market execution (POST /v1/order with type=MARKET, DELETE /v1/position,
DELETE /v1/allOpenPositions):
| Status | Meaning | Terminal |
|---|---|---|
ACCEPTED |
Durably queued. Not yet confirmed by the trade server. | no |
PARTIALLY_FILLED |
Part of the requested volume executed. executedVolume is what has filled so far; more DEAL events may follow. |
no |
FILLED |
Executed. dealId / positionId are populated and executedVolume equals volume. |
yes |
REJECTED |
The trade server refused it. mt5RetCode says why. |
yes |
IN_DOUBT |
The operation may or may not have reached the trade server, and the service cannot determine which. Do not retry with a new client order id. Check GET /v1/positions and the user data stream; retrying the same newClientOrderId is safe. |
no |
Pending orders (type other than MARKET):
| Status | Meaning | Terminal |
|---|---|---|
NEW |
Accepted. Reported from the moment the placement is durably queued, and while the order rests on the server. NEW alone does not prove the order reached the book — an ORDER_UPDATE with its orderId, or GET /v1/openOrders, does. |
no |
PARTIALLY_FILLED |
Part of the volume has executed; the remainder is still resting. | no |
FILLED |
Fully executed. A position now exists. | yes |
CANCELED |
Cancelled by you or by the broker. | yes |
EXPIRED |
Reached its expiration. | yes |
REJECTED |
Refused at placement. | yes |
New status values may be added. Treat an unrecognised status as non-terminal and keep polling
GET /v1/order.
executedVolume accumulates across deals. MT5 may fill one order with several deals. Each one
arrives as its own DEAL event, and executedVolume on GET /v1/order is their sum while price
is their volume-weighted average. Until the sum reaches the requested volume the status is
PARTIALLY_FILLED; a redelivered deal never double-counts.
Idempotency
newClientOrderId is the idempotency key.
- It must be unique per API key, up to 36 characters,
[A-Za-z0-9-_.]. - Resending a request with a
newClientOrderIdthe key has already used never creates a second order. You get back the stored outcome —ACCEPTEDif it is still in flight, or the terminal result if it has one. - This is what makes a retry after a timeout, a
503, or a dropped connection safe.
A retry is answered from the stored record, not re-validated. This matters most on the
operations whose target moves: retrying a DELETE /v1/position whose position has since closed
returns the stored FILLED outcome rather than -2023, and retrying a PUT /v1/order or
PUT /v1/position whose change has already been applied returns the stored outcome rather than
-5005. The same holds for POST /v1/order and every batchOrders item: a retried BUY_LIMIT
whose price the market has since crossed returns its stored NEW (or later) outcome, not -2021.
The response is built from the record, so a field the first response read from a live snapshot may
be absent on the replay. A newClientOrderId this key already used for a different kind of
operation (an id that placed an order, sent on a close) or for a different login is refused
with -1133 on every endpoint — in a batch, as the error object in that item's slot — and is
neither replayed as this operation nor executed again.
Always set it. If you omit it the service generates one, and you lose the ability to retry
safely, because a retry then looks like a brand new order — including on DELETE /v1/position,
PUT /v1/order, PUT /v1/position and DELETE /v1/allOpenPositions.
Idempotency records are retained for at least 24 hours. After that a reused id is treated as new.
What to do on each failure mode
| Situation | Do |
|---|---|
| Connection dropped, no response | Retry the identical request, same newClientOrderId. |
503 with "execution status is UNKNOWN" (-5009) |
Same: retry identically, or check GET /v1/order?origClientOrderId=. This also covers a failure to queue the order — it may still have been queued, so it is recorded as open, not rejected. |
503 with -5015 "no connection to the trade server" on a TRADE endpoint |
The execution path is not running; nothing was queued and no order exists. Retry with backoff. |
200 with status: "ACCEPTED" and no fill event after a few seconds |
GET /v1/order?origClientOrderId=. Do not send a second order. |
GET /v1/order shows REJECTED with -1000 "Service is currently unavailable" |
The service could not queue the order within about a minute of accepting it (for example the trade executor was down), so it expired it unexecuted rather than send it late at a different price. Nothing executed. Retrying the same newClientOrderId sends it as a fresh order — decide against the current market first. |
status: "IN_DOUBT" |
Reconcile against GET /v1/positions before doing anything else. |
4XX with a validation code (-11xx, -40xx) |
Fix the request. The order does not exist. |
4XX with -5001 (requote) or -5002 (price changed) |
The order did not execute. Re-price and send a new newClientOrderId. |
Comments and deal attribution
The MT5 comment field is how an execution is traced back to the request that caused it, so the
service reserves part of it.
- Your
commentmay be up to 24 characters. - The service appends a short correlation tag, making the stored MT5 comment
<your comment><tag>. The tag is 7 characters and is not documented as a parseable format — do not build against it. - On the user data stream,
DEAL.cis the MT5 comment as stored, tag included. Strip the last 7 characters to recover what you sent, or simply ignorecand useC. DEAL.Cis the resolvedclientOrderId— the field to route on. The service resolves it from the tag, or directly from the trade server's answer when the server provides one.- The tag is also set on closes and SL/TP modifications this API issues, so
DEAL.con an API-initiated close carries a tag too, and that close is attributable to thenewClientOrderIdyou sent onDELETE /v1/position.
A deal produced by the account holder, the broker, or a stop loss or take profit firing carries no
tag. Those deals arrive with no C, which is how you tell them apart from your own.
Hedging
Positions are hedged. A BUY on a symbol that already has a SELL position opens a second,
independent position with its own positionId; it does not net against the first. Closing is
always by positionId.
There is no positionSide parameter and no netting mode.


