Execution
Order entry. Every method returns an ExecutionResult and none raises: a timeout, a transport fault and a broker rejection are all results with a reason.
Types
| Alias | Values |
|---|---|
| Side | Literal['buy', 'sell'] |
| OrderType | Literal['market', 'limit', 'stop', 'stop_limit'] |
| Amount | Decimal | str | int |
Execution
Order entry for one tenant. Every method returns a result; none raises.
Place a market or pending order.
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| symbol keyword | str | required | The broker's own symbol name, exactly as the catalogue returns it. MFX Hub never renames an instrument. |
| side keyword | Side | required | "buy" or "sell". |
| volume keyword | Amount | required | Lots, as a Decimal, a string or an int. A float is refused. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| order_type keyword | OrderType | 'market' | "market" (the default), "limit" or "stop". |
| price keyword | Amount | None | None | Entry price of a pending order, as a Decimal, a string or an int. |
| stop_limit_price keyword | Amount | None | None | A |
| sl keyword | Amount | None | None | Stop loss price, as a Decimal, a string or an int. |
| tp keyword | Amount | None | None | Take profit price, as a Decimal, a string or an int. |
| deviation_points keyword | int | None | None | Largest slippage you accept on a market order, in points. |
| expires_at keyword | dt.datetime | None | None | When a pending order expires. Timezone-aware. |
| magic keyword | int | None | None | Your own integer tag on the order, returned on every deal it makes. |
| comment keyword | str | None | None | Up to 31 characters. Longer is refused rather than truncated. |
Returns ExecutionResult
symbol is the broker's own name (EURUSD.sd): MFX never renames an instrument on a tenant's behalf. comment longer than 31 characters is refused rather than truncated, because the terminal cuts it without saying so.
A stop_limit order has two prices: price is the stop price, where the order wakes up, and stop_limit_price is the limit order placed when it does. stop_limit_price is required with stop_limit and refused with any other type; the platform says so, and the refusal comes back as the result.
volume, price, stop_limit_price, sl and tp take a Decimal, a string or an int, and refuse a float.
Cancel a pending order. First class, not a modify with a special case.
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| ticket | int | required | The order's ticket number on the broker. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
Returns ExecutionResult
Move the stop loss, the take profit, or both. At least one is required.
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| ticket | int | required | The order's ticket number on the broker. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| sl keyword | Amount | None | None | Stop loss price, as a Decimal, a string or an int. |
| tp keyword | Amount | None | None | Take profit price, as a Decimal, a string or an int. |
Returns ExecutionResult
Amend a pending order's price, stops or expiry. At least one must change.
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| ticket | int | required | The order's ticket number on the broker. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| price keyword | Amount | None | None | Entry price of a pending order, as a Decimal, a string or an int. |
| stop_limit_price keyword | Amount | None | None |
|
| sl keyword | Amount | None | None | Stop loss price, as a Decimal, a string or an int. |
| tp keyword | Amount | None | None | Take profit price, as a Decimal, a string or an int. |
| expires_at keyword | dt.datetime | None | _Keep | _KEEP | When a pending order expires. Timezone-aware. |
Returns ExecutionResult
What is not given keeps the order's present value, because MetaTrader's amend takes the whole order. A level of "0" clears a stop or a take-profit. For the expiry the three states are told apart: leaving expires_at out keeps the order's own, None makes it good-till-cancelled, and a time sets it. Volume, side, type and symbol cannot be amended — a tenant cancels and places again.
stop_limit_price is a stop-limit order's second price (2.14); on any other order the host refuses it, and the refusal comes back as the result.
price, stop_limit_price, sl and tp take a Decimal, a string or an int, and refuse a float.
Close a position in full.
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| ticket | int | required | The order's ticket number on the broker. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| deviation_points keyword | int | None | None | Largest slippage you accept on a market order, in points. |
Returns ExecutionResult
No comment parameter: PositionClose has no such field and forbids extras, so one would be refused by the platform rather than ignored.
Close a position against an opposite one in the same symbol (hedging accounts).
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| ticket | int | required | The order's ticket number on the broker. |
| by_ticket | int | required |
|
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
Returns ExecutionResult
ticket is the position being closed and by_ticket the opposite one. The smaller of the two disappears and the larger is reduced by its volume, and the spread is paid once and not twice. The result's exec_volume is the volume closed; it has no exec_price, because a close-by has no single price.
Two tickets that are not open positions of the account, in one symbol, on opposite sides are refused before the broker is asked - which is also what a netting account gets, since there the two cannot both exist. The refusal comes back as the result.
Close part of a position — the volume to close, inside the symbol's step.
| Parameter | Type | Default | Description |
|---|---|---|---|
| terminal_id | Id | required | The terminal to act on. Another customer's id answers 404, never 403. |
| ticket | int | required | The order's ticket number on the broker. |
| volume keyword | Amount | required | Lots, as a Decimal, a string or an int. A float is refused. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| deviation_points keyword | int | None | None | Largest slippage you accept on a market order, in points. |
Returns ExecutionResult
Takes a Decimal, a string or an int and refuses a float.
One command and its result. A command belonging to another tenant is a 404, never 403.
| Parameter | Type | Default | Description |
|---|---|---|---|
| command_id | Id | required | The command's id from an earlier result. |
| idempotency_key keyword | str | '' | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
Returns ExecutionResult
Reading is on the execution boundary too: a caller checking what happened to an order must not have to catch an exception to find out that it cannot tell.
Poll until the command is final, or until timeout_s.
| Parameter | Type | Default | Description |
|---|---|---|---|
| command_id | Id | required | The command's id from an earlier result. |
| timeout_s keyword | float | 30.0 | Poll until the command is final, or until |
| idempotency_key keyword | str | '' | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
Returns ExecutionResult
Returns the last answer either way — a command that is still EXECUTING when the time runs out is reported as it is, not raised and not guessed at. A non-final result is never a licence to re-send: an UNKNOWN command may already be a position.
Reason (StrEnum)
Why a command ended as it did.
The platform's dictionary plus the four the SDK itself can conclude. A reason the platform adds later arrives as its own string rather than as one of these — see reason_text — because bucketing a reason the caller has never seen is how a granular vocabulary quietly becomes "failed".
| Member | Value | Meaning |
|---|---|---|
| SUCCESS | 'success' | |
| REQUOTE | 'requote' | |
| INSTRUMENT_DISABLED | 'instrument_disabled' | |
| NO_LIQUIDITY | 'no_liquidity' | |
| MARKET_CLOSED | 'market_closed' | |
| INVALID_STOPS | 'invalid_stops' | |
| INVALID_VOLUME | 'invalid_volume' | |
| INSUFFICIENT_FUNDS | 'insufficient_funds' | |
| TRADE_DISABLED | 'trade_disabled' | |
| REJECTED_OTHER | 'rejected_other' | |
| RATE_LIMITED | 'rate_limited' | |
| EXPIRED | 'expired' | |
| UNKNOWN | 'unknown' | |
| MAINTENANCE | 'maintenance' | A planned maintenance window suspended order placement for this terminal: the API refused it with 403 |
| TRANSPORT_ERROR | 'transport_error' | Concluded by the SDK, never sent by the platform: the request never got an answer. |
| TIMEOUT | 'timeout' | Concluded by the SDK: no answer in time. Never retried — a timed-out order may have been placed, and deal-history reconciliation is the only safe recovery (design ). |
| REFUSED | 'refused' | The platform refused the request itself: a 4xx that is not a rate limit. |
CommandState (StrEnum)
. Final: SUCCEEDED, FAILED, EXPIRED, REJECTED. UNKNOWN is visible and not final.
| Member | Value | Meaning |
|---|---|---|
| ACCEPTED | 'ACCEPTED' | |
| ENQUEUED | 'ENQUEUED' | |
| DELIVERED | 'DELIVERED' | |
| EXECUTING | 'EXECUTING' | |
| SUCCEEDED | 'SUCCEEDED' | |
| FAILED | 'FAILED' | |
| EXPIRED | 'EXPIRED' | |
| REJECTED | 'REJECTED' | |
| UNKNOWN | 'UNKNOWN' |
Tickets
the terminal relates one order, one deal and one position per fill; null where the terminal has none yet.
| Field | Type | Default | Meaning |
|---|---|---|---|
| order | int | None | None | |
| deal | int | None | None | |
| position | int | None | None |
| Parameter | Type | Default | Description |
|---|---|---|---|
| raw | Any | required |
Returns Tickets
ExecutionResult
The whole answer to one execution call. Never raised — always returned.
| Field | Type | Default | Meaning |
|---|---|---|---|
| ok | bool | ||
| idempotency_key | str | The idempotency key this call was made with, so a retry can reuse it without bookkeeping. | |
| client_rtt_ms | float | How long the SDK waited, end to end. Always known, even when nothing else is. | |
| command_id | str | None | None | |
| state | CommandState | None | None | |
| final | bool | False | True once the platform will not change this answer again. |
| retryable | bool | False | Whether sending the same order again under a NEW key can succeed. False while UNKNOWN. |
| duplicate | bool | False | The same key with the same body: this is the original command, not a second one. |
| reason | Reason | None | None | |
| reason_text | str | None | None | The reason exactly as it arrived, including one this SDK version does not know. |
| mt5_retcode | int | None | None | |
| retcode_text | str | None | None | |
| comment_raw | str | None | None | The broker's own comment, verbatim, for a human to read beside the reason. |
| terminal_state | str | None | None | |
| tickets | Tickets | default_factory=Tickets | |
| exec_price | Decimal | None | None | |
| exec_volume | Decimal | None | None | |
| broker_latency_ms | int | None | None | |
| agent_latency_ms | int | None | None | |
| attempts | int | 0 | |
| rerouted_from | str | None | None | The terminal a failover moved this command from, when one did. |
| detail | str | None | None | What the platform said when it refused the request outright. |
| retry_at | dt.datetime | None | None | When sending it again can work: the maintenance window's end, for a |
Build from a Command or a CommandAccepted body, whichever the call answered with.
| Parameter | Type | Default | Description |
|---|---|---|---|
| body | Any | required | |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| client_rtt_ms keyword | float | required |
Returns Self
An answer the SDK concluded itself: no transport, no time, or a refusal.
| Parameter | Type | Default | Description |
|---|---|---|---|
| reason | Reason | required | Your own words, recorded with the action. |
| idempotency_key keyword | str | required | Required on every write and never defaulted. Retrying with the same key returns the original answer; a fresh key asks for a new action. |
| client_rtt_ms keyword | float | required | |
| detail keyword | str | required | |
| retry_at keyword | dt.datetime | None | None |
Returns Self