Symbols
You write XAUUSD. We send whatever your broker calls it.
Brokers do not agree on names.
| Instrument | Exness | Deriv | Also seen |
|---|---|---|---|
| Gold | XAUUSDm | XAUUSD | GOLD, XAUUSD.p, XAUUSD.raw |
| Euro/dollar | EURUSDm | EURUSD | EURUSD.a, EURUSDc |
Send XAUUSD straight to Exness and the order is rejected, because that instrument
does not exist there. So you always send the canonical name, and we translate it
for each account.
Why per account, not per broker
Which symbols an account has depends on its account group, not just its broker. Two Exness logins on the same server can have different instruments. That is why we map against the symbol list your account actually has, rather than a table.
Checking a name before you trade
await client.account(id).resolveSymbol("XAUUSD");
// { canonical: "XAUUSD", brokerSymbol: "XAUUSDm", tradable: true, how: "affix" }
how says how we matched it: override (you pinned it), exact, affix (the
account's suffix or prefix), currency (matched on base and quote currency), or
raw (the broker's own name, below).
Instruments with no canonical name
Brokers list instruments no standard name covers. Send the broker's exact name and it
trades: symbols({ all: true }) lists them with canonical: null. Exact means exact;
a near miss is refused, not guessed.
When we cannot map a name
We refuse rather than guess. A wrong guess is a real position in the wrong instrument.
symbols() lists those names under unresolved, with the reason, and an order for
one returns 400 bad_request.
Pinning a mapping yourself
await client.account(id).setSymbolOverride("XAUUSD", "GOLD"); // pin it
await client.account(id).setSymbolOverride("XAUUSD", null); // hand it back
A pin is for a canonical name, and it chooses between symbols the account really has:
pinning GOLD (not canonical) or a symbol the account lacks is refused with a
bad_request that says so, rather than saved and ignored. It applies to everyone
trading that account: every key, bot and teammate.
Telling us your broker's names up front
If you already know what your broker calls things, send a symbol map when you connect. Each canonical name gets up to five spellings, tried in order; the first one the account has is used.
await client.connect({
platform: "mt5", login, password, server,
symbolMap: { XAUUSD: ["XAUUSDm", "GOLD"], BTCUSD: ["BTCUSDm", "XBTUSD"] },
});
await client.account(id).setSymbolMap({ XAUUSD: ["GOLD"] }); // replace it later; {} clears it
A spelling the account does not have is skipped, and a name none of them match falls
back to the automatic mapping. Keys must be canonical names; anything else is refused
before the account is saved. A pin from setSymbolOverride outranks the map. The map
is names only: lot sizes and risk belong in your own code.
tradable: false
The broker lists the symbol but is not taking new orders on it, for example outside market hours or while it is close-only. Orders for it are refused with a clear message.
What can go wrong
| You see | It means |
|---|---|
| 400, "… is not available on this account" | Not on this account, or we could not map it. Check unresolved. |
| 400, "… cannot be traded on this account right now" | Mapped, but tradable: false. |
| An override that changes nothing | The symbol you pinned is not in this account's list. |