Understand the basics and learn everything you need to start using the B2TRADER API Understand the basics and learn everything you need to start using the B2TRADER API Consult an in-depth reference describing REST API requests and responses Consult an in-depth reference describing REST API requests and responses Explore the supported WebSocket API methods and streams Explore the supported WebSocket API methods and streams Connect to the FIX 4.4 API for market data streaming and order execution Connect to the FIX 4.4 API for market data streaming and order execution ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Trading API: Stop orders for closed markets [#trading-api-stop-orders-for-closed-markets] The **Trading API** now accepts **Stop** orders for markets that are closed according to their trading calendar. The order is stored and activates automatically when the market reopens, instead of being rejected at submission. #### Reports API: full account history [#reports-api-full-account-history] Trading reports can now be generated for the entire account history. The previous **92-day** limit has been removed, and an **All data** range is now available for report generation. #### Trading API: market asset identifiers [#trading-api-market-asset-identifiers] The `baseAssetId` and `quoteAssetId` fields have been added to the v6 `/markets` responses, allowing clients to resolve the base and quote assets of each market without additional lookups. #### Accurate unrealized PnL [#accurate-unrealized-pnl] Unrealized PnL returned by the API is now calculated using the correct order book side for each position direction, improving the accuracy of PnL values in position and margin responses. *** ### Resolved issues [#resolved-issues] * Resolved an issue where `WebhookAlert` order reason and position modifier values were returned as numeric codes instead of API enum strings in History API `/v2/orders` responses. ## April 9, 2026 [#april-9-2026] ### New features [#new-features] #### Trading credit in API responses [#trading-credit-in-api-responses] Broker-issued **trading credit** is now exposed through the API. The account margin data response and the real-time margin stream include the current credit amount in the Reference Asset (`creditInRAT`). Credit is included in the account equity and excluded from the withdrawable amount. *** ### Improvements [#improvements-1] #### Webhook Trading API: webhook URL in key listing [#webhook-trading-api-webhook-url-in-key-listing] The list webhook API keys response now includes the `webhookUrl` field, so the configured webhook endpoint can be retrieved for each key. ## March 16, 2026 [#march-16-2026] ### New features [#new-features-1] #### Webhook Trading API [#webhook-trading-api] A new **Webhook Trading API** has been added, enabling automated order creation via webhook alerts with API key authentication. **Key points:** * Create and manage webhook API keys for secure authentication * Receive trading alerts and create orders automatically * Idempotency supported via deduplication ID * Market type routing by symbol prefix (spot, CFD, perpetual) #### Public Account ID [#public-account-id] A new `publicAccountId` field has been added across all API endpoints, providing a human-readable account identifier as an alternative to internal UUIDs. **Affected APIs:** * Trading API — account-related responses and filters * Settings API — account configuration endpoints * History API — all REST endpoints and WebSocket streams * Reports API — report responses and filters #### Long-term trading data history [#long-term-trading-data-history] Date range restrictions have been removed from **Order History** and **Closed Positions** endpoints, allowing access to full trading history without time-based limitations. *** ### Improvements [#improvements-2] #### Transfer subtype field [#transfer-subtype-field] A new `subtype` field has been added to transfer responses in the History API to distinguish **Negative Balance Protection** transfers from manual ones. #### Rounded position prices [#rounded-position-prices] The `positionPriceInRAT` values are now properly rounded in closed position API responses according to the Reference Asset (RAT) scale. *** ### Resolved issues [#resolved-issues-1] * Resolved an issue where `/total-swaps` requests returned HTTP 504 timeout errors. ## March 11, 2026 [#march-11-2026] ### Added FIX API documentation [#added-fix-api-documentation] Added new FIX API section covering Market Data and Trading sessions via the FIX 4.4 protocol. ## March 11, 2026 [#march-11-2026-1] ### Initial version [#initial-version] ## March 2, 2026 [#march-2-2026] ### New features [#new-features-2] #### Trading Terminal AI assistant [#trading-terminal-ai-assistant] A new **AI assistant** has been added to the Trading Terminal, providing traders with an intelligent widget for market analysis and trading support. *** ### Improvements [#improvements-3] #### Public Account ID (preview) [#public-account-id-preview] The `publicAccountId` field has been added to account-related API responses as a preview, ahead of the full rollout across all endpoints. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-3] #### Funding Rates API [#funding-rates-api] New API endpoints have been added for retrieving funding rate data synchronized from **B2CONNECT**, including funding rates, mark price, and funding interval for Perpetual Futures markets. **Key points:** * Funding rate values streamed in real time * Mark price used for position valuation when available from LP * Funding interval synchronized per market configuration * FIX API contract extended with funding data fields #### OHLC Candlestick API [#ohlc-candlestick-api] A new API endpoint has been added for retrieving OHLC (candlestick) data, supporting both **Spot** and **Perpetual Futures** markets. Minute-level candle data is now stored for up to 5 years. OHLC candle data streaming is also available via the WebSocket API using gRPC transport, providing real-time candlestick updates. #### Favorite markets [#favorite-markets] A new **Favorite markets** feature has been added, allowing traders to manage personalized market lists via the Trading API. #### Comment field for orders and positions [#comment-field-for-orders-and-positions] A new `comment` field has been added to order and position responses across REST, WebSocket, and History APIs. The comment can be set when placing an order and is propagated to the associated position and execution records. #### B2COPY Integration API [#b2copy-integration-api] New API endpoints have been added for **B2COPY** and IB (Introducing Broker) integrations, including special account types for copy trading. The `isCopyTradingAccount` field has been added to the `/api/v1/total-fundings` endpoint. *** ### Improvements [#improvements-4] #### FIX API: enhanced request throughput [#fix-api-enhanced-request-throughput] The FIX API trading request processing has been optimized to support up to 100 requests per second per connection. All `TimeInForce` types are now supported, including **GTD** (Good Till Date). #### Multilingual support [#multilingual-support] Trading API, Settings API, and Reports API endpoints now support multilingual content with full Unicode character support, enabling localized responses for configurable fields, report names, and templates. #### Stop Market order calculation [#stop-market-order-calculation] The **Value** and **Amount** calculation for **Stop Market** orders has been corrected for **Spot** markets. **Slippage Rate** has been removed from **CFD** and **Perpetual Futures** order calculations. #### Trading API: empty categories hidden [#trading-api-empty-categories-hidden] Empty market categories are now automatically excluded from Trading API responses, reducing unnecessary data in category listings. #### Balance API: zero balance for all assets [#balance-api-zero-balance-for-all-assets] Assets without prior balance operations now return a zero balance in API responses instead of being omitted. #### Cross-rate market configuration [#cross-rate-market-configuration] Markets used exclusively for cross-rate calculations can now be disabled for trading while remaining active for rate conversion. #### History API: extended contracts [#history-api-extended-contracts] Positions and Events API responses have been extended with additional fields. The `updatedAt` field is now available as a sorting and filtering parameter in History Server API endpoints. #### Settings API: market update endpoint [#settings-api-market-update-endpoint] The market update endpoint has been changed from `PATCH` to `PUT` semantics, requiring the full market object in the request body. #### Settings API: legacy endpoints removed [#settings-api-legacy-endpoints-removed] Legacy commission and routing rule endpoints have been removed following the tier commission update. Use the current endpoints as documented in the API reference. *** ### Resolved issues [#resolved-issues-2] * Resolved an issue where `takeProfitPrice` and `stopLossPrice` values were missing from the History Server `/v2/orders` endpoint responses. * Resolved an issue where bulk order cancellation returned a successful result for non-existing orders. * Resolved an issue where bulk order cancellation returned a successful result for orders that could not be cancelled. * Resolved incorrect error codes returned when `closePositionLotAmount` was set to `0`, a negative value, or an empty string. * Resolved an issue where the WebSocket Book stream continued sending prices with an outdated tick size after market parameter changes. * Resolved an issue where negative spreads in the **Market Data API** were not handled correctly. * Resolved an issue where orders could not be created when using the default 24/7 calendar. * Resolved an issue where the `/external-orders` API returned `null` for `rejectReason` although the Trading Server received a reason from the LP. Customize your Trading Terminal and configure settings Customize your Trading Terminal and configure settings Explore and manage all available trading widgets Explore and manage all available trading widgets Learn basic terms and values used across the platform Learn basic terms and values used across the platform The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](trading) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `V` — Market Data Request (Client → B2TRADER) * `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER) * `X` — Market Data — Incremental Refresh (Client ← B2TRADER) * `Y` — Market Data Request Reject (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Market Data session, use the following parameters provided by B2TRADER: * **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint) * **SenderCompID**: Your client identifier for the Market Data session * **TargetCompID**: The server identifier for the Market Data session * **Protocol**: FIX 4.4 The Market Data connection does not require SSL. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request. ```text title="Example" 8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Optional. ```text title="Example" 8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^ ``` *** ## Market Data Request (V) [#market-data-request-v] This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol. After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update. To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout. **`262 MDReqID`** `String` The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard. **`263 SubscriptionRequestType`** `int` The type of response expected from the server. Required. Possible values: * `1` — Subscribe: receive updates as the market status changes * `2` — Unsubscribe: stop streaming market data for the specified symbol **`264 MarketDepth`** `int` The market depth for an order book snapshot. Required. Possible values: * `0` — Full order book * `1` — Top-of-the-book prices **`265 MDUpdateType`** `int` The update type. Required. Must be `1` (incremental updates for changed price levels only). **`267 NoMDEntryTypes`** `int` The number of `<269>` MDEntryType entries requested. Required. > Repeating group: **`269 MDEntryType`** `int` The side of the quote. Required. Possible values: * `0` — Bid * `1` — Ask **`146 NoRelatedSym`** `int` The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each. > Repeating group: **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```text title="Example (Client → B2TRADER)" 8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^ ``` ## Market Data — Snapshot/Full Refresh (W) [#market-data--snapshotfull-refresh-w] This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^ ``` ## Market Data — Incremental Refresh (X) [#market-data--incremental-refresh-x] This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. * Must be unique among active entries when `<279>` MDUpdateAction is `0` (New) * Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete) **`279 MDUpdateAction`** `int` The update type. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — New * `1` — Change * `2` — Delete **`58 Text`** `String` Additional context. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^ ``` ## Market Data Request Reject (Y) [#market-data-request-reject-y] This message is sent by the server to reject a Market Data Request due to business or technical reasons. **`262 MDReqID`** `String` The identifier of the rejected Market Data Request. Required. **`281 MDReqRejReason`** `int` The reason why the request is rejected. Optional. Possible values: * `0` — Unknown symbol * `1` — Duplicate MDReqID * `2` — Insufficient bandwidth * `3` — Insufficient permissions * `4` — Unsupported SubscriptionRequestType * `5` — Unsupported MarketDepth * `6` — Unsupported MDUpdateType * `8` — Unsupported MDEntryType **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^ ``` The Trading session enables order placement and execution management via the FIX 4.4 protocol. Use this session to submit orders and receive real-time execution reports for your trading activity. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Trading** session only. For real-time order book streaming, use the [Market Data](market-data) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `D` — New Order Single (Client → B2TRADER) * `8` — Execution Report (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Trading session, use the following parameters provided by B2TRADER: * **Host and port**: The Trading endpoint (provided separately from the Market Data endpoint) * **SenderCompID**: Your client identifier for the Trading session * **TargetCompID**: The server identifier for the Trading session * **Protocol**: FIX 4.4 The Trading connection requires SSL with a self-signed certificate. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=117^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=117^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=93^35=A^1=68a4446ac84827ff5cd35c74^34=225^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=054^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Conditional — required when sent in response to a Test Request. ```text title="Example" 8=FIX.4.4^9=79^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=156^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Required. ```text title="Example" 8=FIX.4.4^9=87^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=250^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=90^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=176^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=105^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=Session terminated by client^10=183^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=81^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=009^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Execution Report with rejected status and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=128^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=11^372=D^373=1^58=Required tag missing: ClOrdID^10=126^ ``` *** ## New Order Single (D) [#new-order-single-d] This message is sent by the client to place a new order. The server responds with an Execution Report confirming the order status. For details on supported order types, see [Order types](../get-started/order-types). For details on time-in-force options, see [Time in force](../get-started/time-in-force). **`11 ClOrdID`** `String` The unique client-assigned order identifier. Required. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`38 OrderQty`** `Qty` The order quantity. Required. Must be greater than zero. The decimal precision must not exceed the market's amount scale, and the value must be at least the market's minimum amount. **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`59 TimeInForce`** `char` The order's time-in-force policy. Required. Possible values: * `0` — Day * `1` — Good Till Cancel (GTC) * `3` — Immediate or Cancel (IOC) * `4` — Fill or Kill (FOK) * `6` — Good Till Date (GTD) **`44 Price`** `Price` The order price. Conditional — required when `<40>` OrdType is `2` (Limit), must not be present when `<40>` OrdType is `1` (Market). Must be greater than zero. The decimal precision must not exceed the market's price scale. **`126 ExpireTime`** `UTCTimestamp` The order expiration time. Conditional — required when `<59>` TimeInForce is `6` (GTD), must not be present otherwise. **`60 TransactTime`** `UTCTimestamp` The time of order creation. Required. ```text title="Limit order example (Client → B2TRADER)" 8=FIX.4.4^9=168^35=D^34=3^52=20231220-09:15:30.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order001^55=spot.btc_usdt^54=1^38=0.5^40=2^44=42500.00^59=1^60=20231220-09:15:30.000^10=123^ ``` ```text title="Market order example (Client → B2TRADER)" 8=FIX.4.4^9=155^35=D^34=4^52=20231220-09:16:00.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order002^55=spot.btc_usdt^54=2^38=0.1^40=1^59=3^60=20231220-09:16:00.000^10=045^ ``` ## Execution Report (8) [#execution-report-8] This message is sent by the server to confirm order status changes, including acknowledgment of new orders, fills, partial fills, cancellations, and rejections. For details on order statuses, see [Order statuses](../get-started/order-statuses). **`37 OrderID`** `String` The server-assigned unique order identifier. Required. **`11 ClOrdID`** `String` The client-assigned order identifier from the original New Order Single. Required. **`17 ExecID`** `String` The unique execution identifier. Present for trade executions. **`150 ExecType`** `char` The type of execution being reported. Required. Possible values: * `0` — New: order has been accepted * `4` — Canceled: order has been canceled by the server (e.g., IOC order partially filled, GTD order expired, or market settings changed) * `8` — Rejected: order has been rejected * `F` — Trade: order has been partially or fully filled **`39 OrdStatus`** `char` The current order status. Required. Possible values: * `0` — New * `1` — Partially filled * `2` — Filled * `4` — Canceled * `8` — Rejected **`1 Account`** `String` The account identifier. Required. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`44 Price`** `Price` The order price. Present for Limit orders. **`6 AvgPx`** `Price` The average price of all fills on this order. Required. **`14 CumQty`** `Qty` The total filled quantity. Required. **`151 LeavesQty`** `Qty` The remaining quantity to be filled. Required. Set to `0` for Canceled or Rejected orders. **`31 LastPx`** `Price` The price of the last fill. Present when `<150>` ExecType is `F` (Trade). **`32 LastQty`** `Qty` The quantity of the last fill. Present when `<150>` ExecType is `F` (Trade). **`15 Currency`** `String` The quote asset identifier. Optional. **`60 TransactTime`** `UTCTimestamp` The transaction time. Required. **`64 SettlDate`** `String` The settlement date in `YYYYMMDD` format. Required. **`58 Text`** `String` Additional information, such as the rejection reason. Optional. ```text title="New order accepted (B2TRADER → Client)" 8=FIX.4.4^9=220^35=8^34=5^52=20231220-09:15:30.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^150=0^39=0^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=0^14=0^151=0.5^60=20231220-09:15:30.100^64=20231220^10=087^ ``` ```text title="Trade execution (B2TRADER → Client)" 8=FIX.4.4^9=245^35=8^34=6^52=20231220-09:15:30.200^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^17=01HBXK5V3R8NQ7YR^150=F^39=2^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=42500.00^14=0.5^151=0^31=42500.00^32=0.5^15=usdt^60=20231220-09:15:30.200^64=20231220^10=154^ ``` ```text title="Order rejected (B2TRADER → Client)" 8=FIX.4.4^9=214^35=8^34=7^52=20231220-09:16:00.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YS^11=order002^150=8^39=8^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=2^40=1^6=0^14=0^151=0^58=Insufficient balance^60=20231220-09:16:00.100^64=20231220^10=201^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard session-level Reject or Execution Report rejection. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=100^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=006^ ``` Each trading account has an `accountStatus` field that determines which operations are permitted on the account. The field is returned on account objects by the API, such as in [Get accounts](../rest-api/settings). An account can be assigned one of the following statuses: * **Active**: All operations are permitted, including placing, modifying, and canceling orders, opening and closing positions, deposits, and withdrawals. * **Halted**: Trader-initiated trading is blocked. Requests to place, modify, or cancel orders and to open or close positions are rejected. Deposits and withdrawals remain allowed. Managed trading through the Management API (MAM, B2COPY) continues to work. * **Frozen**: All operations are blocked. Trading, deposits, and withdrawals are unavailable, and the account is view-only. Stop-out liquidation still executes as a safety mechanism. * **Archived**: The account is decommissioned and hidden from all user-facing surfaces. Real-time profit and loss, equity, margin level, and funding settlement continue for all statuses. Archived accounts are never returned in the trading API account list. They are excluded server-side, so an account that changes to *Archived* stops appearing in [Get accounts](../rest-api/settings) responses. A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. ## Introduction [#introduction] B2TRADER provides developers with three distinct methods for data delivery, each optimized for specific use cases and performance requirements: REST, WebSocket, and FIX APIs. The **REST API** provides read access to market data as well as both read and write access to trading operations. It serves as the foundation for synchronous data operations where immediate confirmation and guaranteed delivery are essential. The **WebSocket API** provides access to public market data streaming as well as private account updates. It delivers real-time updates with low latency, making it ideal for live trading environments. The **FIX API** provides direct access to market data and trading via the FIX 4.4 protocol. It is designed for institutional clients and algorithmic trading systems that require standardized, low-latency connectivity using the industry-standard Financial Information eXchange protocol. This approach provides developers with flexible options for building robust, scalable trading applications that can handle both operational requirements and real-time market dynamics. ### When to use REST API [#when-to-use-rest-api] * **Account configuration and settings**: Managing user preferences and system configurations. * **Order placement and modification**: Creating, updating, and canceling trading orders. * **Historical data retrieval**: Accessing past trading records and market data. * **One-time data requests**: Retrieving specific information that doesn't require continuous updates. * **Administrative operations**: Account management and system administration tasks. ### When to use WebSocket API [#when-to-use-websocket-api] * **Real-time price monitoring**: Live market price feeds and ticker updates. * **Live position tracking**: Continuous monitoring of open and closed positions. * **Order book visualization**: Real-time depth of market data. * **Market data feeds**: Streaming market statistics and trading activity. * **Account balance monitoring**: Live updates of account equity and margin status. ### When to use FIX API [#when-to-use-fix-api] * **Institutional connectivity**: Standardized FIX 4.4 protocol for professional trading infrastructure. * **Algorithmic trading**: Low-latency order execution and market data for automated strategies. * **Market data streaming**: Real-time order book snapshots and incremental updates via FIX protocol. * **Multi-venue integration**: Unified FIX connectivity for systems already integrated with other FIX-based venues. ## General considerations [#general-considerations] The following applies to all interface descriptions provided in this documentation: * **Endpoints**: All endpoints are relative and resolved based on a specified hostname (indicated as `{host}`). * **Authentication**: REST and WebSocket APIs require an access token (see [Authentication](#authentication)). The FIX API uses in-band authentication via the Logon message with Username, Password, and Account fields provided by B2TRADER. * **Data format**: REST and WebSocket APIs return results in JSON format. The FIX API uses the standard FIX 4.4 message format. * **Security**: All communications use secure protocols (HTTPS for REST, WSS for WebSocket, encrypted TCP for FIX). ### Authentication [#authentication] API access requires an access token for both REST and WebSocket connections. Authentication follows a two-step process: 1. Generate an offline token in the Trading terminal. 2. Exchange the offline token for an access token via API call. #### Token types [#token-types] **Offline token** * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time * **Purpose**: Generate access tokens **Access token** * **Type**: Bearer token * **Validity**: 60 minutes * **Purpose**: Authorize API requests ### Generate offline token [#generate-offline-token] To generate an offline token: 1. In the Trading terminal, open **Settings** and select **API token management**. 2. Click **+ Create new**. 3. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 4. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ### Obtain access token [#obtain-access-token] Request an access token using your offline token. **Endpoint**: `POST` `/frontoffice/api/v4/access-token` **Request body**: ```json { "token": "{YOUR_OFFLINE_TOKEN}" } ``` **Response** (Success): ```json { "accessToken": "{YOUR_ACCESS_TOKEN}", "expiresIn": 3600, "tokenType": "Bearer" } ``` **`accessToken`** `string` The access token for API authorization. **`expiresIn`** `integer` The token lifetime, in seconds. **`tokenType`** `string` The authentication type, always `"Bearer"`. ### Using access tokens [#using-access-tokens] Include the access token in API requests: ```http title="REST" Authorization: Bearer {YOUR_ACCESS_TOKEN} ``` ```http title="WebSocket" {URL}?access_token={YOUR_ACCESS_TOKEN} ``` Access tokens must be refreshed before expiration by repeating the Step 2 with your offline token. ## REST API: Synchronous data operations [#rest-api-synchronous-data-operations] The REST API serves as the foundation for synchronous data operations within the B2TRADER platform. This approach follows standard HTTP protocols and is ideal for operations requiring immediate confirmation and guaranteed delivery. ### Key characteristics [#key-characteristics] * **Request-response operations** where immediate confirmation is required. * **Account management** including settings and configuration. * **Order placement and modification** with guaranteed delivery. * **Historical data retrieval** for analysis and reporting. * **Stateless operations** that don't require persistent connections. ### HTTP response codes [#http-response-codes] B2TRADER API uses conventional HTTP response codes to indicate the success or failure of requests. **Success codes:** * `200 OK` — Request successful **Error codes:** * `400 Bad Request` — Invalid request parameters * `401 Unauthorized` — Authentication required * `403 Forbidden` — Insufficient permissions * `404 Not Found` — Resource not found * `429 Too Many Requests` — [Rate limit](#rate-limits) exceeded * `500 Internal Server Error` — Server error In case of an error, an object will be returned with the following structure: ```json { "code": "text", "message": "text", "details": { "source": "text", "message": "text", "stackTrace": "text" } } ``` ### Available endpoints [#available-endpoints] * **[Trading operations](../rest-api/trading)**: Create, modify, and cancel orders; open, close, and modify positions; control price trigger settings. * **[Trading history](../rest-api/history)**: Retrieve detailed execution records for positions and orders. * **[Settings and configurations](../rest-api/settings)**: Access account information, market specifications, trading sessions, and asset details. ### Rate limits [#rate-limits] Rate limits are applied per minute for each unique **AccountId** to ensure fair resource usage and maintain optimal API performance. All limits use the **Fixed Window** strategy. When rate limits are exceeded, the API returns a `429 Too Many Requests` HTTP status code. #### Trading methods [#trading-methods] * **Default limit**: 600 requests per minute for all methods. * **Reduced limit (200 rpm)** applies to: * Get order data methods * Bulk close positions method * Price triggers methods #### History methods [#history-methods] * **All request types**: 60 requests per minute. #### Settings methods [#settings-methods] * **GET requests**: 100 requests per minute. * **POST and DELETE requests**: 60 requests per minute. Rate limits are calculated independently for each method category. For example, you can make 100 GET requests to Settings methods and 60 requests to History methods within the same minute without hitting rate limits. ## WebSocket API: Real-time data streaming [#websocket-api-real-time-data-streaming] The WebSocket API delivers real-time updates with minimal latency, essential for modern trading applications. The implementation uses unidirectional communication from server to client, ensuring efficient data delivery. ### Key characteristics [#key-characteristics-1] * **Unidirectional communication** from server to client for optimal performance. * **Real-time market data** for live trading environments. * **Position and order updates** as they occur in real-time. * **Low-latency data delivery** for time-sensitive trading operations. * **Persistent connections** maintaining continuous data flow. ### SignalR implementation [#signalr-implementation] B2TRADER utilizes **AspNetCore SignalR** for WebSocket message organization and transmission, providing a robust and scalable real-time communication framework. **Resources:** * [Official GitHub Repository](https://github.com/dotnet/aspnetcore/tree/main/src/SignalR) * [Official Documentation](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr) SignalR provides a structured approach to real-time communication through standardized message formatting and connection management. ### Connection lifecycle [#connection-lifecycle] The data transfer process consists of two essential phases: 1. **Connection establishment** — Initial handshake, authentication, and subscription setup. 2. **Data streaming** — Continuous real-time data flow with automatic reconnection handling. ### Message types [#message-types] SignalR utilizes numerical `type` indicators for different operations: ### Available stream types [#available-stream-types] * **[Trading streams](../ws-api/trading)**: Track active orders, open and closed positions. * **[Market data streams](../ws-api/market-data)**: Get real-time order book updates, market statistics and price changes. * **[Account information streams](../ws-api/account-info)**: Get live account balance and margin updates. ## FIX API: Standardized protocol connectivity [#fix-api-standardized-protocol-connectivity] The FIX API provides direct access to B2TRADER via the FIX 4.4 protocol, the industry standard for electronic trading communication. It is designed for institutional clients and algorithmic trading systems. ### Key characteristics [#key-characteristics-2] * **FIX 4.4 protocol** for standardized, vendor-neutral connectivity. * **Dedicated sessions** for Market Data and Trading with separate endpoints. * **In-band authentication** via Logon message (Username, Password, Account). * **Real-time market data** with order book snapshots and incremental updates. * **Session management** with Heartbeat, Test Request, and Sequence Reset support. ### Authentication [#authentication-1] Unlike REST and WebSocket APIs, the FIX API does not use access tokens. Authentication is performed in-band as part of the FIX Logon message using credentials provided by B2TRADER: * **Username** (`<553>`): The client username * **Password** (`<554>`): The client password * **Account** (`<1>`): The account identifier ### Available session types [#available-session-types] * **[Market Data](../fix-api/market-data)**: Subscribe to real-time order book updates, snapshots, and incremental refreshes. * **[Trading](../fix-api/trading)**: Place orders and receive execution reports in real time. ## Integration best practices [#integration-best-practices] ### API selection strategy [#api-selection-strategy] * Use **REST API** for operational tasks requiring confirmation (order placement, account management). * Use **WebSocket API** for real-time monitoring and market data visualization. * Use **FIX API** for institutional connectivity, algorithmic trading, and integration with existing FIX-based infrastructure. * Implement multiple APIs in comprehensive trading applications for optimal functionality. ### Performance optimization [#performance-optimization] * Implement proper connection pooling for REST API requests. * Use WebSocket subscriptions efficiently by subscribing only to required data streams. * Handle reconnection logic for WebSocket connections to ensure data continuity. * Implement appropriate error handling and retry mechanisms. ### Security considerations [#security-considerations] * Store authentication tokens securely and implement token refresh mechanisms. * Use secure connections (HTTPS/WSS) for all API communications. * Implement proper input validation and sanitization. * Monitor API usage and implement rate limiting on the client side. This comprehensive API architecture enables developers to build sophisticated trading applications that can handle both real-time market dynamics and operational trading requirements efficiently. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all Limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the platform, without taking into account the time settings of the devices from which the platform is accessed. ## Get full balance [#get-full-balance] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"FullBalance"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "FullBalance", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of balance objects. **`item.assetId`** `string` The asset identifier. **`item.available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`item.total`** `decimal string` The overall amount of the asset, including locked funds. **`item.locked`** `decimal string` The asset amount locked on the account for execution of all placed Limit orders. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "assetId": "eur", "available": "497838.8", "total": "497838.8", "locked": "0" } ] } ``` ## Get margin data [#get-margin-data] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"MarginData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "MarginData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.marginBalanceInRAT`** `decimal string` The total amount of funds that can be used as a collateral for trading, in RAT. This value is calculated as SUM (*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*) Where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the BP root asset. **`item.creditInRAT`** `decimal string` The promotional trading credit granted to the account by the broker, in RAT. Credit is included in the account equity but excluded from the withdrawable amount. During a rolling deployment, older payloads might omit this field. In that case, default it to `0`. **`item.unrealizedPnlInRAT`** `decimal string` The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) **`item.equityInRAT`** `decimal string` The potential balance if all open positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. **`item.usedMarginInRAT`** `decimal string` The amount of funds that is used for maintaining all open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **`item.freeMarginInRAT`** `decimal string` The amount of funds that can be used for opening new positions. **`item.marginLevel`** `decimal string` The ratio of funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "marginBalanceInRAT": "497838.8", "creditInRAT": "0", "unrealizedPnlInRAT": "-5.25", "equityInRAT": "497833.55", "usedMarginInRAT": "100.18", "freeMarginInRAT": "497733.37", "marginLevel": "4969.3905" } } ``` ## Get order book [#get-order-book] ### Connection [#connection] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Book"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eur_chf" ], "invocationId": "0", "target": "Book", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.askTotalAmount`** `string` The total ask amount. **`item.bidTotalAmount`** `string` The total bid amount. **`item.asks`** `array of objects` The array of ask price objects. **`item.asks.price`** `string` The price, in the quote asset. **`item.asks.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.asks.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.bids`** `array of objects` The array of bid price objects. **`item.bids.price`** `string` The price, in the quote asset. **`item.bids.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.bids.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.version`** `string` The order book version. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eur_chf", "askTotalAmount": "18700000", "bidTotalAmount": "19100000", "asks": [ { "price": "0.93677", "amount": "5000000", "total": "4683850" }, { "price": "0.93676", "amount": "0", "total": "0" }, { "price": "0.93676", "amount": "0", "total": "0" } ], "bids": [ { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93655", "amount": "5000000", "total": "4682750" } ], "version": "12498", "snapshot": false } } ``` ## Get trading data [#get-trading-data] ### Connection [#connection-1] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"TradingData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.bnb_btc" ] ], "invocationId": "0", "target": "TradingData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.markets.displayName`** `string` The market ticker. **`item.markets.fullName`** `string` The market full name or description (optional). **`item.markets.price`** `decimal string` The current top-of-the-book price, in the quote asset. **`item.markets.priceInRAT`** `decimal string` The current top-of-the-book price, in conversion to the root asset of the platform. **`item.markets.priceChange24hr`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.markets.priceChangeAbs24hr`** `decimal string` The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. **`item.markets.highPrice24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.markets.lowPrice24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.markets.markPrice`** `decimal string` *Applicable to Perpetual markets only.* The mid-spread price, in conversion to RAT. **`item.markets.fundingRate`** `decimal string` *Applicable to Perpetual markets only.* The current funding rate. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "cfd.eur_chf", "type": "Cfd", "displayName": "cfd.eur_chf", "fullName": "", "price": "0.93586", "priceInRAT": "1", "priceChange24hr": "-0.0006", "priceChangeAbs24hr": "-0.00049", "highPrice24hr": "0.93695", "lowPrice24hr": "0.93134", "markPrice": null, "fundingRate": null } ], "snapshot": false } } ``` ## Get top of the book [#get-top-of-the-book] ### Connection [#connection-2] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Tob"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.eth_usdt" ] ], "invocationId": "0", "target": "Tob", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.ask`** `decimal string` The top-of-the-book ask price. **`item.markets.bid`** `decimal string` The top-of-the-book bid price. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "spot.eth_usdt", "ask": "2483.82", "bid": "2483.81" } ], "snapshot": false } } ``` ## Get trading chart [#get-trading-chart] ### Connection [#connection-3] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` and `timescale` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Chart"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eth_eur@15m" ], "invocationId": "0", "target": "Chart", "type": 4 } ``` *** ### Message [#message-3] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.low`** `decimal string` The lowest base asset price within the specified time interval. **`item.high`** `decimal string` The highest base asset price within the specified time interval. **`item.open`** `decimal string` The base asset price at the beginning of the specified time interval. **`item.close`** `decimal string` The base asset price at the end of the specified time interval. **`item.start`** `dateTime` The beginning of the specified time interval, in ISO 8601 format. **`item.end`** `dateTime` The end of the specified time interval, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eth_eur", "low": "2240.88", "high": "2270.29", "open": "2265.63", "close": "2255.99", "start": "2025-05-21T15:30:00Z", "end": "2025-05-21T15:45:00Z" } } ``` ## Get market summary [#get-market-summary] ### Connection [#connection-4] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Summary"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "cfd.eur_chf" ] ], "invocationId": "0", "target": "Summary", "type": 4 } ``` *** ### Message [#message-4] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.items`** `array of objects` The array of data objects. **`item.items.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.items.last`** `decimal string` The price of the last trade. **`item.items.high24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.items.low24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.items.percentChange`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "items": [ { "marketId": "cfd.eur_chf", "last": "0.93597", "high24hr": "0.93695", "low24hr": "0.93134", "percentChange": "-0.02" } ], "snapshot": false } } ``` ## Get open orders [#get-open-orders] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenOrders", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of market objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.status`** `string` The current [order status](../get-started/order-statuses). Possible values: * `Started` * `Pending` * `Working` **`item.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`item.reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`item.remainingAmount`** `decimal string` The order amount that hasn't yet been filled, in the base asset. **`item.requestedPrice`** `decimal string` The limit price for Limit orders; `null` for Market orders. **`item.executionPrice`** `decimal string` The volume-weighted average price of the order executions. **`item.createdAt`** `dateTime` The timestamp when the order was created, in ISO 8601 format. **`item.updatedAt`** `dateTime` The timestamp of the most recent update to the order, in ISO 8601 format. **`item.cancellationDate`** `dateTime` The timestamp when the order was cancelled or expired, in ISO 8601 format; `null` if not cancelled. **`item.commissionAssetId`** `string` The currency in which the commission was held. **`item.commissionAmount`** `decimal string` The total commissions put on hold for executing the order. **`item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when placing the order. **`item.fillFactor`** `decimal string` The proportion of the order amount filled so far, where `1` represents 100% fulfillment. **`item.comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.stopLoss`** `decimal string` The Stop Loss price, if set. ```json { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "orderId": "01JVQBFSTVC40VK03A0AY7K016", "timeInForce": "Gtc", "status": "Pending", "source": "Manual", "reason": "Trader", "side": "Buy", "orderType": "Limit", "requestedAmount": "10000", "remainingAmount": "10000", "requestedPrice": "0.9", "executionPrice": "0", "createdAt": "2025-05-20T17:22:31.899Z", "updatedAt": "2025-05-20T17:22:31.9001213Z", "cancellationDate": null, "commissionAssetId": "eur", "commissionAmount": "0", "leverage": 1, "fillFactor": "0", "takeProfit": null, "stopLoss": null, "comment": null } ] } ``` ## Get open positions [#get-open-positions] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenPositions"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenPositions", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.item`** `array of objects` The array of position objects. **`item.item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.item.marketDisplayName`** `string` The market ticker. **`item.item.marketFullName`** `string` The market full name or description (optional). **`item.item.createdAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. **`item.item.updatedAt`** `dateTime` The timestamp of the most recent update to the position, in ISO 8601 format. **`item.item.side`** `string` The position side. Possible values: * `Buy` * `Sell` **`item.item.status`** `string` The current position status. Always `"Open"`. **`item.item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when opening the position. **`item.item.positionLotAmount`** `decimal string` The position volume, in lots. **`item.item.positionPriceInRAT`** `decimal string` The current position price, in conversion to RAT. **`item.item.rateToRAT`** `decimal string` The current exchange rate of a quote asset to RAT. **`item.item.usedMarginInRAT`** `decimal string` The amount of trader’s funds used for maintaining a position, in conversion to RAT. **`item.item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.item.currentMarketPrice`** `decimal string` The current market price of the base asset: bid for Long positions and ask for Short positions. **`item.item.unrealizedPnlDayInRAT`** `decimal string` The potential profit or loss earned for a current day, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. **`item.item.unrealizedPnlDayPercent`** `decimal string` The potential profit or loss earned for a current day, in percents. **`item.item.unrealizedPnlTotalInRAT`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). **`item.item.unrealizedPnlTotalPercent`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT, in percents. **`item.item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.item.stopLoss`** `decimal string` The Stop Loss price, if set. **`item.item.positionModifier`** `string` The reason for the latest position update. **`item.item.comment`** `string | nullable` The text note inherited from the opening order, up to 100 characters. **`snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "item": [ { "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-03-12T06:36:31.257Z", "updatedAt": "2025-03-12T06:36:31.257Z", "side": "Buy", "status": "Open", "leverage": 1, "positionLotAmount": "0.01", "positionPriceInRAT": "1000.46", "rateToRAT": "1.07", "usedMarginInRAT": "1000.53", "openPrice": "0.96304", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "1.86", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-29.93", "unrealizedPnlTotalPercent": "-0.0291", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null }, { "positionId": "01JVQB9ZWJ6G4QV0P98X0QWNA7", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-05-20T17:19:21.49Z", "updatedAt": "2025-05-20T17:19:21.491321Z", "side": "Buy", "status": "Open", "leverage": 100, "positionLotAmount": "0.1", "positionPriceInRAT": "10004.6", "rateToRAT": "1.07", "usedMarginInRAT": "100.06", "openPrice": "0.93666", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "18.61", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-17.02", "unrealizedPnlTotalPercent": "-0.0017", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null } ], "snapshot": false } } ``` ## Get closed positions [#get-closed-positions] ### Connection [#connection-2] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"ClosePositionsOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "ClosePositionsOrders", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of position objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.positionCloseLotAmount`** `decimal string` The closed volume, in lots, which is equivalent to the corresponding filled order volume. **`item.reason`** `string` The reason for position closing. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.realizedPnlInRAT`** `decimal string` The actual profit or loss earned, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). **`item.closedAt`** `dateTime` The timestamp when the position was closed, in ISO 8601 format. **`item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`item.positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`item.rateToRAT`** `decimal string` The conversion rate to RAT. **`item.openedAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketFullName": "", "marketDisplayName": "EUR/CHF", "marketType": "Cfd", "orderId": "01JVSQ8WFA3QZ6AQTKYPXVXDWA", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.01", "reason": "Trader", "realizedPnlInRAT": "-29.25", "closedAt": "2025-05-21T15:26:57.0027785Z", "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "openPrice": "0.96304", "closePrice": "0.93571", "positionPriceInRAT": "1001.2", "rateToRAT": "1.07", "openedAt": "2025-03-12T06:36:31.257Z" } ] } ``` ## Open positions [#open-positions] ### Get executions for an open position [#get-executions-for-an-open-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/executions/list` #### Summary [#summary] Use this method to retrieve execution details for a specific open position using its position identifier. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`positionId`** `required` The position identifier. ##### Body [#body] **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`offset`** `integer · int32 | nullable` The number of items to skip before starting to collect the result set. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PMT0VMJG5B8XBDNZ7FNM1F/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "offset": 0 } ``` #### Response [#response] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VNWB23GSRN2XQAJD6Q", "baseAmount": "0.314", "executionPrice": "4603.5", "commissionAmountInRAT": "0", "commissions": [], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VN1F2JPM14AEV6V8YJ", "baseAmount": "0.045", "executionPrice": "4603.49", "commissionAmountInRAT": "0", "commissions": [], "comment": null } ] } ``` ### Get executions for open positions [#get-executions-for-open-positions] `POST` `/frontoffice/api/v4/positions/executions/list` #### Summary [#summary-1] Use this method to retrieve execution details for multiple open positions by providing an array of position identifiers. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`positionIds`** `array · string[]` The array of position identifiers. **`limit`** `integer · int32 | nullable` The maximum number of items to return. ```http title="Request example" POST /frontoffice/api/v4/positions/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "positionIds": [ "01K2PMT0VMJG5B8XBDNZ7FNM1F", "01K2PMXY63HESK110WT1CHMAFA" ], "limit": 5 } ``` #### Response [#response-1] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMXY63HESK110WT1CHMAFA", "orderId": "01K2PMXY1894RC6E2BYFR00T87", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:38:10.627Z", "executionId": "01K2PMXY63NXM30VNWPDECSFJR", "baseAmount": "15", "executionPrice": "4333.69288", "commissionAmountInRAT": "32.27", "commissions": [ { "assetId": "eur", "amount": "32.27" } ], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.292Z", "executionId": "01K2PMT0VMPCZW0JB2C9J6B405", "baseAmount": "0.141", "executionPrice": "4602.3", "commissionAmountInRAT": "5", "commissions": [ { "assetId": "eur", "amount": "5" } ], "comment": null } ] } ``` ## Closed positions [#closed-positions] ### Get orders for closed positions [#get-orders-for-closed-positions] `POST` `/frontoffice/api/v4/orders/closed-positions` #### Summary [#summary-2] Use this method to retrieve orders associated with closed positions within specified date ranges and market filters. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`createdAtFrom`** `string · date-time | nullable` The start date of the period when the positions were opened. **`createdAtTo`** `string · date-time | nullable` The end date of the period when the positions were opened. **`closedAtFrom`** `string · date-time | nullable` The start date of the period when the positions were closed. **`closedAtTo`** `string · date-time | nullable` The end date of the period when the positions were closed. **`marketId`** `string | nullable` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`marketType`** `string | nullable` The market type. Possible values: * `Cfd` * `Perp` **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastOrderId`** `string | nullable` The identifier of the final order to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/closed-positions HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "createdAtFrom": "2025-08-01T12:00:32.886Z", "createdAtTo": "2025-08-15T12:00:32.886Z" } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier. **`marketFullName`** `string | nullable` The market full name or description (optional). **`marketDisplayName`** `string | nullable` The market ticker. **`marketType`** `string` The market type. Possible values: * `Cfd` * `Perp` **`orderId`** `string` The order identifier. **`orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`timeInForce`** `string` The [time-in-force setting](../get-started/time-in-force) of the order. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`side`** `string` The order side. Possible values: * `Buy` * `Sell` **`positionCloseLotAmount`** `decimal string` The position amount closed by the order, in lots. **`reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`closedAt`** `string · date-time | nullable` The date and time when the position was closed. **`positionId`** `string` The position identifier. **`openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`rateToRAT`** `decimal string` The conversion rate to RAT. **`openedAt`** `string · date-time` The date and time when the position was opened. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "data": [ { "marketId": "cfd.eth_eur", "marketFullName": null, "marketDisplayName": "CFD ETH/EUR", "marketType": "Cfd", "orderId": "01K2PNGX50SR1FRE6P14PJC17E", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "15", "reason": "Trader", "realizedPnlInRAT": "-144.64", "closedAt": "2025-08-15T10:48:32.393Z", "positionId": "01K2PMXY63HESK110WT1CHMAFA", "openPrice": "4333.69288", "closePrice": "3370.58389", "positionPriceInRAT": "50558.75", "rateToRAT": "1", "openedAt": "2025-08-15T10:38:10.628Z", "comment": null }, { "marketId": "perp.eth_usdt", "marketFullName": "ETH/USDT_4s8hKqiPXmXOEhsO1J6W", "marketDisplayName": "ETH/USDT_jC6Im5PxwgZLrwyccRcI", "marketType": "Perpetual", "orderId": "01K2PNG3N6NKAJVV4RV5E2V0HK", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.5", "reason": "Trader", "realizedPnlInRAT": "13.42", "closedAt": "2025-08-15T10:48:06.234Z", "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "openPrice": "4603.1607", "closePrice": "4634.3915", "positionPriceInRAT": "1992.78", "rateToRAT": "0.86", "openedAt": "2025-08-15T10:36:02.293Z", "comment": null } ], "isExceeded": true } ``` ### Get executions for a closing order [#get-executions-for-a-closing-order] `POST` `/frontoffice/api/v5/orders/``{orderId}``/executions/list` #### Summary [#summary-3] Use this method to retrieve execution details for a specific position-closing order using its identifier. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The order identifier. ##### Body [#body-3] **`positionId`** `string | nullable` The position identifier. **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastExecutionId`** `string | nullable` The identifier of the final execution to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/01K2PNG3N6NKAJVV4RV5E2V0HK/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 5 } ``` #### Response [#response-3] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed amount of the base asset. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T19:02:22.196Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true } ], "isExceeded": true } ``` ### Get executions for closing orders [#get-executions-for-closing-orders] `POST` `/frontoffice/api/v5/orders/executions/list` #### Summary [#summary-4] Use this method to retrieve execution details for multiple position-closing orders by providing an array of order identifiers. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`orderId`** `string` The order identifier. **`positionId`** `string` The order identifier. ```http title="Request example" POST /frontoffice/api/v4/orders/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "orderPositionPairs": [ { "orderId": "01K31APDKZCVGWZA3XTF5JPAMD", "positionId": "01K31APDWF2EBHRKHH15VGB1ST" } ], "limit": 0 } ``` #### Response [#response-4] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T18:53:15.657Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true, "comment": null } ], "isExceeded": true } ``` ## Accounts [#accounts] ### Get accounts [#get-accounts] `GET` `/frontoffice/api/v3/accounts` #### Summary [#summary] Use this method to retrieve a list of all trading accounts with their basic information including account type and total balance. #### Request [#request] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/accounts HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response] In case of success, an array of objects will be returned. Each object contains the following information: **`accountId`** `string` The trading account identifier. **`publicAccountId`** `integer` The public account identifier for display purposes. **`accountName`** `string` The account name. **`accountType`** `string` The account type. Possible values: * `Hedging` * `Netting` **`accountStatus`** `string` The account status, which determines the permitted operations. For a description of each value, see [Account statuses](../get-started/account-statuses). Possible values: * `Active` * `Halted` * `Frozen` **`totalBalanceInRAT`** `decimal string` The total balance, in RAT. **`isCopyTradingAccount`** `boolean` Indicates if the account is `Copy`. ```json title="Response example — 200: OK" [ { "accountId": "685a7eaa360f9e7416221a61", "publicAccountId": 1234567, "accountName": "B2TRADER Hedging account", "accountType": "Hedging", "accountStatus": "Active", "totalBalanceInRAT": "6020.12", "isCopyTradingAccount": false }, { "accountId": "6891e70db552ff9c6fbbccf5", "publicAccountId": 1234568, "accountName": "B2TRADER Netting account", "accountType": "Netting", "accountStatus": "Halted", "totalBalanceInRAT": "10987.39", "isCopyTradingAccount": false } ] ``` ## Assets [#assets] ### Get assets [#get-assets] `GET` `/frontoffice/api/v3/assets` #### Summary [#summary-1] Use this method to retrieve a list of available assets on the platform. #### Request [#request-1] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-1] In case of success, an array of objects will be returned. Each object contains the following information: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`isRootAsset`** `boolean` Indicates whether this is a root asset. ```json title="Response example — 200: OK" [ { "assetId": "usdt", "assetName": "Tether", "isRootAsset": true }, { "assetId": "xrp", "assetName": "Ripple", "isRootAsset": false } ] ``` ## Markets [#markets] ### Get markets [#get-markets] `GET` `/frontoffice/api/v6/markets` #### Summary [#summary-2] Use this method to retrieve a list of available markets with their type, subtype, and favorite status. #### Request [#request-2] ##### Query parameters [#query-parameters] **`categoryId`** The market category identifier. **`dynamicCommissionGroupId`** The dynamic commission group identifier. **`isFavorite`** `boolean` Filter by favorite status. If set to `true`, only markets marked as favorites are returned. ```http title="Request example" GET /frontoffice/api/v6/markets?isFavorite=true HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} ``` #### Response [#response-2] In case of success, an array of market objects is returned. Each market object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description. **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" [ { "marketId": "spot.btc_usdt", "displayName": "BTC/USDT", "fullName": null, "type": "Spot", "subtype": null, "isFavorite": true }, { "marketId": "cfd.eth_btc", "displayName": "ETH/BTC", "fullName": "Ethereum to Bitcoin", "type": "Cfd", "subtype": "Crypto", "isFavorite": false }, { "marketId": "perp.trx_usdt", "displayName": "TRX/USDT", "fullName": "TRX to Tether Perpetual", "type": "Perpetual", "subtype": null, "isFavorite": false } ] ``` ### Get market [#get-market] `GET` `/frontoffice/api/v6/markets/``{marketId}` #### Summary [#summary-3] Use this method to retrieve detailed information about a specific market using its market identifier. #### Request [#request-3] ##### Path parameters [#path-parameters] **`marketId`** `required` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```http title="Request example" GET /frontoffice/api/v6/markets/{marketId} HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description (optional). **`baseAssetId`** `string` The base asset identifier. **`quoteAssetId`** `string` The quote asset identifier. **`minAmount`** `decimal string | nullable` *Applicable to Spot markets only.* The minimum tradable amount of the base asset. **`maxBaseAmount`** `decimal string | nullable` The maximum tradable amount of the base asset. **`priceDeviation`** `decimal string` The allowed price deviation for Limit orders placed on the market. Supports decimal values in the range `[0, 1]`, with up to 4 decimal places, for example: * `0.1` = 10% * `0.01` = 1% * `0.001` = 0.1% * `0.0001` = 0.01% If set to `0`, no restriction is applied, the price deviation is ignored. **`priceScale`** `integer` The price precision, which is the number of digits after a decimal separator. Also determines the minimum allowed trade price. Supports only integer values in the range `[2, 8]`. For example, `2` means the following price format: `0.01`, and `8`: `0.00000001`. **`amountScale`** `integer | nullable` *Applicable to Spot markets only.* The amount precision, which is the number of digits after a decimal separator. Also determines the minimum trade amount. Supports only integer values in the range `[0, 8]`. For example: * `0` means `1` (no digits after the decimal separator) * `5` means `0.00001` (five digits after the decimal separator) * `8` means `0.00000001` (eight digits after the decimal separator) **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`swapSettings`** `object | nullable` *Applicable to CFD markets only.* The fee type charged for holding open positions overnight. The amount can be negative for rebates. Possible values: * `FixPerLot`: The fixed amount per lot. * `Percent`: The fixed amount in points which is applied to the position size, in the range `[-1, 1]`, with up to 5 decimal places. * `Points`: The fixed amount of percents which is applied to the position size, with up to 3 decimal places. Structure: * **`type`** `string` — Swap calculation type. Possible values: `FixPerLot`, `Percent`, `Points`. * **`shortPositionSettings`** `object` — Settings for Short positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` * **`longPositionSettings`** `object` — Settings for Long positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` **`lotSize`** `integer | nullable` *Not applicable to Spot markets.* The standardized quantity of the base asset per lot. Supports only integer values in the range `[1, 1000000]`. **`minLotAmount`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum order amount, in lots, that can be placed and executed. Supports values in the range `[0.00000001, 1]`. **`maxLotAmount`** `integer | nullable` *Not applicable to Spot markets.* The maximum order amount, in lots, that can be placed and executed. Supports only integer values in the range `[1, 10000]`. **`tickSize`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum price increment. **`lotStep`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum lot amount increment. Supports values in the range `[0.00000001, 1]`. By default, equals to the `minLotAmount`. **`slippageRate`** `decimal string` The expected slippage, that is, the difference between the expected execution price and the actual one. This value is used as a multiplier to calculate the funds to be put on hold for a market order execution. Supports values in the range `[1, 10]`, including decimal values with up to 4 decimal places. The default value is `1` which means that only the current bid/ask price is put on hold. For example, `1.1` means that the current bid or ask price + 10% is put on hold for each order, to cover the 10% slippage. **Mind that** the total amount funds to be held depends on the order parameters and takes into account many conditions, the slippage rate is only one of them. **`calendar`** `object` The trading calendar defining market trading hours. Structure: * **`timeZoneId`** `string` — IANA time zone identifier. * **`tradingSessions`** `array` — Weekly trading sessions: * **`dayOfWeek`** `string` — One of: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. * **`timeIntervals`** `array` — List of intervals with: * **`start`** `string` (time) — Start time in `calendar.timeZoneId`. * **`end`** `string` (time) — End time in `calendar.timeZoneId`. * **`sessionOverrides`** `array` — Optional specific-date overrides: * **`date`** `string` (date) — In `YYYY-MM-DD` format. * **`timeIntervals`** `array | nullable` — Intervals for that date. **`fundingStartTime`** `string | nullable` *Applicable to Perpetual markets only.* The time of the first funding settlement, in the following format: `HH:MM:SS`. **`fundingIntervalInHours`** `integer | nullable` *Applicable to Perpetual markets only.* The funding settlement interval, in hours. Possible values: 1, 2, 3, 4, 6, 8, 12, 24. **`leverageProfile`** `object` *Not applicable to Spot markets.* The leverage profile. Structure: * **`leverageType`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`leverage`** `object` * **`useOnlyMaxLeverage`** `boolean` * **`maxLeverage`** `integer` — For `Fixed` leverage type only. * **`tiers`** `array` — For `Dynamic` leverage type only. * **`maxLeverage`** `integer` — The maximum allowed leverage for this tier. * **`maxNotionalValueInRAT`** `string | nullable` — The maximum position notional for this tier. **`commissionSettings`** `object` The commission settings. Structure: * **`type`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`charge`** `object` * **`type`** `string` — Possible values: `Percent`, `FixPerLot`. * **`assetId`** `string | nullable` — For `Fixed` commission type only. * **`size`** `decimal string` — For `Fixed` commission type only. * **`tiers`** `array` — For `Dynamic` commission type only. * **`size`** `string` — The commission amount for this tier. * **`minTradingVolumeInRAT`** `string` — The minimum required trading volume for this tier. * **`minCommissionInRAT`** `decimal string | nullable` * **`dynamicCommissionGroupId`** **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" { "marketId": "string", "displayName": "string", "fullName": "string", "baseAssetId": "string", "quoteAssetId": "string", "minAmount": "string", "maxBaseAmount": "string", "minQuoteAmount": "string", "priceDeviation": "string", "priceScale": 0, "amountScale": 0, "type": "Spot", "subtype": "Cash", "swapSettings": { "type": "FixPerLot", "shortPositionSettings": { "size": "string", "assetId": "string" }, "longPositionSettings": { "size": "string", "assetId": "string" } }, "lotSize": 0, "minLotAmount": "string", "maxLotAmount": 0, "tickSize": "string", "lotStep": "string", "slippageRate": "string", "calendar": { "timeZoneId": "string", "tradingSessions": [ { "dayOfWeek": "Monday", "timeIntervals": [ { "start": "string", "end": "string" } ] } ], "sessionOverrides": [ { "date": "2025-12-18", "timeIntervals": [ { "start": "string", "end": "string" } ] } ] }, "fundingStartTime": "string", "fundingIntervalInHours": 0, "leverageProfile": { "leverageType": "Fixed", "leverage": { "useOnlyMaxLeverage": true, "maxLeverage": 0 } }, "commissionSettings": { "type": "Dynamic", "сharge": { "type": "Percent", "tiers": [ { "size": "string", "minTradingVolumeInRAT": "string" }, { "size": "string", "minTradingVolumeInRAT": "string" } ], "minCommissionInRAT": "string" }, "dynamicCommissionGroupId": "string" }, "isFavorite": true } ``` *** ### Add favorite market [#add-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/add` #### Summary [#summary-4] Add a market to the current user's favorites list. #### Request [#request-4] ##### Body [#body] **`marketId`** `string` `required` The market identifier to add to favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/add HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-4] In case of success (`200`), an empty object is returned. *** ### Remove favorite market [#remove-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/delete` #### Summary [#summary-5] Remove a market from the current user's favorites list. #### Request [#request-5] ##### Body [#body-1] **`marketId`** `string` `required` The market identifier to remove from favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/delete HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-5] In case of success (`200`), an empty object is returned. ## Account margin settings [#account-margin-settings] ### Get margin assets [#get-margin-assets] `GET` `/frontoffice/api/v4/account-margin-settings/assets` #### Summary [#summary-6] Use this method to retrieve a list of assets that can be used as collateral for margin trading. #### Request [#request-6] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v4/account-margin-settings/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`assets`** `array` A list of assets that can be used as a collateral for margin trading. Each array item contains: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`total`** `decimal string` The overall amount of the asset, including locked funds. **`marginRatio`** `decimal string` The percentage of the asset value used as a collateral. Supports values in the range `[0, 1]`, where `1` represents 100.00%. **`isSelected`** `boolean` Indicates whether the asset is selected to be used as collateral. Can be `true` only for assets with the `marginRatio` more than `0`. ```json title="Response example — 200: OK" { "assets": [ { "assetId": "btc", "assetName": "btc", "available": "0.031", "total": "0.031", "marginRatio": "1", "isSelected": true }, { "assetId": "eth", "assetName": "eth", "available": "0", "total": "0", "marginRatio": "1", "isSelected": false } ] } ``` ### Select margin asset [#select-margin-asset] `POST` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-7] Use this method to enable a particular asset to be used as collateral for margin trading. Only assets with the `marginRatio` more than `0` can be selected. #### Request [#request-7] ##### Path parameters [#path-parameters-1] **`assetId`** `required` The asset identifier. ```http title="Request example" POST /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json Accept: */* {} ``` #### Response [#response-7] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ### Disable margin asset [#disable-margin-asset] `DELETE` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-8] Use this method to prohibit a specific asset from being used as collateral for margin trading. #### Request [#request-8] ##### Path parameters [#path-parameters-2] **`assetId`** `required` The asset identifier. ```http title="Request example" DELETE /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-8] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ## Info [#info] ### Get server info [#get-server-info] `GET` `/frontoffice/api/v3/info` #### Summary [#summary-9] Use this method to retrieve current server time and timezone information. #### Request [#request-9] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`serverTime`** `string` The server time, in the Unix timestamp format. **`serverTimeZone`** `string` The server time zone. ```json title="Response example — 200: OK" { "serverTime": "1755190380", "serverTimeZone": "+00:00" } ``` ### Get server time zones [#get-server-time-zones] `GET` `/frontoffice/api/v3/info/time-zones` #### Summary [#summary-10] Use this method to retrieve available server time zones. #### Request [#request-10] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info/time-zones HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-10] In case of success, an array of objects will be returned. Each object contains the following information: **`id`** `string` The time zone identifier. **`offset`** `string` The UTC offset, in the following format: `HH:MM:SS`. **`offsetInMinutes`** `integer · int32` The UTC offset in minutes. **`shortLabel`** `string` The short label for the time zone. **`label`** `string` The display label for the time zone. ```json title="Response example — 200: OK" [ { "id": "Africa/Abidjan", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Abidjan", "label": "(UTC+00:00) Côte d’Ivoire Time" }, { "id": "Africa/Algiers", "offset": "01:00:00", "offsetInMinutes": 60, "shortLabel": "Africa/Algiers", "label": "(UTC+01:00) Central European Time (Algiers)" }, { "id": "Africa/Bissau", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Bissau", "label": "(UTC+00:00) Guinea-Bissau Time" }, ... ] ``` ## Webhooks [#webhooks] ### Create webhook API key [#create-webhook-api-key] `POST` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-11] Create a new webhook API key for receiving TradingView alerts. #### Request [#request-11] ##### Header parameters [#header-parameters] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Body [#body-2] **`name`** `string` `required` A descriptive name for the API key, up to 100 characters. ```http title="Request example" POST /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "name": "My TradingView Key" } ``` #### Response [#response-11] In case of success (`201`), the created API key object is returned. **`id`** `string` The unique identifier of the API key. **`apiKey`** `string` The full API key value. The key is shown only once at creation. **`name`** `string` The name assigned to the key. **`userId`** `string` The user identifier the key is bound to. **`status`** `string` The key status: `Active`. **`createdAt`** `string` The timestamp when the key was created. **`expiresAt`** `string` The timestamp when the key expires (one year from creation). ```json title="Response example" { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "apiKey": "wh_key_abc123def456...", "name": "My TradingView Key", "userId": "01JZ3CVZKN20410JPYYH1YZJSK", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ``` The API key is shown only once in the creation response. It can't be retrieved again after this call. *** ### List webhook API keys [#list-webhook-api-keys] `GET` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-12] Retrieve all webhook API keys for the authenticated user along with the webhook URL. #### Request [#request-12] ##### Header parameters [#header-parameters-1] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ```http title="Request example" GET /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-12] In case of success (`200`), the webhook URL and a list of API keys are returned. **`webhookUrl`** `string` The webhook URL to configure in TradingView alerts. **`apiKeys`** `array of objects` The list of API keys. **`apiKeys[].id`** `string` The unique identifier of the API key. **`apiKeys[].name`** `string` The name assigned to the key. **`apiKeys[].status`** `string` The key status. Possible values: * `Active` * `Revoked` * `Expired` **`apiKeys[].createdAt`** `string` The timestamp when the key was created. **`apiKeys[].expiresAt`** `string` The timestamp when the key expires. ```json title="Response example" { "webhookUrl": "https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3...", "apiKeys": [ { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "name": "My TradingView Key", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ] } ``` *** ### Revoke webhook API key [#revoke-webhook-api-key] `DELETE` `/frontoffice/api/v3/webhook/api-keys/{id}` #### Summary [#summary-13] Revoke an active webhook API key. After revocation, the key can no longer be used to authenticate webhook requests. #### Request [#request-13] ##### Header parameters [#header-parameters-2] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Path parameters [#path-parameters-3] **`id`** `string` `required` The unique identifier of the API key to revoke. ```http title="Request example" DELETE /frontoffice/api/v3/webhook/api-keys/01JZ3CVZKN20410JPYYH1YZJSK HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-13] In case of success (`200`), a confirmation object is returned. **`success`** `boolean` Indicates whether the key was revoked successfully. **`message`** `string` A description of the result. ```json title="Response example" { "success": true, "message": "API key revoked successfully" } ``` *** ### Receive TradingView alert [#receive-tradingview-alert] `POST` `/frontoffice/api/v3/webhook/alerts/{userId}` #### Summary [#summary-14] Accept a webhook alert from TradingView and place an order on the specified trading account. TradingView calls this endpoint when an alert triggers. #### Request [#request-14] ##### Path parameters [#path-parameters-4] **`userId`** `string` `required` The B2TRADER user identifier (ULID format). ##### Body [#body-3] **`apiKey`** `string` `required` The webhook API key for authentication. **`accountId`** `string` `required` The trading account identifier. **`symbol`** `string` `required` The market symbol with a type prefix (`spot.`, `cfd.`, or `perp.`) followed by the pair name. For example: `spot.btc_usdt`, `cfd.eur_usd`, `perp.btc_usdt`. **`side`** `string` `required` The order side. Possible values: * `buy` * `sell` **`quantity`** `decimal string` `required` The order quantity in the base asset. **`orderType`** `string` The order type. Default: `market`. Possible values: * `market` * `limit` * `stop` * `stop_limit` **`price`** `decimal string` The limit price. Required for `limit` and `stop_limit` orders. **`stopPrice`** `decimal string` The stop price. Required for `stop` and `stop_limit` orders. **`leverage`** `decimal string` The leverage ratio. Applicable to CFD and Perpetual Futures markets only. **`takeProfit`** `decimal string` The take profit trigger price. **`stopLoss`** `decimal string` The stop loss trigger price. **`timeInForce`** `string` The time-in-force policy. Default: `gtc`. Possible values: * `gtc` * `ioc` * `fok` * `day` **`comment`** `string` A custom comment, up to 256 characters. **`deduplicationId`** `string` A UUID for idempotency. Duplicate requests with the same ID within five minutes return a cached response. ```http title="Request example" POST /frontoffice/api/v3/webhook/alerts/01JZ3CVZKN... HTTP/1.1 Host: {host} Content-Type: application/json { "apiKey": "wh_key_abc123def456...", "accountId": "01JZ3CVZKN20410JPYYH1YZJSK", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01", "comment": "TV Strategy Signal" } ``` #### Response [#response-14] In case of success (`200`), an order confirmation is returned. **`success`** `boolean` Indicates whether the order was placed successfully. **`orderId`** `string` The unique identifier of the created order. **`orderStatus`** `string` The initial status of the order. **`message`** `string` A description of the result. **`timestamp`** `string` The timestamp of the response. ```json title="Response example" { "success": true, "orderId": "01JZ3CVZKN20410JPYYH1YZJSK", "orderStatus": "Working", "message": "Order placed successfully", "timestamp": "2026-02-02T12:34:56.789Z" } ``` #### Rate limits [#rate-limits] Webhook requests are limited to five requests per second per user. If the limit is exceeded, the response returns a `429` status code with the following headers: * `X-RateLimit-Limit`: Maximum requests per window * `X-RateLimit-Remaining`: Remaining requests in the current window * `X-RateLimit-Reset`: Unix timestamp when the window resets ## Orders [#orders] ### Place SPOT order [#place-spot-order] `POST` `/frontoffice/api/v3/orders` #### Summary [#summary] Use this method to create and submit a new order for SPOT markets. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Body [#body] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Limit", "timeInForce": "Gtc", "requestedAmount": 0.02, "requestedPrice": 115193.35, "comment": "Strategy A" } } ``` #### Response [#response] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. Right after the order is created commission is `0`. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K1ZTB4DB0S6Y2NH81S781BQX", "orderType": "Limit", "side": "Buy", "status": "Pending", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.02", "remainingAmount": "0.02", "requestedPrice": "115193.35", "executionPrice": "0", "createdAt": "2025-08-06T13:50:13.931Z", "updatedAt": "2025-08-06T13:50:13.9325008Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Place CFD order [#place-cfd-order] `POST` `/frontoffice/api/cfd/v4/orders` #### Summary [#summary-1] Use this method to create and submit a new order for CFD markets. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "timeInForce": "Gtd", "requestedLotAmount": 1, "requestedPrice": 3280, "leverage": 75, "cancellationDate": "2025-08-10T00:00:00Z", "stopLoss": { "price": 3320, "isTrailing": false }, "takeProfit": { "price": 3200 }, "comment": "Strategy A" } } ``` #### Response [#response-1] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2253Q9X3VTJ68PNWY40JC6Q", "status": "Pending" } } ``` ### Place PF order [#place-pf-order] `POST` `/frontoffice/api/perpetual/v4/orders` #### Summary [#summary-2] Use this method to create and submit a new order for Perpetual markets. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `perp.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "perp.eth_usdt", "side": "Buy", "orderType": "Market", "timeInForce": "Ioc", "requestedLotAmount": 10, "leverage": 159, "comment": "Strategy A" } } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K228VN55N7WFZRG70M24T9J1", "status": "Working" } } ``` ### Cancel order [#cancel-order] `DELETE` `/frontoffice/api/v3/orders/``{orderId}` #### Summary [#summary-3] Use this method to cancel an active order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`orderId`** `required` The order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/orders/01K2PF9XS29WN4JZRHMCTTQYJB HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` * `StopOrder` * `FixApi` * `System` **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.eth_usdt", "marketDisplayName": "SPOT ETH/USDT", "orderId": "01K2PF9XS29WN4JZRHMCTTQYJB", "orderType": "Limit", "side": "Buy", "status": "Cancelled", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.1", "remainingAmount": "0.1", "requestedPrice": "4450", "executionPrice": "0", "createdAt": "2025-08-15T08:59:51.97Z", "updatedAt": "2025-08-15T09:00:06.2791048Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Get SPOT order data [#get-spot-order-data] `POST` `/frontoffice/api/v3/order-data` #### Summary [#summary-4] Use this method to retrieve and validate order data for SPOT market orders before placing. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-3] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.requestedBaseAmount`** `decimal string | nullable` The requested amount in base asset units. **`order.requestedQuoteAmount`** `decimal string | nullable` The requested amount in quote asset units. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. ```http title="Request example" POST /frontoffice/api/v3/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=3.0 Accept: */* { "order": { "marketId": "spot.eth_usdt", "side": "Buy", "orderType": "Limit", "requestedBaseAmount": 0.2, "requestedPrice": 4600 } } ``` #### Response [#response-4] In case of success, an object will be returned. Each object contains the following information: **`baseAmount`** `decimal string` The calculated base asset amount for the order. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmount`** `decimal string` The estimated commission amount to be charged. **`total`** `decimal string` The total quote asset amount, including the estimated commission. ```json title="Response example — 200: OK" { "order": { "baseAmount": "0.2", "quoteAmount": "920", "commissionAmount": "9.2", "total": "929.2" } } ``` ### Get CFD order data [#get-cfd-order-data] `POST` `/frontoffice/api/cfd/v4/order-data` #### Summary [#summary-5] Use this method to retrieve and validate order data for CFD market orders before placing. #### Request [#request-5] ##### Header parameters [#header-parameters-5] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables the Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/cfd/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": 15000, "triggerType": "points" }, "stopLoss": { "triggerSize": "4020", "triggerType": "price", "isTrailing": false }, "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Market", "leverage": 135, "requestedLotAmount": 1 } } ``` #### Response [#response-5] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "34.4613643", "quoteAmount": "4004.345", "commissionAmountInRAT": "0", "marginLevel": "5.3015", "takeProfit": { "price": "3989.345", "rate": "0.0037", "points": 15000, "pnl": "17.42713545" }, "stopLoss": { "price": "4020", "rate": "-0.0039", "points": -15655, "pnl": "-18.18812036" } } } ``` ### Get PF order data [#get-pf-order-data] `POST` `/frontoffice/api/perpetual/v4/order-data` #### Summary [#summary-6] Use this method to retrieve and validate order data for Perpetual market orders before placing. #### Request [#request-6] ##### Header parameters [#header-parameters-6] **`accountId`** `required` The trading account identifier. ##### Body [#body-5] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/perpetual/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": "0.01", "triggerType": "rate" }, "stopLoss": { "triggerSize": "-100", "triggerType": "pnl", "isTrailing": false }, "marketId": "perp.btc_usdt", "side": "Buy", "orderType": "Limit", "leverage": 100, "requestedLotAmount": 0.5, "requestedPrice": 118450 } } ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "592.25", "quoteAmount": "59225", "commissionAmountInRAT": "0", "marginLevel": "0.3582", "takeProfit": { "price": "119634.5", "rate": "0.01", "points": 11845, "pnl": "592.25" }, "stopLoss": { "price": "118250", "rate": "-0.0016", "points": -2000, "pnl": "-100" } } } ``` ## Stop orders [#stop-orders] ### Place SPOT Stop order [#place-spot-stop-order] `POST` `/frontoffice/api/v3/stop-orders` #### Summary [#summary-7] Use this method to create and submit a new Stop order for SPOT markets. #### Request [#request-7] ##### Header parameters [#header-parameters-7] **`accountId`** `required` The trading account identifier. ##### Body [#body-6] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Market", "activationPrice": 128000, "requestedAmount": 0.01, "timeInForce": "Ioc", "comment": "Strategy A" } } ``` #### Response [#response-7] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order, same as in the request. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K2MNC3BVR5WRTBEE9YWAS91K", "orderType": "Market", "side": "Buy", "requestedPrice": "0", "activationPrice": "128000", "requestedAmount": "0.01", "timeInForce": "Ioc", "status": "WaitingForActivation", "createdAt": "2025-08-14T16:07:25.8193038Z", "updatedAt": "2025-08-14T16:07:25.8193044Z", "cancellationDate": null, "comment": null } } ``` ### Place CFD Stop order [#place-cfd-stop-order] `POST` `/frontoffice/api/cfd/v4/stop-orders` #### Summary [#summary-8] Use this method to create and submit a new Stop order for CFD markets. #### Request [#request-8] ##### Header parameters [#header-parameters-8] **`accountId`** `required` The trading account identifier. ##### Body [#body-7] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "activationPrice": 3200, "requestedLotAmount": 0.5, "timeInForce": "Gtd", "leverage": 76, "requestedPrice": 3500, "cancellationDate": "2025-08-18T00:00:00Z", "stopLoss": { "price": "3900", "isTrailing": false }, "takeProfit": { "price": "3100" }, "comment": "Strategy A" } } ``` #### Response [#response-8] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNRWP2J1S8T9TKTCXWYY87", "status": "WaitingForActivation" } } ``` ### Place PF Stop order [#place-pf-stop-order] `POST` `/frontoffice/api/perpetual/v4/stop-orders` #### Summary [#summary-9] Use this method to create and submit a new Stop order for Perpetual markets. #### Request [#request-9] ##### Header parameters [#header-parameters-9] **`accountId`** `required` The trading account identifier. ##### Body [#body-8] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "perp.btc_usdt", "side": "Sell", "orderType": "Market", "activationPrice": 115000, "requestedLotAmount": 1, "timeInForce": "Fok", "leverage": 22, "stopLoss": { "price": "118020", "isTrailing": true }, "takeProfit": { "price": "113873" }, "comment": "Strategy A" } } ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNM0S8B2R9DS7BWJ8PGYPR", "status": "WaitingForActivation" } } ``` ### Cancel Stop order [#cancel-stop-order] `DELETE` `/frontoffice/api/v3/stop-orders/``{orderId}` #### Summary [#summary-10] Use this method to cancel an active Stop order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-10] ##### Header parameters [#header-parameters-10] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The Stop order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/stop-orders/01K2MNGAWPMQJ7WGATFSCAS1G4 HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-10] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. ```json title="Response example — 200: OK" { "order": { "marketId": "perp.btc_usdt", "marketDisplayName": "Perpetual BTC/USDT", "orderId": "01K2MNGAWPMQJ7WGATFSCAS1G4", "orderType": "Limit", "side": "Sell", "requestedPrice": "115100", "activationPrice": "115000", "requestedAmount": "1", "timeInForce": "Gtc", "status": "Rejected", "createdAt": "2025-08-14T16:09:44.5986099Z", "updatedAt": "2025-08-14T16:09:44.5986103Z", "cancellationDate": null } } ``` ## Positions [#positions] ### Close position [#close-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/close` #### Summary [#summary-11] Use this method to close a specific position entirely or partially. #### Request [#request-11] ##### Header parameters [#header-parameters-11] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-2] **`positionId`** `required` The position identifier to close. ##### Body [#body-9] **`closePositionLotAmount`** `decimal string | nullable` The portion of the position to close, in lots. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PFXDP1FWCJSGTX4GJ6JHM0/close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-11] In case of success, an object will be returned. Each object contains the following information: **`positionId`** `string` The position identifier. ```json title="Response example — 200: OK" { "positionId": "01K2PFXDP1FWCJSGTX4GJ6JHM0" } ``` ### Bulk close positions [#bulk-close-positions] `POST` `/frontoffice/api/v4/positions/bulk-close` #### Summary [#summary-12] Use this method to close multiple positions simultaneously based on different criteria such as all positions, positive PnL only, or negative PnL only. #### Request [#request-12] ##### Header parameters [#header-parameters-12] **`accountId`** `required` The trading account identifier. ##### Body [#body-10] **`mode`** `string` `required` The bulk close mode. Possible values: * `AllPositions` — close all positions. * `PositivePnl` — close only positions with positive PnL. * `NegativePnl` — close only positions with negative PnL. ```http title="Request example" POST /frontoffice/api/v4/positions/bulk-close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "mode": "AllPositions" } ``` #### Response [#response-12] In case of success, an object will be returned containing identifiers of closed positions. ```json title="Response example — 200: OK" { "status": "accepted", "positionIds": [ "01K228VNC2Q7E7K9W8GABWBZ5Z", "01K22BZ2DCETJZKW6MK81N1T8Y", "01K2CXF06A3A5SK2YFJT67CMZ5", "01K2CXF2ZJ6MJYMEK663TBBY8K", "01K2PFXDP1FWCJSGTX4GJ6JHM0" ] } ``` ### Get trigger data [#get-trigger-data] `POST` `/frontoffice/api/v4/positions/``{positionId}``/trigger-data` #### Summary [#summary-13] Use this method to retrieve Stop loss and Take profit settings for an open position. #### Request [#request-13] ##### Header parameters [#header-parameters-13] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-3] **`positionId`** `required` The position identifier. ##### Body [#body-11] **`stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`stopLoss.isTrailing`** `boolean | nullable` Indicates if Stop loss is Trailing. **`takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/trigger-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "triggerSize": "-0.01", "triggerType": "rate", "isTrailing": true }, "takeProfit": { "triggerSize": 2500, "triggerType": "points" } } ``` #### Response [#response-13] In case of success, an object will be returned. Each object contains the following information: **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "takeProfit": { "price": "248.27", "rate": "0.1119", "points": 2500, "pnl": "21.5" }, "stopLoss": { "price": "221.04", "rate": "-0.01", "points": -223, "pnl": "-1.91" } } ``` ### Submit triggers [#submit-triggers] `PUT` `/frontoffice/api/v4/positions/``{positionId}``/triggers` #### Summary [#summary-14] Use this method to modify Stop loss and Take profit settings for an open position. #### Request [#request-14] ##### Header parameters [#header-parameters-14] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-4] **`positionId`** `required` The position identifier. ##### Body [#body-12] **`stopLoss.price`** `decimal string` The Stop loss trigger price. **`stopLoss.isTrailing`** `boolean` If `true`, enables the Trailing behavior for Stop loss. **`takeProfit.price`** `decimal string` The Take profit trigger price. ```http title="Request example" PUT /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/triggers HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "price": "165.13", "isTrailing": true }, "takeProfit": { "price": 250 } } ``` #### Response [#response-14] In case of success, an object will be returned containing the identifier of the updated position. ```json title="Response example — 200: OK" { "positionId": "01K2HYXA7N2G9NHTFEWYVM9SEQ" } ``` ## Commissions [#commissions] ### Get account trading volume [#get-account-trading-volume] `GET` `/frontoffice/api/v3/commission/``{dynamicCommissionGroupId}``/account-trading-volume` #### Summary [#summary-15] Use this method to obtain a cumulative account trading volume used for calculating the commission tier. #### Request [#request-15] ##### Header parameters [#header-parameters-15] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-5] **`dynamicCommissionGroupId`** `required` The dynamic commission group identifier. Use [Get market](settings#get-market) to obtain. ```http title="Request example" GET /frontoffice/api/v3/commission/{dynamicCommissionGroupId}/account-trading-volume HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-15] In case of success, an object will be returned containing current trading volume, in RAT, for the account. ```json title="Response example — 200: OK" { "currentTradingVolumeInRAT": "string" } ``` You can connect B2Trader to **ChatGPT** as a **connector**. It uses the same B2Trader MCP URL and OAuth sign-in as every other agent. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in ChatGPT's connector directory. Connector availability depends on your ChatGPT plan. ## Connect the B2Trader connector [#connect-the-b2trader-connector] 1. In ChatGPT, open **Settings** → **Connectors**. 2. Choose to add a connector by **URL** (custom connector). 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Confirm. ChatGPT reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — no API key is pasted into ChatGPT. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. ChatGPT lists the connector as connected, and the B2Trader tools become available to it. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — ChatGPT receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and ChatGPT stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector appears as connected in ChatGPT's settings. * B2Trader tools are available to ChatGPT in your chats. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In ChatGPT, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). You can connect B2Trader to **Claude** in two places: * **claude.ai** (web and desktop app) — add B2Trader as a **custom connector**. * **Claude Desktop** — add B2Trader as an MCP server; the OAuth sign-in completes through Claude's hosted redirect (`https://claude.ai/api/mcp/auth_callback`). Both use the same B2Trader MCP URL and the same OAuth sign-in. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in Claude's connector directory. ## Connect on claude.ai [#connect-on-claudeai] 1. Open **Settings** → **Connectors** in claude.ai. 2. Click **Add custom connector**. 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Click **Add**. Claude reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — you are **not** pasting an API key into Claude. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. Claude shows the connector as **Connected**, and the B2Trader tools appear in the tool list for your conversations. ## Connect in Claude Desktop [#connect-in-claude-desktop] 1. Open **Claude Desktop** → **Settings** → **Connectors**. 2. Add a new MCP server pointing at the B2Trader MCP URL for your surface. 3. Claude Desktop opens your browser for OAuth sign-in and completes the flow through Claude's **hosted** redirect (`https://claude.ai/api/mcp/auth_callback`), a pre-registered redirect URI. 4. Sign in and — for full access — approve the consent screen. 5. The B2Trader tools appear in Claude Desktop once the connector reports **Connected**. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — Claude receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and Claude stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector is listed as **Connected** in Claude's settings. * B2Trader tools (for example `trader_get_accounts`, plus platform market-data and portfolio tools) are available to Claude in your conversations. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In Claude, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). If you are building your own agent (for example with an Agent SDK) or using an MCP client that is not Claude or ChatGPT, you connect to the same two B2Trader endpoints and the same OAuth flow. This page covers the OAuth details a custom client needs. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` `` is the domain you open your B2Trader terminal on, not a separate API address. ## OAuth discovery [#oauth-discovery] Your client needs no B2Trader-specific configuration beyond the MCP URL. B2Trader is an OAuth 2.1 protected resource and advertises everything a compliant client needs: 1. Your client calls the MCP endpoint without a token and receives `401 Unauthorized` with a `WWW-Authenticate: Bearer resource_metadata="…"` header. 2. That header points at the protected-resource metadata (RFC 9728) for the surface you called — each surface has its own document: `https:///.well-known/oauth-protected-resource/mcp-read-only` and `https:///.well-known/oauth-protected-resource/mcp-full-access`. Fetching it returns the resource identifier, the authorization server (your broker's Keycloak realm), and `scopes_supported` — one scope only, matching the surface: `[mcp:read]` for `/mcp-read-only`, `[mcp:trade]` for `/mcp-full-access`. 3. Your client runs the standard OAuth 2.1 **authorization-code flow with PKCE** against that authorization server, requesting the scope for the surface you want. 4. B2Trader validates the token's audience (`bbp-mcp`) and the required scope (`mcp:read` for read-only, `mcp:trade` for full access) before serving any tool. Use a compliant MCP client library — it performs discovery, PKCE, and token refresh for you. You only supply the MCP URL. ## Pre-registered OAuth clients [#pre-registered-oauth-clients] B2Trader ships two pre-registered public OAuth clients. Use the one matching your surface: | Surface | `client_id` | Scope | Consent | | ----------- | ----------------- | ----------- | ---------------------------- | | Read-only | `mcp-read-only` | `mcp:read` | None | | Full access | `mcp-full-access` | `mcp:trade` | Explicit trade-scope consent | Both are **public** clients (no client secret) and require **PKCE (S256)**. A custom client authenticates as one of these `client_id`s and completes the browser sign-in as any other agent does. Depending on how your broker set up your platform, the page that opens is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account — your client behaves the same either way. ## Command-line agents (Codex CLI, Claude Code) [#command-line-agents-codex-cli-claude-code] Command-line MCP clients default to **Dynamic Client Registration (DCR)** — on first connect they try to register a brand-new OAuth client with the authorization server instead of using a fixed `client_id`. The B2Trader Keycloak realm does not permit anonymous DCR, so these tools must be told to use one of the pre-registered `client_id`s above: * **Codex CLI:** ```bash codex mcp add --url --oauth-client-id mcp-full-access codex mcp login ``` Use `mcp-read-only` in place of `mcp-full-access` for the read-only surface. * **Claude Code:** ```bash claude mcp add --transport http --client-id mcp-full-access --callback-port 8080 ``` Without an explicit `client_id`, both tools fall back to anonymous DCR, which the authorization server rejects — the connection fails before you reach the sign-in page. ## Redirect URIs [#redirect-uris] The pre-registered clients accept these redirect URIs: | Redirect URI | Use | | ------------------------------------------------------- | ----------------------------------------------------- | | `https://claude.ai/api/mcp/auth_callback` | Claude (claude.ai) | | `https://chatgpt.com/connector_platform_oauth_redirect` | ChatGPT | | `http://localhost:8080/*` | Claude Code — fixed callback port | | `http://127.0.0.1/*` | Codex CLI and other loopback clients — ephemeral port | If your custom agent runs locally, use one of the loopback redirects above. Most Agent SDKs and MCP client libraries (including Codex CLI) default to an ephemeral-port loopback callback on `127.0.0.1`, matching `http://127.0.0.1/*`, so no configuration change is needed. Claude Code is the exception: it needs a **fixed** callback port to match a registered redirect, so pass `--callback-port 8080` (matching `http://localhost:8080/*`) as shown above. ## Adding a custom redirect URI (broker step) [#adding-a-custom-redirect-uri-broker-step] If your agent runs on a hosted callback URL that is **not** one of the above (for example a server-side agent with its own public redirect), your broker must add that redirect URI to the pre-registered client in Keycloak before sign-in will succeed. A redirect URI that is not registered on the client fails at the sign-in step with an "Invalid redirect URI" error from Keycloak. Send your broker the exact callback URL your agent uses and which surface it needs (read-only or full access). Adding a redirect URI is a broker-side change to the MCP client registration. It requires no product change and is the documented path for onboarding custom, non-marketplace agents. ## Full access [#full-access] If your custom agent uses the full-access surface, the same [full-access safety](full-access-safety) rules apply: no per-action confirmation, irreversible actions, and the prompt-injection risk of an autonomous agent. Read that page before granting `mcp:trade`. The full-access surface (`/mcp-full-access`) lets a connected AI agent trade on your account **directly**. This page explains exactly what that means and how to stay in control. Read it before you approve the full-access consent screen. Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. ## No per-action confirmation [#no-per-action-confirmation] The in-terminal **AI Assistant chat** asks you to confirm each trade before it executes. The full-access MCP surface does **not**. Once connected, the agent can place, cancel, and close orders and set price triggers on its own, as fast as it decides to — there is no confirmation dialog and no "are you sure?" step. ## Actions are irreversible [#actions-are-irreversible] Trades execute against the live market. A filled order, a closed position, or a cancelled order **cannot be undone**. If your agent makes a mistake — or is manipulated into one — the market result stands. ## Prompt-injection risk [#prompt-injection-risk] An autonomous agent acts on the text it reads. If your agent processes untrusted content — a web page, an email, a chat message, a document — that content can contain hidden instructions telling the agent to trade against your interest. This is called **prompt injection**. Because the full-access surface has no confirmation gate, a successful injection can move real money before you notice. To reduce the risk: * Prefer the **read-only** surface unless you specifically need the agent to trade. * Only grant full access to agents and workflows you trust and control. * Be cautious about letting a full-access agent read untrusted external content in the same session it can trade. ## How to stop your agent [#how-to-stop-your-agent] You have two independent controls. Use either — or both. 1. **Stop it in the agent (fastest).** Disconnect or remove the B2Trader connector in your agent (Claude, ChatGPT, or your custom client). The agent immediately stops making new calls. 2. **Revoke the grant in B2Trader.** Open your **account console** (your broker's Keycloak account page) → **Applications**, find the connected MCP application, and **revoke** its access. This removes your consent so the agent cannot obtain a new token. There is no broker-side "kill switch" that instantly voids a token already in the agent's hands. A token the agent already holds stays valid until it expires (see [Access tokens are short-lived](#access-tokens-are-short-lived)). Revoking in the account console stops **new** tokens; disconnecting in the agent stops it using the one it has. Do both to be certain. ## You still get execution notifications [#you-still-get-execution-notifications] Every order the agent places, cancels, or closes fires the **same account notifications** you already receive for terminal activity. Your normal notification channels keep working, so a full-access agent cannot act silently — watch them to see what your agent is doing. ## Access tokens are short-lived [#access-tokens-are-short-lived] The agent's access token has a **short lifetime**. If you revoke consent in the account console, the agent can finish using its current token but cannot get a new one once it expires — so a revoked grant fully lapses within the token's short window, without any forced server-side revocation. ## Choosing read-only instead [#choosing-read-only-instead] If you do not need the agent to trade, connect the **read-only** surface (`/mcp-read-only`) instead. Its tools cannot place or change anything — the trading tools are not part of that surface at all. See [Overview](overview) for the comparison. B2Trader can expose your trading account to external AI agents through the **Model Context Protocol (MCP)** — an open standard that lets AI applications such as Claude and ChatGPT call a defined set of tools on your behalf. Once you connect an agent, it can read your market data and portfolio, and — on the full-access surface — place and manage orders directly. This is different from the **in-terminal AI Assistant chat**, which runs inside the B2Trader terminal and confirms each trade with you before it executes. An external MCP agent runs in *its own* application (Claude, ChatGPT, or your own client) and connects to B2Trader over the internet using your account sign-in. Connecting an AI agent is optional — it's your choice whether to use it. The MCP surfaces are available by default, though your broker can restrict or disable them for your platform. The MCP endpoints live on the same domain you use to open your B2Trader terminal, so wherever these pages show `https:///…`, that means your terminal address — not a separate API address. If a connection URL below doesn't work, contact your broker. ## Two surfaces [#two-surfaces] B2Trader publishes **two** separate MCP endpoints. You choose one when you connect your agent. | | Read-only | Full access | | ------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Endpoint path** | `/mcp-read-only` | `/mcp-full-access` | | **What the agent can do** | View market data, your portfolio, order and position history, and analytics | Everything in read-only **plus** place, cancel, and close orders and set price triggers | | **Tools exposed** | 23 | 39 | | **Trading** | None — mutating tools are not present at all | Full trading, with **no per-action confirmation** | | **OAuth scope** | `mcp:read` | `mcp:trade` | | **Consent screen** | No extra consent | Explicit trade-scope consent (see [Full-access safety](full-access-safety)) | | **Marketplace-listed** | Yes | No — connect by URL | The **read-only** surface is the one listed in AI marketplaces (for example the Claude and ChatGPT connector directories). It is safe to connect broadly: the trading tools are **structurally absent** — the agent cannot see or call them. The **full-access** surface is connected by pasting its URL directly. It grants your agent the ability to trade with no confirmation gate. Read [Full-access safety](full-access-safety) before you connect it. ## Tool categories [#tool-categories] Both surfaces expose the same read tools; the full-access surface adds the mutating ones. | Category | Read-only | Full access | | ------------------------------------------------------------------------------ | --------- | ----------- | | Market data — B2Trader platform prices (tickers, order book, market summaries) | Yes | Yes | | Portfolio & account (balances, margin, open positions) | Yes | Yes | | Order & position history | Yes | Yes | | Analytics & reference data | Yes | Yes | | Place / cancel / close orders (single) | No | Yes | | Bulk order / position actions | No | Yes | | Set & edit price triggers, other account mutations | No | Yes | | **Total tools** | **23** | **39** | The 16 tools that the full-access surface adds are the mutating actions: single trading actions, bulk trading actions, and non-trading account mutations. ## Which surface to choose [#which-surface-to-choose] * **Choose read-only** if you want an agent to analyze markets, summarize your portfolio, or answer questions about your trading history. This is the recommended default and the safest option. * **Choose full access** only if you deliberately want your agent to trade for you without confirming each action, and you understand the risks in [Full-access safety](full-access-safety). ## Prerequisites [#prerequisites] Before connecting any agent you need: * A **B2Trader account** on a platform that offers the MCP surfaces. They are available by default; a broker can restrict or disable them. * Your account must be **active** (`bbp.spot.status = Active`) — the same status required to trade in the terminal. A non-active account can sign in, but its tool calls are rejected by the platform. * An AI application that supports MCP with OAuth — for example [Claude](connect-claude), [ChatGPT](connect-chatgpt), or a [custom agent](connect-custom-agent). ## How connecting works [#how-connecting-works] You never paste an API key or password into your agent. Connection uses **OAuth 2.1 with PKCE**: 1. You add the B2Trader MCP URL to your agent. 2. The agent discovers B2Trader's authorization server automatically — it reads the endpoint's protected-resource metadata at `/.well-known/oauth-protected-resource/mcp-read-only` or `/.well-known/oauth-protected-resource/mcp-full-access`, depending on the surface. 3. Your browser opens the sign-in page for your platform, where you sign in with the credentials you normally use. 4. For the full-access surface, you approve an explicit consent screen describing what the agent may do. 5. The agent receives a short-lived access token and is connected. No long-lived secret is stored in the agent. The sign-in page you see depends on how your broker set up your platform: either the B2Trader sign-in form, or the sign-in page of the portal you normally use to access your account, which opens automatically. If you are already signed in there in the same browser, no sign-in prompt appears. The per-client steps are covered in the connection guides: * [Connect Claude](connect-claude) * [Connect ChatGPT](connect-chatgpt) * [Connect a custom agent](connect-custom-agent) * [Full-access safety](full-access-safety) ## Global interface controls [#global-interface-controls] ### Account selection [#account-selection] The **Account select** is located in the topbar and enables you to switch between your trading accounts. Each account shows its type: `H` (Hedging) or `N` (Netting). Once you switch the account, all the widgets automatically adjust to show relevant information for the selected account. Account select #### Account status [#account-status] An account can have a status that limits what you can do with it. When a status applies, a status indicator is shown on the account, and a banner explains the restriction. Account status is managed by your administrator. The following statuses are visible to you: * **Halted**: A banner reads *Account is locked for trading. Contact your administrator.* The trading controls are disabled, but you can still deposit and withdraw funds, and your balances, positions, and history stay visible. * **Frozen**: A banner reads *Account is frozen. Contact your administrator.* The account is view-only. All controls are disabled, while your balances, positions, and history stay visible. To restore trading on an account that is Halted or Frozen, contact your administrator. Archived accounts don't appear in the account list. ### Instrument selection [#instrument-selection] The **Instrument select** is located in the topbar and enables you to switch between various markets and trading pairs. Once you change the market, all the widgets automatically adjust to show relevant information for the selected instrument. Instrument select #### Favorite markets [#favorite-markets] Mark instruments as favorites for quick access. To add or remove a market from favorites, click the **star icon** next to the market name in the instrument selection list. Favorite markets can be accessed in two ways: * **Favorites tab** in the instrument selection panel — filters the list to show only your favorite markets. * **Favorites dropdown** in the topbar — provides quick access to favorite markets from anywhere in the terminal. ### Settings [#settings] Use this control to access interface and system settings. Refer to [Settings](settings) for details. Settings ### Other controls [#other-controls] * **Introduction tour**: Access the interactive platform walkthrough. Introduction tour * **Alerts**: View new system notifications. Unread alerts * **Analytics**: Open the **Account Analytics** view with the **Equity Curve** chart — your account balance and equity dynamics over time (Margin Balance, Equity, Total Equity, Unrealized PnL, Deposits / Withdrawals) for a selected period and granularity. The data updates hourly. Click **Back to Trading** to return to the terminal. Analytics * **Log out**: Log out of the system to securely terminate the session. After that you’re navigated to the Login page. Log out ## Working with widgets [#working-with-widgets] > For more information about available widgets, refer to the **Widgets** section of this guide. ### Add widgets to your workspace [#add-widgets-to-your-workspace] **To add a new widget**: 1. Click the **Add Widget** button. 2. Browse the available widgets. 3. Click any widget to add it to your workspace. Add Widget **To add widgets to existing panels**: 1. Look for the **+** button next to the tabs in a panel's header. 2. Click it to open the widget catalog. 3. Select a widget to add it as a new tab to that panel. Add widget tabs ### Move and position widgets [#move-and-position-widgets] **To move a widget**: 1. Click and hold the **move handle** in the top-right corner of the panel header. 2. Drag it to desired location on the page. 3. Drop it. Move widgets **To rearrange widget tabs within a panel**: 1. Click and hold any widget tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ### Resize widgets [#resize-widgets] **To resize a widget panel**: * **Single edge**: Hover over any edge until you see the resize cursor, then drag. * **Corner resize**: Drag a corner to adjust both width and height simultaneously. * **Precision**: Use edge dragging for fine-tuned sizing. Resize widgets ### Remove widgets and tabs [#remove-widgets-and-tabs] **To remove a tab**: 1. Click the **×** button in the top-right corner of the widget tab. 2. The tab will be removed immediately. 3. When you remove the last tab from a panel, the entire panel disappears. Remove tabs and widget panels ### Link panels to a group [#link-panels-to-a-group] Each panel header has a **Link to group** button — the circle icon **next to the move handle** in the top-right corner. Linking panels to the same colored group keeps them in sync: when you select an instrument in one linked panel, the other panels in the same group switch to it automatically. **To link a panel to a group**: 1. Click the **Link to group** button (next to the move handle) in the panel's top-right corner. 2. Select one of the color groups (Group 1–5). 3. Repeat for other panels, choosing the same group to keep them synchronized. Link to group ### Customize widget content [#customize-widget-content] Certain widgets let you customize which columns to display and their order: Look for the **column settings** button in the widget header. **To customize columns**: 1. Click the **column settings** button. 2. **Show/hide columns**: Check or uncheck boxes (grayed-out columns are required). 3. **Reorder columns**: Drag and drop items in the list. 4. **Reset**: Click *Reset to default* to restore original settings. Configure columns ## Managing workspaces [#managing-workspaces] ### Create new workspaces [#create-new-workspaces] **To create a workspace**: 1. Click the **+** tab next to your existing workspaces. 2. Choose a template: * **Pre-built templates**: Start with common widget combinations. * **Empty**: Build completely from scratch. 3. Enter a name for your workspace. 4. Start customizing. Add a new workspace ### Workspace management [#workspace-management] **To rename or delete a workspace**: 1. Click the menu icon on the workspace tab. 2. Select **Rename** or **Remove**. Workspace menu **To reorder workspaces**: 1. Click and hold any workspace tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ## Market info panel [#market-info-panel] Click the **info icon** next to a market symbol in widgets to view: * Detailed market information. * Trading session schedules. * Leverage details (for CFD and PF markets). * Fee details. * Funding details (for PF markets). Market info ## Pro tips [#pro-tips] ### Efficient layout building [#efficient-layout-building] * Start with a template that is close to your needs, then customize. * Group related widgets in tabs to save screen space. * Use larger panels for charts, smaller ones for order books. ### Layout best practices [#layout-best-practices] * **Save multiple workspaces** for different trading strategies. * **Test your layout** during low-activity periods. * **Keep essential widgets visible** (account info, positions, alerts). Access settings by clicking the **gear icon** in the topbar of the Trading terminal. Settings Settings are organized into tabs: * [Interface](#interface): Configure language, time display, and visual theme. * [Widgets](#widgets): Customize widget display options. * [Action Confirmation](#action-confirmation): Choose which actions require additional confirmation. * [Account margin](#account-margin): Manage collateral assets for margin trading. * [Trading report](#trading-report): Generate comprehensive trading and account reports. * [API token management](#api-token-management): Generate and manage tokens for accessing the Trading API. * [TradingView Webhooks](#tradingview-webhooks): Configure TradingView webhook alerts for automated order execution. ## Interface [#interface] Configure global interface preferences: **Language** Select the interface language from the dropdown menu. **24 hour mode** * Enable: Display time in 24-hour format. * Disable: Display time in 12-hour format with AM/PM. **Dark theme** * Enable: Apply dark color scheme. * Disable: Apply light color scheme. ## Widgets [#widgets] Configure display options for the following widgets. ### Price chart [#price-chart] **Display positions** When enabled, open positions are shown on the chart along with: * Position size and current PnL. * Quick access to edit price triggers and close positions. * Color coding: Long positions (green), Short positions (red). **Display orders and triggers** When enabled, the following orders and triggers are displayed on the chart: * Active Limit and Stop orders with order type, price, and amount. * Stop loss, Take profit, and Trailing stop triggers. * Quick access to edit triggers and cancel orders. * Color coding: Buy orders (green), Sell orders (red). **Display executed orders** When enabled, executed orders are shown on the chart with order type indicators: * Green `B` tag for Buy orders. * Red `S` tag for Sell orders. Clicking `B` or `S` will open details of one or more orders that were executed during the candle interval. **Market quick trade panel** When enabled, a panel is displayed on the chart for placing Market orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. **Limit quick trade panel** When enabled, a panel is displayed on the chart for placing Limit orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. ## Action Confirmation [#action-confirmation] Choose which trading actions require an additional confirmation dialog before execution. **Cancel orders** * Enable: A confirmation dialog is displayed before canceling orders. * Disable: Orders are canceled immediately without confirmation. This setting applies to single and bulk order cancellations from the **Open Orders** widget and the **Price chart**. The confirmation dialog includes a **"Don't ask again"** checkbox. To skip the confirmation for future order cancellations, check this box. **Full Close Positions** * Enable: A confirmation dialog is displayed before closing positions. * Disable: Positions are closed immediately without confirmation. This setting applies to single and bulk position closures from the **Open Positions** widget. **Limit order cross-TOB warning** * Enable: A confirmation dialog is displayed before a Limit order is submitted if its price crosses the current top-of-book — that is, when a Buy price is at or above the best ask, or a Sell price is at or below the best bid. The dialog shows the entered price and the current best bid/ask, and includes a **Do not show this warning again** checkbox. * Disable: Crossing Limit orders are submitted immediately without the warning. The warning is enabled by default. The dialog checkbox and this toggle share the same global setting and stay in sync. The warning is informational only — it does not block the order. If you confirm, the order is submitted with the original price. The warning applies only to standard Limit orders; Stop-limit, Take-profit-limit, IOC, FOK, and other order types are not affected. If best bid or best ask data is unavailable (empty book or disconnected feed), the order is submitted without the warning. ## Account margin [#account-margin] Control which assets can be used as collateral for margin trading. ### Asset list [#asset-list] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance available for trading, calculated as *Total – Halted*, where *Halted* represents funds locked for pending Limit orders. *** **Total** The complete asset balance including locked funds. *** **Margin ratio** The percentage of asset value that can be used as collateral for margin trading. *** **Use as margin** Enable this toggle to use the asset as collateral for margin trading. Configure which assets can be used as collateral for margin trading by toggling the **Use as margin** setting for each asset. Only assets with **Margin ratio** greater than 0 (zero) can be enabled. The platform root asset is enabled by default and can't be disabled. ### Filtering options [#filtering-options] Click the **funnel icon** to configure the asset list display: * **Show/Hide zero balances**: Control visibility of assets with zero balance. By default, hidden. * **Show/Hide assets unused as margin**: Control visibility of assets with disabled margin usage. * **Show/Hide assets with zero margin ratio**: Control visibility of assets that can't be used as collateral. By default, hidden. ## Trading report [#trading-report] Generate comprehensive reports containing: * **Trade history** * Closed positions * Executed orders * Individual trades * **Transfers history** * All account transfers * **Account statistics** * Total balance * Realized PnL * Position swaps * Position funding * Commissions To generate a report: 1. Select a custom period of time (UTC time), or generate a report for your entire account history using the **All data** range. The following timeframe presets have been implemented for your convenience: * **Today** * **Current**: week, month, quarter * **Previous**: week, month, quarter * **All data**. 2. Click **Download**. Once generated, the report will be automatically downloaded to your computer as a zipped CSV file. ## API token management [#api-token-management] Generate tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/): * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time To generate a token: 1. Click **+ Create new**. 2. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 3. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ## TradingView Webhooks [#tradingview-webhooks] Use TradingView Webhooks to automatically execute orders on your trading account based on alerts from TradingView. When a TradingView alert triggers, it sends a webhook request to B2TRADER, which places an order according to the parameters specified in the alert message. This feature supports all market types: Spot, CFD, and Perpetual Futures. ### Set up the webhook [#set-up-the-webhook] #### Step 1: Create a webhook API key [#step-1-create-a-webhook-api-key] To create a webhook API key in the Trading terminal: 1. Click the **gear icon** in the topbar to open Settings. 2. Navigate to the **TradingView Webhooks** tab. 3. Click **+ Create new**. 4. In the popup, fill in a **Name** for the key. 5. Click **Create**. The popup displays the generated API key and the webhook URL. Copy both values and store them securely. The API key is shown only once at creation. It can't be retrieved after closing the popup. The following limits apply: * Maximum 10 active keys per user * Each key is valid for 1 year from creation * Keys can be revoked at any time #### Step 2: Configure the alert in TradingView [#step-2-configure-the-alert-in-tradingview] 1. In TradingView, create a new alert or edit an existing one. 2. In the **Notifications** section, enable **Webhook URL**. 3. Paste the webhook URL copied from the terminal. 4. In the **Message** field, enter the alert body in JSON format (see [Alert message format](#alert-message-format)). 5. Save the alert. When the alert triggers, TradingView sends the message to B2TRADER, and the order is placed automatically. ### Alert message format [#alert-message-format] The alert message is a JSON object with the following fields: | Field | Required | Description | | ----------------- | ----------- | -------------------------------------------------------------------------- | | `apiKey` | Yes | Webhook API key generated in the terminal | | `accountId` | Yes | Trading account ID | | `symbol` | Yes | Market symbol with type prefix (see [Symbol format](#symbol-format)) | | `side` | Yes | Order side: `buy` or `sell` | | `quantity` | Yes | Order quantity in base asset | | `orderType` | No | `market` (default), `limit`, `stop`, or `stop_limit` | | `price` | Conditional | Limit price. Required for `limit` and `stop_limit` orders | | `stopPrice` | Conditional | Stop price. Required for `stop` and `stop_limit` orders | | `leverage` | No | Leverage ratio. Applicable to CFD and Perpetual Futures markets only | | `takeProfit` | No | Take profit trigger price | | `stopLoss` | No | Stop loss trigger price | | `timeInForce` | No | `gtc` (default), `ioc`, `fok`, or `day` | | `comment` | No | Custom comment, up to 256 characters | | `deduplicationId` | No | UUID for idempotency. Duplicates within 5 minutes return a cached response | #### Symbol format [#symbol-format] The symbol must include a market type prefix: | Market type | Prefix | Example | | ----------------- | ------- | --------------- | | Spot | `spot.` | `spot.btc_usdt` | | CFD | `cfd.` | `cfd.eur_usd` | | Perpetual Futures | `perp.` | `perp.btc_usdt` | #### Examples [#examples] **Market buy order (Spot):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01" } ``` **Limit sell order with TP/SL (CFD):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "cfd.eur_usd", "side": "sell", "orderType": "limit", "price": "1.0900", "quantity": "1000", "leverage": "10", "takeProfit": "1.0800", "stopLoss": "1.0950", "timeInForce": "gtc" } ``` ### Manage webhook API keys [#manage-webhook-api-keys] To view or manage your webhook API keys, navigate to **Settings** > **TradingView Webhooks**. The following information is provided about each key: | Column | Description | | ----------- | ----------------------------------------------- | | **Name** | The name assigned to the key at creation | | **Status** | Current key status: Active, Revoked, or Expired | | **Created** | The date and time the key was generated | | **Expires** | The date and time the key expires | To revoke a key, click the **Revoke** button next to the key entry. ### Rate limits [#rate-limits] Webhook requests are limited to 5 requests per second per user. If this limit is exceeded, the request returns a `429` error code and the order isn't placed. ### Troubleshooting [#troubleshooting] The following table describes common error scenarios and their solutions: | Issue | Cause | Solution | | -------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | | `Invalid API key` | The API key is incorrect or wasn't copied in full | Generate a new key and update the TradingView alert | | `API key expired` | The key has passed its 1-year validity period | Generate a new key | | `API key revoked` | The key was manually revoked | Generate a new key | | `Invalid symbol format` | The symbol is missing a market type prefix | Add the prefix: `spot.`, `cfd.`, or `perp.` | | `Price required for limit order` | A `limit` or `stop_limit` order is missing the `price` field | Add the `price` field to the alert message | | `Rate limit exceeded` | More than 5 requests were sent within 1 second | Reduce the alert frequency in TradingView | | `Account not found` | The `accountId` doesn't exist or isn't accessible | Verify the account ID in the terminal | A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to limit and stop limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to limit and stop limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the BP, without taking into account the time settings of the devices from which the BP is accessed. ## iOS v1.35 [#ios-v135] This version includes: * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. Select a time period and granularity level to filter performance data, and switch between accounts using the built-in account selector. * **AI Assistant** A new **AI Assistant** widget provides AI-powered market analysis for each instrument, including trade recommendations, market sentiment, signal drivers, suggested actions, and key metrics. * **Quick order from the chart** You can now place orders directly from the **Price chart** by tapping a price pin. The **Quick Order** panel opens pre-filled at the selected price level for faster order placement. * **Customizable workspace** You can now reorder and show or hide bottom tabs in **Settings**, allowing you to tailor the terminal layout to your trading preferences. * **Adaptive interface by market type** Tabs, **Margin Level**, and perpetual funding indicators are now automatically hidden for accounts that do not have access to the corresponding market types, providing a cleaner and more focused interface. * **Landscape mode for the chart** Tapping the **Expand** button on the **Price chart** now automatically rotates the chart to landscape mode for a wider view. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.34 [#ios-v134] This version includes: * **Drag Take Profit and Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be adjusted by dragging their lines directly on the **Price chart**. Changes are applied to the order immediately, with automatic rollback if an error occurs. * **Demo accounts** Demo trading accounts are now supported, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets appear as chips in the market list and are indicated with an icon in the terminal. * **Credit in margin details** A dedicated **Credit** row has been added to the margin details section, providing visibility into credit amounts allocated to your trading account. * **Comments for orders, positions, and trades** You can now add a comment when placing an order or managing a position. The comment is visible throughout the trading lifecycle — on open orders, open positions, and in trade history. * **Margin Level display** When **Margin Level** data is unavailable, the field now displays "–" instead of 0% for clearer data visibility. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.33 [#ios-v133] This version includes: * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Hide zero balances settings relocated** The **Hide zero balances** toggle has been moved to the **Assets** tab for more intuitive access. * **Improved backend error messages** Backend error messages are now mapped to user-friendly descriptions, providing clearer feedback when issues occur. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.32 [#ios-v132] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Quick cancel button for open orders** The **Open orders** widget now features a quick **Cancel** button on each order card, enabling faster order cancellation directly from the list view. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Redesigned account selection header** The account selection section in the terminal header has been redesigned for improved navigation and a cleaner appearance. * **Updated closed positions design** The **Closed positions** widget has been updated with a refreshed layout for better readability and consistency with other trading widgets. * **Confirmation bottom sheet** Order and position actions now display a confirmation bottom sheet, helping to prevent accidental trades and providing a clearer review step before execution. * **Settings button relocated** The **Settings** button has been moved from the **Price chart** widget to the terminal header for easier access across all views. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.31 [#ios-v131] This version includes: Experience an advanced trading workflow with the introduction of our new **tiered leverage system**, offering dynamic leverage based on position size and enhanced margin visibility. This update also brings improved commission transparency with a dedicated Fees tab, enhanced market info, a new deposit shortcut, and updated screens for tiered commissions. We've also refined formatters to respect your selected app language for a more consistent experience. *** ## iOS v1.30 [#ios-v130] This version includes: * **Notifications widget** A new **Notifications** widget has been implemented providing quick access to system notifications related to price changes, Margin calls, Stop outs, Take profit and Stop loss triggers. * **Closing open positions from the Price chart** Open positions can now be closed directly on the **Price chart** screen ensuring quick reaction to volatile market conditions and efficient trade management. This feature is available if the **Display positions** setting is activated for the Price chart. * **Closing all open positions** The **Open positions** tab now features the **Close all** button that liquidates all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Canceling all active orders** The **Open orders** tab now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * **Trading session status** The **Trading session status** in the **Position details** is now accompanied by an info icon and an explanatory tooltip. * **Automatic horizontal scrolling for tabs** The horizontal auto scroll has been added to tabs. Active tabs are now automatically centered for optimal visibility and better accessibility to all available tabs. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.29 [#ios-v129] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding**/**Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Updated account creation process** When creating a trading account in the app, the **account type** can now be selected: **Hedging** or **Netting**, enabling traders to plan and adjust their trading strategies to maximize profit or reduce risk. Depending on the platform settings, the option may be prefilled or require manual selection. The account type can’t be changed after the account is created. * **Support for Take Profit, Stop Loss, and Trailing Stop** The **Take Profit**, **Stop Loss**, and **Trailing Stop** triggers are now supported in the app for CFD and PF trading. They can be applied to Market, Limit, and Stop orders, as well as to currently open positions. * **Support for price alerts** Price alerts are now fully supported in the app: * Multiple alerts can be added to monitor different price levels for any instrument. * Configure alerts based on a fixed price or a percentage change. * View a list of all configured alerts for each instrument. * Adjust or delete existing alerts as needed. * Triggered alerts are automatically removed to keep the list up to date. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order history widget. * **Admin-managed orders and positions** On the **Open positions**, **Closed positions**, and **Order history** widgets, if BP Admins have managed positions or orders, this is now indicated in the **Reason** field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, mitigate risks, or resolve outstanding positions before account termination. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.28 [#ios-v128] This version includes: * **Performance upgrade** Streamlined top-of-the-book ask and bid prices in the Place Order widget are now received through a dedicated socket for faster obtaining and display. * **Mobile and Web Consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** Placeholders are now displayed for empty fields and widgets for improved UX clarity. * **Internal improvements** Enhanced system logs for better diagnostics. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## Android v2.12.0 [#android-v2120] This version includes: * **AI Assistant** A new **AI Assistant** provides AI-powered market analysis for each market, including trade recommendations, a 12-month price forecast, market sentiment, signal drivers, suggested actions, and key metrics. * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. * **Account status indicators** Account statuses such as **Halted** and **Frozen** are now shown with badges and a warning banner, and the related trading actions are restricted accordingly. * **Quick order from the chart** You can now place orders directly from the **Price chart**, enabling faster reaction to market movements. * **Take Profit / Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be set by dragging their lines directly on the **Price chart**, with support for trailing Stop Loss. * **Cross-price limit order warning** A warning is now displayed before you place a **Limit** order whose price crosses the top of the **Order book**. This warning can be enabled or disabled in **Settings**. * **Customizable trading terminal** You can now customize the trading terminal layout and tab order from the new **Workspace** settings. * **Adaptive interface by market type** Margin- and perpetual-related tabs and indicators are now hidden for accounts with access to **Spot** markets only, providing a cleaner interface tailored to the account type. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.11.0 [#android-v2110] This version includes: * **Comment field in Place Order** An optional **Comment** field has been added to the **Place order** form in **Advanced Mode**. The field supports up to 100 characters and is available for all order types across Spot, CFD, and Perpetual markets. * **Full-screen chart mode** The **Price chart** widget now supports full-screen mode. Tap the **Expand** button to switch to a landscape view for a more detailed chart analysis. * **Credit information in margin details** A **Credit** row has been added to the margin section, providing visibility into credit amounts allocated to trading accounts. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.10.0 [#android-v2100] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Demo accounts** Demo trading accounts are now supported in the app, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets are synchronized between the web and mobile terminals. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Improved market status display** The **Market Closed** label is now automatically removed once live data starts updating, providing a more accurate representation of market availability. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.9.0 [#android-v290] This version includes: This update introduces the new **tiered leverage system**, enhanced fee transparency and fully redesigned Fees tab, quick Deposit/Trade shortcuts on account cards for faster navigation and various UI improvements across the app. *** ## Android v2.8.0 [#android-v280] This version includes: * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.7.0 [#android-v270] This version includes: * **Key position parameters on the TP/SL editing** Key position parameters, such as **Name**, **Side**, **Amount**, **Open price**, **Current price**, and **Leverage** are displayed at the top of the Take Profit/Stop Loss configuration screen to give you immediate, accurate context and reduce input errors. Values are updated in real time. * **Closing positions on the Price chart** You can now close positions directly on the **Price chart** widget, by tapping a position indicator. * **Canceling all active orders** The **Open orders** widget now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Closing all open positions** The **Open positions** widget now features the **Close all** button allowing to liquidate all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Closed position details** The **Order type** and **Time in force** values are now displayed for every closed position to improve trade execution transparency. * **Price chart settings saved** The **Price chart** widget now remembers your preferred timeframe and chart type settings. Each time you open the terminal, it displays the chart with your last selected settings. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.6.0 [#android-v260] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding/Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order History widget. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * Expanded capabilities for account administration and risk management for Brokers have been added. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.5.0 [#android-v250] This version includes: * **Stop Loss and Take Profit on the Price chart widget** * Introduction of Stop-Loss (SL) and Take-Profit (TP) lines on the Price chart for enhanced trading insights. * TP and SL are displayed as color-coded lines with only abbreviations visible. * Tap to view prices on the Y-axis and access deletion options. * **Full support for price alerts in the app** * Alerts can be set for specific price levels. * Alerts can be configured based on either a set price or a percentage change. * A list of configured alerts is available for each instrument. * Options to delete or adjust alerts are provided. * Triggered alerts are automatically removed from the list. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.4.0 [#android-v240] This version includes: * **New mobile features** * Introduction of Take Profit, Stop Loss, and Trailing Stop functionalities in the Mobile app. * Support for Netting accounts in the Mobile app. * **Mobile and Web consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** For order lists, the All/Spot/CFD filter is only displayed when there are both Spot and CFD orders, for improved UX clarity. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## June 10, 2026 [#june-10-2026] ### New features [#new-features] #### Guest mode [#guest-mode] A new **Guest mode** lets you explore the Trading terminal without signing in. As a guest you can browse markets and market categories, follow live price streams and interactive charts, and open the **AI Assistant** widget for market analysis. A dedicated guest workspace is provided, and the [Place order](../widgets/place-order) panel opens in the advanced view by default. A **Sign in** action is always available so you can switch to a full trading session at any time. ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Full account history in Trading reports [#full-account-history-in-trading-reports] You can now generate [Trading reports](../get-started/settings) for your entire account history. The previous **92-day** limit has been removed, and a new **All data** range has been added to the report period selector alongside the existing presets. #### Stop orders during closed market sessions [#stop-orders-during-closed-market-sessions] You can now place **Stop** orders while a market is closed according to its trading schedule. The order is accepted and activates automatically once the market reopens, instead of being rejected at placement. #### More accurate unrealized PnL [#more-accurate-unrealized-pnl] Unrealized PnL is now calculated using the correct order book side for each position direction, improving the accuracy of the PnL shown across your widgets. #### Limit price crossing warning [#limit-price-crossing-warning] When you place a limit order at a price that crosses the current top of book, the terminal now shows a warning, helping you avoid an unintended immediate execution. ## April 9, 2026 [#april-9-2026] ### New features [#new-features-1] #### Trading credit [#trading-credit] Your broker can now grant you **trading credit** — a promotional bonus balance you can use for trading. Credit appears as a separate **Credit Balance** alongside your own funds and becomes available for placing trades immediately upon issuance. You are notified when credit is granted or revoked. Trading credit is a trading-only bonus and cannot be withdrawn as cash, so it is excluded from your withdrawable balance. *** ### Improvements [#improvements-1] #### Fee-aware 100% allocation [#fee-aware-100-allocation] The **100%** button in the [Place order](../widgets/place-order) widget now accounts for commissions and margin requirements when allocating funds, so the calculated amount reflects what is actually available for the trade. #### Faster price updates [#faster-price-updates] The price update frequency in terminal widgets has been increased, providing more responsive market data across your workspace. ## March 18, 2026 [#march-18-2026] ### New features [#new-features-2] #### Webhook API for TradingView alerts [#webhook-api-for-tradingview-alerts] A new **Webhook API** has been added, enabling you to connect **TradingView** alerts to your trading workflow. You can generate and copy authentication tokens directly from the Trading terminal to configure webhook-based alerts in **TradingView**. *** ### Resolved issues [#resolved-issues] There have been no customer-facing issues reported in this release. ## March 3, 2026 [#march-3-2026] ### New features [#new-features-3] #### Long-term trading data history [#long-term-trading-data-history] The three-month limit on trading data history has been removed. You can now access the full history of your orders, positions, and trades without time restrictions, enabling deeper analysis of past trading activity. #### AI Assistant widget [#ai-assistant-widget] A new **AI Assistant** widget is now available in the Trading terminal. The widget provides AI-powered market analysis for the selected instrument, including: * A recommendation gauge displaying a score from **Strong Sell** to **Strong Buy** * A 12-month price forecast with target price and percentage change * A market sentiment bar showing the bullish/bearish ratio * Signal drivers section with technical, on-chain, and sentiment factors * Suggested trading actions and key market metrics The widget can be added to any workspace like other terminal widgets. *** ### Improvements [#improvements-2] #### Updated order cancellation confirmation [#updated-order-cancellation-confirmation] The order cancellation confirmation dialog now includes a **Don't ask again** checkbox when canceling triggers from the **TradingView** chart. This allows you to skip the confirmation step for future trigger cancellations, streamlining the trading workflow. *** ### Resolved issues [#resolved-issues-1] There have been no customer-facing issues reported in this release. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-4] #### Redesigned Market Depth widget [#redesigned-market-depth-widget] The [Market Depth](../widgets/market-depth) widget has been completely redesigned with an updated visual layout. Bid and ask labels are now displayed when hovering over a price level, providing better visibility into the order book at a glance. #### Redesigned widget adding experience [#redesigned-widget-adding-experience] The process of adding widgets to workspaces has been redesigned with a more intuitive and streamlined flow. The new interface makes it easier to customize your trading workspace layout by providing a clearer visual selection of available widgets. #### Order and position comments [#order-and-position-comments] A new **Comment** field has been added to orders, positions, and trades throughout the Trading terminal. You can now attach notes directly to your trading activities, making it easier to annotate trading decisions and keep records of your reasoning. #### Favorites [#favorites] You can now mark instruments as favorites for quick access across the Trading terminal. The [Favorite markets](../get-started/customizing-your-terminal#favorite-markets) feature integrates with the instrument selection panel, making it faster to locate and trade your preferred instruments. #### Multi-language support [#multi-language-support] The Trading terminal now supports additional languages: **Chinese (Simplified)**, **Spanish**, **Portuguese**, **French**, **Turkish**, and **Farsi**. Existing translations have also been updated to reflect the latest interface changes. *** ### Improvements [#improvements-3] #### Updated order calculations [#updated-order-calculations] The **Value** and **Amount** calculation logic has been improved for more accurate order handling: * For **Stop Market** orders, the estimated values are now calculated using updated formulas that align with the actual execution logic. * For **Spot** market orders, the **Slippage Rate** is now correctly applied only to buy orders and has been removed from sell order calculations. * The **Slippage Rate** attribute has been removed from **CFD** and **PF** market forms and information displays, as it is not applicable to these market types. #### Improved TP/SL trigger management [#improved-tpsl-trigger-management] Removing Take Profit and Stop Loss triggers is now easier in the TradingView charting widget. Instead of opening a dialog and unchecking the trigger, you can now click the close button directly on the trigger to remove it immediately. #### Updated default columns [#updated-default-columns] The default columns displayed in the [Open positions](../widgets/open-positions) and [Open orders](../widgets/open-orders) widgets have been updated to show the most relevant information by default, reducing the need for manual customization. #### Account margin value formatting [#account-margin-value-formatting] Account margin values such as **Balance**, **Equity**, **Margin**, and **Free margin** in the [Margin](../widgets/margin) widget are now formatted according to the **Root Asset Scale**. This ensures that numerical precision matches the asset's defined scale, eliminating misleading decimal places. #### Updated Settings experience [#updated-settings-experience] The [Settings](../get-started/settings) experience has been improved: * The **Action Confirmation** section text has been rewritten for clarity. The description now reads: "Choose which actions will require additional confirmation," making the toggle behavior immediately clear. * The **One-click trading** configuration has been updated with improved toggle controls and clearer options for enabling or disabling confirmation dialogs on trading actions. #### Improved order validation [#improved-order-validation] Order validation logic has been updated across the Trading terminal, providing clearer feedback on invalid inputs and reducing errors during order placement and management. #### Workspace tab styling [#workspace-tab-styling] Visual improvements have been applied to workspace tabs: gaps have been added between tabs for better visual separation, tab padding has been corrected, and hovered tabs now display a proper card-style fill matching the updated design system. ## December 19, 2025 [#december-19-2025] ### New features [#new-features-5] #### Volume-based tiered commissions [#volume-based-tiered-commissions] You can now benefit from **volume-based commission tiers** that automatically reduce your trading fees as your monthly volume grows. **Key points**: * **Trade more, pay less**: For markets with tiered fees, your 30‑day trading volume (in the root asset, for example USD) is tracked across all markets included in the same group. As you move into higher tiers, your commission percentage decreases. * **Clear fee overview**: Open [Market info](../get-started/customizing-your-terminal#market-info-panel) and switch to the **Fees** tab to see your **Current volume** for the month, the configured **Min. fee**, and the full **Commission tiers** table with volume ranges and fee %. A check mark highlights the tier you are currently in. * **Grouped volume**: Your traded volume is aggregated across markets to which the dynamic commission is applied. * **No surprises**: Orders on markets without tiered fees continue to use the existing flat commission model. Tiered markets simply adjust your fee according to the tier that matches your current trading volume. #### New settings [#new-settings] The [Settings](../get-started/settings) menu has been enriched with the following configuration options: * **Widgets**: This updated section now provides access to multiple widgets’ display settings. Along with existing [Price chart](../widgets/price-chart), you can now configure: * One-click trading for [Open positions](../widgets/open-positions): When enabled, single and bulk position closing are executed immediately, without going through additional confirmation dialogs. * One-click trading for [Open orders](../widgets/open-orders): When enabled, single and bulk order cancellations are executed immediately, without going through additional confirmation dialogs. * **API token management**: This new section allows you to generate and manage tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/). Up to 10 tokens can be generated per account. The validity period for each token is one year. The tokens can be revoked or deleted anytime. *** ### Improvements [#improvements-4] #### Responsive widget layout [#responsive-widget-layout] Widget content now adapts dynamically to the available space, ensuring that key information such as primary values, titles, and critical actions remains visible even when widgets are resized or minimized. Layouts have been refined to avoid unnecessary empty areas while preventing clipping of important elements, delivering a more readable and informative experience across all widget sizes. #### Clearer margin level display [#clearer-margin-level-display] The [Margin](../widgets/margin) widget has been updated to provide a clearer signal. Now, whenever no margin is used (for example, when you have no open positions), the **used margin** value displays **–** instead of 0%. This aligns with common brokerage practices and helps you better understand the current risk state at a glance. #### Smarter default filters for Assets and Account margin [#smarter-default-filters-for-assets-and-account-margin] Certain default filters are now applied automatically when the Trading terminal is opened for the first time. In the [Assets](../widgets/assets) widget, **Hide zero balances** is enabled by default, so assets with zero balance are not shown. In the [Account margin](../get-started/settings#account-margin) settings, **Hide zero balances** and **Hide assets with zero margin ratio** are enabled by default, hiding assets that carry no margin or balance. If you change any of these filters, the platform remembers their states. #### Improved quick trade panels [#improved-quick-trade-panels] The **Market quick trade panel** has been moved not to cover the important controls of the [Price chart](../widgets/price-chart). Additionally, it now displays the **cross icon** to quickly close the panel if needed. *** ### Resolved issues [#resolved-issues-2] There have been no customer-facing issues reported in this release. ## November 7, 2025 [#november-7-2025] ### New features [#new-features-6] #### Tiered leverage system [#tiered-leverage-system] With this release, we're excited to introduce the **tiered leverage system** that provides more sophisticated leverage options based on your position sizes, offering better risk management. **Key points:** * **Dynamic leverage tiers**: Markets can now offer tiered leverage where your maximum available leverage decreases as your position size increases. This allows you to access higher leverage on smaller positions while maintaining appropriate risk controls on larger trades. * **Enhanced market information**: Markets with tiered leverage now display comprehensive leverage information in the **Market info** panel. A new **Leverage** tab shows all available tiers, including the notional value ranges and maximum leverage for each tier. * **Improved position tracking**: Your open positions now display both the leverage you selected when opening the position (**Requested leverage**) and the actual leverage being applied (**Leverage**). Detailed tooltips explain how these values are calculated, giving you better visibility into your margin usage. * **Smart leverage selection**: When placing orders on markets with tiered leverage, the system automatically calculates your margin requirements across all applicable tiers. You can see the exact margin required before placing your order. **How it works** For markets with dynamic leverage, your position is allocated across different tiers based on its notional value. Each tier has its own maximum leverage limit, typically starting with higher leverage for smaller positions and decreasing as position size grows. This allows you to maintain appropriate risk management. **Order placement** When trading on tiered markets, you can still select your preferred leverage (up to the maximum allowed for the first tier), and the system will automatically apply the appropriate leverage limits. The margin calculator shows you the exact requirements before you place your order. All existing positions continue to operate normally with no changes to your current trading experience. Markets without tiered leverage continue to work exactly as before. *** ### Improvements [#improvements-5] #### Improved documentation experience [#improved-documentation-experience] The documentation window is now fully resizable, allowing traders to adjust both vertical and horizontal dimensions independently. All screenshots can now be zoomed, making detailed interface elements clearly visible. #### Streamlined market selection [#streamlined-market-selection] The market selection control is now displayed as the **chevron icon** directly next to the market name in widgets. The magnifying glass icon has been removed. Both the market name and chevron are now clickable and open the market selector. #### Reorganized market information access [#reorganized-market-information-access] The market info popover has been relocated under the **info icon** in the widget header to maintain accessibility while keeping the market name area focused solely on selection functionality, creating a cleaner and more consistent user interface. #### Enhanced workspace tab design [#enhanced-workspace-tab-design] A clear distinction between active and inactive workspace tabs has been achieved due to intuitive styling. Workspace option buttons are now hidden by default to reduce visual clutter and only appear when tabs are active or being hovered over. This applies to both default and custom workspace tabs, creating a cleaner interface while maintaining full functionality when needed. *** ### Resolved issues [#resolved-issues-3] There have been no customer-facing issues reported in this release. ## October 9, 2025 [#october-9-2025] ### New features [#new-features-7] #### Placing orders from the Price chart [#placing-orders-from-the-price-chart] The [Price chart](../widgets/price-chart) widget now supports direct order placement with two new quick trading panels. The **Market quick trade panel** provides a persistent interface for instant buy/sell orders, while the **Limit quick trade panel** allows hover-based order placement at specific price levels. When enabled through **Price chart settings**, both panels offer configurable amount presets and leverage ratio selection for margin trading (when applicable), creating a seamless trading experience without leaving the chart view. #### Bulk order canceling [#bulk-order-canceling] The [Open orders](../widgets/open-orders) widget introduces a **Cancel all** button that closes all active orders simultaneously. This feature provides better risk management capabilities during volatile market conditions. #### In-platform documentation [#in-platform-documentation] User documentation is now integrated directly within the Trading terminal interface. This eliminates the need to switch between applications when accessing help materials or reference guides, keeping essential information readily available during trading sessions. #### New market subtype [#new-market-subtype] The new **Commodities** subtype has been added for CFD markets, enhancing the market categorization system. *** ### Improvements [#improvements-6] #### Enhanced position tracking [#enhanced-position-tracking] A new **Direction** column has been added to **Trades** info in the [Open positions](../widgets/open-positions) and [Closed positions](../widgets/closed-positions) widgets. It indicates whether a position size increased (In) or decreased (Out) as a result of each trade. This enhancement provides clearer visibility into position movement patterns. #### Cross rates calculation precision [#cross-rates-calculation-precision] Accuracy for cross-rate calculations has been improved by introducing a new cross-rate scale parameter. It has a default value of 8 and can be adjusted in configuration files. This addresses the previous limitation where cross rates were rounded to the root asset type scale (typically 2 decimal places), causing incorrect zero values in certain scenarios. The improvement ensures accurate cross-rate calculations across all currency and cryptocurrency pairs, regardless of their relative values. #### Redesigned Settings interface [#redesigned-settings-interface] The **Settings** menu has been restructured with a new tabbed popup interface. Related configuration options are now logically grouped, making settings easier to navigate and manage. #### Pre-filled Limit order price [#pre-filled-limit-order-price] Limit order placement now includes automatic price pre-population using the best bid or ask price from the order book. This static pre-fill reduces manual entry requirements and helps prevent pricing errors during order submission. #### Updated sorting of open positions [#updated-sorting-of-open-positions] [Open positions](../widgets/open-positions) are now sorted chronologically with the newest positions displayed at the top, improving visibility of recent trading activity. #### Improved messages [#improved-messages] User communications have been updated throughout the platform, including improved Introduction tour messaging for better onboarding and clearer system notifications. #### UI enhancements [#ui-enhancements] UI improvements for this release include: * **Support for dynamic resizing of the trading interface layout**: The trading interface now features a responsive layout system that dynamically adjusts to browser window resizing. Widgets automatically scale and reposition to maintain optimal viewing regardless of screen size changes. * **Loader**: [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now display loading indicators when fetching additional data. * **Improved PnL representation**: When displayed on charts, the PnL values are now accompanied by "+" or "–" signs for immediate profit/loss recognition. * **Improved scrollbars**: Scrollbar positioning has been refined to prevent overlay of table content, ensuring all data remains visible and accessible. *** ### Resolved issues [#resolved-issues-4] There have been no customer-facing issues reported in this release. ## July 2, 2025 [#july-2-2025] ### New features [#new-features-8] #### Trading reports [#trading-reports] We've implemented a new feature enabling you to generate trading reports for a specific period of time and download them as zipped CSV files to your computer. The report includes a detailed information on: * **Trade history** * Closed positions * Executed orders * Trades * **Transfers history** * **Account statistics** * Total balance * Realized PnL * Swaps * Funding * Commissions The data is available for any period within the last **92 days** (UTC time). The following timeframe presets have been implemented for your convenience: * Today * Current: week, month, quarter * Previous: week, month, quarter Access the new **Trading report** menu under the **Settings** icon on the topbar of the Trading terminal. *** ### Improvements [#improvements-7] #### Admin-managed orders and positions [#admin-managed-orders-and-positions] In the [Open positions](../widgets/open-positions), [Closed positions](../widgets/closed-positions), and [Order history](../widgets/order-history) widgets, if BP Admins have managed positions or orders, this is now indicated in the Reason field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, and mitigate risks. *** ### Resolved issues [#resolved-issues-5] There have been no customer-facing issues reported in this release. ## May 30, 2025 [#may-30-2025] ### New features [#new-features-9] #### PF trading [#pf-trading] We are excited to introduce **Perpetual Futures (PF) trading** on our platform. These contracts feature a funding fee mechanism based on the Mark price and Funding rate. A positive rate means Long positions pay Shorts, and a negative rate means the reverse. You can see the countdown to the next funding fee settlement in the [Market summary](../widgets/market-summary) widget. This update also includes a new market type — Perpetual — enhancing your trading opportunities. *** ### Improvements [#improvements-8] #### Price chart setting [#price-chart-setting] The [Price chart](../widgets/price-chart) widget now supports displaying of open positions, as well as open and executed orders. Click the **gear icon** in the topbar to access Price chart settings and enable desired options. #### Close all positions [#close-all-positions] The [Open positions](../widgets/open-positions) widget now features a new **Close all** option, offering enhanced management capabilities. This update provides a more efficient way to handle multiple positions by allowing you to simultaneously close: * All open positions * All open positions with positive PnL * All open positions with negative PnL #### Enhanced price control [#enhanced-price-control] The following enhancements have been implemented for the [Price control](../widgets/price-control) widget: * **Editable price alerts**: You can now adjust existing price alerts by clicking a price. * **Enhanced market additions**: Price and percentage fields now automatically open for editing when a new market is added to the widget. * **Visual indicators**: Arrows near price triggers aren’t shown if the price feed is unavailable, reducing clutter and potential confusion. #### Historical data limits [#historical-data-limits] The [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now provide historical data with a limit of **92 days**. *** ### Resolved issues [#resolved-issues-6] There have been no customer-facing issues reported in this release. ## April 17, 2025 [#april-17-2025] ### New features [#new-features-10] #### Netting account type [#netting-account-type] With this release, a new **Netting** account type has been enabled. It intelligently consolidates all orders placed on the same market into a single position. Previously, the system supported only Hedging, where each order opens a separate position. **Key points of netting** * **Reduced margin requirements**: Instead of calculating margin requirements separately for each position, netting combines them, lowering overall capital needs. * **Lower trading costs**: By holding opposing positions, traders often incur double position swaps. Netting treats these positions as one, reducing unnecessary costs. * **Streamlined position management**: Managing multiple positions manually can become complicated, especially when balancing between different trade sizes, directions, leverages and margin requirements. Netting helps with it by combining positions into a single one. **Netting VS Hedging** Netting may sometimes lack the flexibility required for complex hedging strategies. In contrast, hedging excels by allowing traders to hold both long and short positions simultaneously without offsetting them. This enhances the ability to track and adjust individual trades easily while permitting precise margin management for separate positions. The Hedging type is perfectly suited for traders seeking detailed control over their positions. On the other hand, the Netting type ensures simplicity and reduced margin requirements, making it the perfect choice for straightforward trading strategies. **Workflow changes** When opening a new trading account, you must now choose its type: either Hedging or Netting. This choice is permanent and influences all future trades in the account. In the account selection interface, each account displays its type: `H` for Hedging or `N` for Netting. All existing accounts are automatically assigned to the Hedging type. *** ### Improvements [#improvements-9] #### Improved widget control [#improved-widget-control] With this release, you now have enhanced control over the viewing experience: * **Configuring widget columns**: Certain widgets allow you to configure widget columns in a way that best suits your needs, offering you the flexibility to select which columns you wish to display or hide. Additionally, you can arrange the order of these columns for your convenience, ensuring that the information you prioritize is always at your fingertips. * **Rearranging widget tabs**: All widgets now feature drag-and-drop functionality for rearranging tabs effortlessly. This user-friendly feature offers a more customized and organized interface, making it easier than ever to personalize your widget experience. #### Enhanced Order book [#enhanced-order-book] The Order book widget has been upgraded with new customizable settings. This update introduces intuitive controls, empowering you to adjust the widget view according to your preference: * **Full view**: Shows both buy and sell orders along with the market spread. * **Buy only view**: Displays only buy orders and the market spread. * **Sell only view**: Displays only sell orders and the market spread. *** ### Resolved issues [#resolved-issues-7] There have been no customer-facing issues reported in this release. ## January 15, 2025 [#january-15-2025] ### New features [#new-features-11] #### Take profit, Stop loss, Trailing stop [#take-profit-stop-loss-trailing-stop] With this release, the following new triggers for open positions have been implemented on the platform: * **Take profit**: A take-profit trigger is used to close a position automatically once the market hits a predefined price, ensuring the trader locks in profits. * **Stop loss**: A stop-loss order is a trigger to limit potential losses. It automatically closes a position when its price changes to a predetermined level. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified value. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. These settings can be used when trading on CFD markets and can be applied to Market, Limit, and Stop orders, as well as for currently open positions. The new settings can be enabled when placing an order via the [Place order](../widgets/place-order) widget (Advanced mode). Until a position is fully closed, they can also be adjusted or canceled via the [Open positions](../widgets/open-positions) widget. The information about applied settings is also available in the corresponding widgets: [Closed positions](../widgets/closed-positions), [Open orders](../widgets/open-orders), and [Order history](../widgets/order-history). *** ### Resolved issues [#resolved-issues-8] There have been no customer-facing issues reported in this release. *** ## Past releases [#past-releases] ### December, 2024 [#december-2024] #### New features [#new-features-12] ##### CFD trading [#cfd-trading] With this release, we're excited to announce the support for CFD (Contract for Difference) trading on our brokerage platform. This empowers you to trade with dynamic leverage, using your funds as collateral to secure positions confidently. Enjoy the flexibility to go both long and short, capitalizing on both bullish and bearish markets. Our CFD trading support boasts an intuitive interface, robust risk management tools, and real-time data. ##### Innovative market approach and instrument picker [#innovative-market-approach-and-instrument-picker] * **Market type**: Markets are now classified into Spot and CFD, reflecting their differing parameters. A panel indicating CFD or Spot is now included in all widgets. * **Market parameters and trading schedule**: Click a market name to access its key parameters and scheduled trading sessions. * **Market categories**: Now accessible via the top bar, offering a hierarchical view for easier selection and switching between markets. ##### Account margin settings [#account-margin-settings] Access the new [Account margin settings](../get-started/settings) to monitor your balances and configure assets to be used as collateral for CFD trading. ##### Reworked Place order widget [#reworked-place-order-widget] Place any order with a [single widget](../widgets/place-order) now. Choose Quick IOC Market or Stop with adjusted leverage — all conveniently in one place, along with an order summary. ##### Positions [#positions] Discover two new widgets for position monitoring: * [Open positions](../widgets/open-positions): Offers real-time monitoring of currently open positions with price changes, PnL, used margin, and other parameters. * [Closed positions](../widgets/closed-positions): Provides historical data on position details, prices, and realized PnL. ##### Risk management [#risk-management] You now have three essential widgets to maintain control: * [Margin](../widgets/margin): Monitor your margin account parameters in real time and respond swiftly to changes. * [Price control](../widgets/price-control): Set price alerts tailored to your specific needs and parameters. * [Messages](../widgets/messages): Receive system notifications and price alerts directly. ##### Market data [#market-data] Two new widgets have been introduced to enhance market monitoring: * [Market summary](../widgets/market-summary): Provides detailed information and updates on price changes for a specific market. * [All markets](../widgets/all-markets): Displays price change statistics across all markets simultaneously. #### Improvements [#improvements-10] * Performance has increased significantly, allowing each trader to hold up to 1,000 CFD positions open. * Limits have been increased to 3,000 requests per second. #### Resolved issues [#resolved-issues-9] There have been no customer-facing issues reported in this release. *** ### June 20, 2024 [#june-20-2024] #### Improvements [#improvements-11] * Account selection is now available from the topbar of the Trading terminal. Once you change your account, all the widgets will automatically adjust to show relevant information for the selected account. * Tabs are now available in the Trading terminal. You can place up to 10 tabs to open multiple workspaces simultaneously for better information organization. You can utilize pre-configured layouts for your workspaces or create custom ones. *** ### June 13, 2024 [#june-13-2024] #### New features [#new-features-13] ##### iOS mobile application [#ios-mobile-application] With this release, our team is thrilled to announce the launch of the brand-new iOS mobile app. The mobile app is closely integrated with B2CORE mobile. Along with single sign-on implemented, it allows you to seamlessly navigate between the apps, without re-entering credentials. In the mobile app, just like in the web version of the Trading terminal, you can access all of your BP accounts, place orders, monitor market data, and so on. For your convenience, it all can be done in a very similar way as in the web version. A consistent and user-friendly interface makes using the app easy and intuitive. Among the key features and services that the new BP mobile offers: * The account list with detailed balances, to always keep your funds under control. Creation and renaming of accounts, to keep your funds well organized. * Asset balances screen, with the amounts of free and frozen funds specified and with the possibility to hide assets with zero balances. * The Order book and price chart, to monitor and analyze trading data and make buy or sell decisions, with a quick and easy jump to the order placing screen. * Candles and line charts, with easy switching and the possibility to scroll the data for historical values. * Limit & Market order placing, with all time in force options supported in the Web version (Market: IOC, FOK; Limit: IOC, FOK, GTC, GTD, Day). * Open and history orders lists, with easy access to order parameters and details, quick canceling or repeating an order. * Light and dark themes and many more. ### October 18, 2023 [#october-18-2023] #### New features [#new-features-14] With this initial release, our team is happy to announce the launch of our new Trading terminal. ##### Placing orders [#placing-orders] The platform currently supports placing Market, Limit, Stop Market, and Stop Limit orders (refer to [Order types](../knowledge-base/order-types)). You can also choose from various [Time in force](../knowledge-base/time-in-force) options such as FOK, IOC, GTC, GTD, and DAY. ##### Widgets [#widgets] The platform provides you with enhanced widgets that are specifically designed for convenient trading. These widgets allow you to easily place orders, access the Order book, monitor open orders and order history, and much more. Refer to [Place order](../widgets/place-order) and the other pages of the Widgets section for more information. ##### Dashboard [#dashboard] The customizable dashboard allows you to personalize the layout to suit your needs and keep you focused on what's important. Refer to [Interface overview](../get-started/customizing-your-terminal) to learn more about workspace customization. ## Summary [#summary] This widget provides AI-powered market analysis and trading recommendations for the selected market. AI Assistant The widget is organized into the following sections: * [AI Recommendation](#ai-recommendation): Overall recommendation score. * [Forecast](#forecast): Price target and market sentiment. * [Signal Drivers](#signal-drivers): Technical, on-chain, and sentiment signals. * [Suggested Actions](#suggested-actions): AI-generated trading suggestions. * [Key Metrics](#key-metrics): Market data overview. ## AI Recommendation [#ai-recommendation] Displays a numeric score from 0 to 100 representing the overall AI assessment of the market, along with a label such as **Strong Buy**, **Buy**, **Neutral**, **Sell**, or **Strong Sell**. A higher score indicates a more favorable outlook. ## Forecast [#forecast] **1Y Price Target** The forecasted price in one year and the expected percentage change from the current price. *** **Market Sentiment** A visual bar showing the ratio between bullish and bearish sentiment among market participants. ## Signal Drivers [#signal-drivers] Signals that influence the AI recommendation, categorized into three types: * **Technical**: Signals based on technical analysis indicators such as RSI and Moving Averages. * **On-Chain**: Signals based on blockchain data such as ETF inflows, active addresses, and total value locked (TVL). * **Sentiment**: Signals based on community and analyst opinions. Each signal includes a description and an impact assessment: **Bullish**, **Bearish**, or **Neutral**. ## Suggested Actions [#suggested-actions] A list of AI-generated trading suggestions based on the current market conditions. These are informational recommendations, not automated trading signals. ## Key Metrics [#key-metrics] The following market data is displayed: **All-Time High** The highest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **All-Time Low** The lowest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **24h Volume** The total trading volume over the last 24 hours in USD. *** **Market Cap** The total market capitalization of the asset in USD. AI-generated insights are for informational purposes only. The AI Assistant widget can be enabled or disabled by the platform administrator. If the widget isn't available in the **Add Widget** menu, contact your broker. ## Summary [#summary] Use this widget to monitor price data on all markets available on the platform. The widget is dynamic and is continuously updated in real time. All markets ## Fields [#fields] The following information is provided about each market: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current market price, in the quote asset and in the platform root asset. This value is green if the price is rising and red if it's falling. *** **24h change** The price change over the last 24 hours, in absolute and percentage values. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. ## Summary [#summary] This widget displays the list of all asset balances on your account. Assets ## Settings [#settings] ### Hide zero balances [#hide-zero-balances] Use this option to hide all assets with zero balances from the list. It's enabled by default. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance at your disposal, meaning the difference between your total assets and a sum of all limit orders placed by this time. This value is calculated as *Total – Halted*, where *Halted* is the asset amount frozen on the account for execution of placed Limit orders. *** **Available, \{RAT}** The available balance, in conversion to the platform root asset. *** **Total** The overall amount of the asset available in your wallet, including locked funds. *** **Total, \{RAT}** The total balance, in conversion to the platform root asset. ## Summary [#summary] This widget displays a list of your closed positions on the selected account. The entire history of your closed positions is available. Closed positions The widget lists only closed positions. For a list of currently open positions, use the [Open positions](open-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists closed positions for the last three months. To display positions closed during a specific time period, use the **Select date range** field. The most recently closed positions appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related orders [#view-related-orders] Click the **chevron icon** in a position row to expand a list of position-closing orders. As positions can be partially closed, there may be more than one line. For each executed position-closing order, a separate line is added. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Pos. closed size** The closed volume, in lots, which is equivalent to the corresponding filled order volume. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Close price** The volume-weighted average price (VWAP) of trades related to a position-closing order. *** **Close order ID** The identifier of an order closing the position. *** **Realized PnL, \{RAT}** The actual profit or loss earned, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). *** **\{RAT} notional** The equivalent of the closed volume in the platform root asset. *** **History rate to \{RAT}** The rate to the platform root asset at the moment of position closing. *** **Reason** The reason for closing a position. Possible values: * **Trader**: The position was closed by you. * **Admin**: The position was closed by an Admin. * **Stop-out**: The position was automatically closed by the system, as a result of Stop out. * **Stop loss**: The position was closed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The position was closed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The position was closed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. *** **Open date, time** The date and time when a position was opened. *** **Closed date, time** The date and time when a position-closing order was last updated (fully executed). ## Summary [#summary] This widget helps you monitor margin parameters and statistics. Margin ## Fields [#fields] All values are in displayed in conversion to the platform root asset: **Your margin level** The ratio of your funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. Possible values: * **Empty**: No open positions. * **Low risk**: Everything is ok. * **Margin call**: Your margin level fell below the set Margin call value. You received a notification urging you to increase the margin level to avoid a Stop out. Remember that if you ignore this warning, the margin level may continue to decrease. During the Margin call, you can only close existing positions; opening new positions isn’t possible. * **Stop out level**: Your margin level fell below the set Stop out value; the platform started a process of liquidating your positions. This process continues until the margin level exceeds this required value. **ANY** currently open position can be closed regardless of its side and volume. *** **Margin balance** The total amount of your funds that can be used as a collateral for CFD trading. It’s calculated as Σ(*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*), where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the platform root asset. The Margin balance is continually recalculated based on price fluctuations. An increase in the prices of assets boosts available Balance & Free margin. Conversely, a decrease in asset prices may reduce the available Balance and Free margin. Additionally, a decline in the prices of assets with open positions may trigger Margin calls and Stop outs. *** **Credit** A promotional bonus granted by your broker for margin (CFD and Perpetual) trading, shown in the platform root asset (RAT). When you have no credit, this row shows 0. Credit increases your Equity and Free margin and can be used as collateral to open positions. It becomes available immediately when granted and never expires. However, credit cannot be withdrawn as cash, so it is excluded from your withdrawable balance. Your broker can revoke credit at any time, and the row updates in real time when this happens. The row includes an info tooltip that reads: *Promotional credit for margin trading only. Cannot be withdrawn.* *** **Equity** The potential balance of your account if all your positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. *** **Used margin** The amount of funds that is used for maintaining all your open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **Example** **Step 1: Initial balance** * Margin balance: $10,000 * Opened positions: 0 * Free margin: $10,000 * Used margin: $0 **Step 2: Open a long position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 100 = $1,001 * After opening: * Free margin: $8,999 * Used margin: $1,001 **Step 3: Open a long position (Leverage 1:20)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 20 = $5,005 * After opening: * Free margin: $3,994 * Used margin: $6,006 **Step 4: Open a short position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 9 lots (900,000 units) * Current price: $1 * Required margin: $(900,000 × 1.001) / 100 = $9,009. The system verifies that upon opening this position, the MarketUsedMargin remains valid by satisfying the condition: **MarketUsedMargin** = MAX(*MarketPositionLong*, *MarketPositionShort*) = MAX(6,006, 9,009) = 9,009. Since the condition is met, the position opens. * After opening: * Free margin: $991 * Used margin: $9,009 As a result, you can open multiple opposite positions without significantly increasing the Used margin. Furthermore, closing positions never increases the Used margin. *** **Free margin** The amount of funds that can be used for opening new positions. *** **Unrealized PnL** The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) ## Summary [#summary] Use this widget to assess the current market depth indicating the actual liquidity of an asset, which is evaluated based on the number of currently open orders to buy and sell it as well asset prices and volumes at various price levels. Market depth The widget is dynamic and is continuously updated in real time. The widget displays a chart indicating the overall volume of buy (green) and sell (red) orders at various price levels awaiting execution at the moment. You can hover the mouse pointer over the chart to learn the exact price and volume of an asset traded at a specific price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ## Summary [#summary] Use this widget to monitor statistics on a specific instrument. The widget is dynamic and is continuously updated in real time. Market summary To monitor multiple instruments at a time, use the [Watch list](watch-list) widget. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the first column. To change the market, click the market symbol and select a different one from the list. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current top-of-the-book price, in the quote asset. *** **Current price, \{RAT}** The current top-of-the-book price, in conversion to the platform root asset. *** **24h change** The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h high** The highest trade price over the last 24 hours. This value is always green. *** **24h low** The lowest trade price over the last 24 hours. This value is always red. *** **Info icon** Click this icon to view market details and trading sessions schedule. ## Summary [#summary] This widget displays a list of received notifications, both system and configured via the [Price control](price-control) widget. Messages ## Settings [#settings] ### Mark as read [#mark-as-read] Unread alerts are marked with a red dot in the list: * Click the dot to mark the notification as read. * Click **Mark all as read** to mark all new notifications as read at once. * Click the **three dots** icon in the upper right corner of the widget to access the **Hide read notifications option**. The counter of unread alerts is also displayed on the **bell icon** in the topbar. ## Summary [#summary] This widget displays a list of Limit orders that have been placed from this specific account and are currently open and assigned one of the following [statuses](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. Open orders The widget lists only open orders, that are currently not filled or partially filled. For a list of orders in the final statuses, use the [Order history](order-history) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders for all the time. To display orders for a specific time period, use the **Select date range** field. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled so far. *** **Fee** The total commission paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that hasn’t yet been filled. *** **Limit price** For Limit orders, the Limit price set when placing the order. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set. *** **Used leverage** For margin trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Valid until** The date and time when an order expires. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Admin**: The order was placed by an Admin. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Cancel orders [#cancel-orders] To cancel an order, click the **×** in the corresponding row. To cancel all active orders at once, click the **Cancel all** button in the widget header. ## Summary [#summary] This widget displays a list of your positions currently open on the selected account. Open positions The widget lists only open positions. For a list of closed positions, use the [Closed positions](closed-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists open positions for all the time. To display positions opened during a specific time period, use the **Select date range** field. The most recent position appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related trades [#view-related-trades] Click the **chevron icon** in a position row to expand a list of related trades. ### Close positions [#close-positions] To close a position, hover over it and click the **CLOSE** button that appears. To close all/multiple positions at once, click **Close all** and select the desired option: close all positions or close positions with positive/negative PnL. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Position size** The current position volume, in lots. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Current price** The current market price of the base asset: bid for Long positions and ask for Short positions. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Unrealized PnL, DAY, \{RAT}** The potential profit or loss earned for a current day, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. *** **Unrealized PnL, DAY, %** The potential profit or loss earned for a current day, in percents. *** **Unrealized PnL, Total, \{RAT}** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). *** **Unrealized PnL, Total, %** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset, in percents. *** **Used margin, \{RAT}** The amount of your funds used for maintaining a position, in conversion to the platform root asset. *** **Leverage** The actual leverage ratio used for opening a position. *** **Req. leverage** The leverage ratio you requested when opening a position. *** **\{RAT} notional** The current position size equivalent in the platform root asset. *** **Rate to \{RAT}** The current exchange rate of a quote asset to the platform root asset. *** **Open date, time** The date and time when a position was opened. *** **Updated date, time** The date and time of the latest position-related trade. *** **Reason** The reason for opening a position: * **Trader**: The position was opened by you. * **Admin**: The position was opened by an Admin. * **Webhook alert**: The position was opened via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. ## Summary [#summary] This widget displays a list of currently open buy and sell limit orders for a selected asset along with the current bid-ask spread. Order book The widget is dynamic and is continuously updated in real time. It provides three different sections displaying the following information: * Open sell orders are highlighted in red and listed in the top section. The best ask, which is the sell order with the lowest price, is displayed at the bottom of this list. * Open buy orders are highlighted in green and listed in the bottom section. The best bid, which is the buy order with the highest price, is displayed at the top of this list. * The middle section displays the current bid-ask spread indicating the gap between the best ask and bid prices declared for an asset. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Display only asks/bids [#display-only-asksbids] In the upper part of the widget, you can choose how to display the Order book: * Full view. * Buy orders only + spread. * Sell orders only + spread. ## Fields [#fields] Each row of the Order book provides the following information about a selected market: **Price, \{QUOTE}** The price, in the quote asset. *** **Amount, \{BASE}** The total amount of the base asset available at a corresponding price level. *** **Total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. In addition, you can use the [Market depth](market-depth) widget to evaluate the liquidity of a specific asset based on the overall volume of orders traded at various price levels. For Spot markets, hover over Order book rows to view additional information and buy or sell assets in click: **Average price** The average price, in the quote asset. *** **Total volume** The total amount of the base asset available at a corresponding price level. *** **Grand total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. *** **Buy** / **Sell** Click the button to instantly place a Market order to buy or sell the asset at the selected price level. ## Summary [#summary] This widget provides up-to-date information about the orders executed on a selected market partially or in full, as well as the orders that were canceled, rejected, and expired. The entire order history of your account is available. Order history The widget lists only the orders to which final statuses are assigned. For a list of orders that are still being executed, use the [Open orders](open-orders) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders with the *Completed* status for the last three months. To display orders for a specific time period, use the **Select date range** field. To display orders with specific statuses, select one or more from the dropdown above the list. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled. *** **Fee** The total commissions paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that wasn't filled. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Completed*, *Cancelled*, *Rejected*, or *Expired*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Stop loss**: The order was placed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The order was placed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Summary [#summary] Use this widget to place new orders. Place order The widget has two states: ### The PRO toggle is disabled [#the-pro-toggle-is-disabled] In this state, you can quickly place **IOC Market** and **GTC Limit** orders by selecting the order side (Buy/Sell) and type (Market/Limit), and specifying the order size (in lots) and price (for Limit orders). You can also place orders on CFD markets with the maximum leverage automatically applied. ### The PRO toggle is enabled [#the-pro-toggle-is-enabled] In this state, you get access to more precise order settings, such as: * **Stop orders** * **Time in force** * **Leverage** * **Take profit, Stop loss, Trailing stop** * **Comment** * **Complete order information** The **Comment** field allows you to attach a text note to the order (up to 100 characters). The comment is inherited by the resulting position and can't be edited after the order is placed. ## Settings [#settings] ### Select a market [#select-a-market] The market on which the order will be placed is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Place an order [#place-an-order] To place an order, fill in the parameters, review order details and preliminary calculated values, and then confirm the order by clicking the **Place** button. For a Limit order whose price crosses the current top-of-book — Buy at or above the best ask, or Sell at or below the best bid — the platform shows a confirmation dialog before submission. The dialog shows the entered price and the current best bid/ask, and lets you confirm or cancel the order. This warning is enabled by default; you can disable it from the dialog (**Do not show this warning again**) or from the **Limit order cross-TOB warning** toggle in [Settings](../get-started/settings#action-confirmation). ### Set price triggers [#set-price-triggers] If using **Take profit, Stop loss, Trailing stop**, set the prices in consideration of the current highest market bid/ask or a specified Limit price: These values can be adjusted any time until the position is fully closed via the [Open positions](open-positions) widget. You can't place orders during non-trading hours, according to the trading calendar schedule. The order controls are disabled when the selected account is Halted or Frozen. For more information, see [Account status](../get-started/customizing-your-terminal#account-status). You will not be able to place an order if the execution of the order causes your margin level to fall below the *Margin call* level. The same conditions apply to withdrawal operations. ## Summary [#summary] This widget displays a price chart showing fluctuation of prices for a selected market over a certain time period. Price chart The horizontal axis (X-axis) represents the time scale, and the vertical axis (Y-axis) indicates the price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Customization [#customization] Multiple customization options are provided, allowing you to configure the chart according to your preferences. You can switch between bar, candle, Heikin Ashi, line, area and baseline views, as well as specify the time period for which data should be displayed. The chart supports numerous financial indicators, such as moving averages and regressions, and can feature a variety of custom shapes, including arrows and lines, pitchforks, and various ranges, allowing you to perform an in-depth market analysis. ### Display options [#display-options] The widget supports displaying of open positions, price triggers, open and executed orders. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart) to enable desired options. ## Placing orders [#placing-orders] ### Enable placing orders [#enable-placing-orders] To enable placing orders directly from the Price chart, you need to activate the corresponding settings: 1. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart). 2. Activate the **Market quick trade panel** or **Limit quick trade panel** toggle, or both. 3. If needed, adjust the amount presets. These amounts will be available for quick selection when placing an order. ### Market quick trade panel [#market-quick-trade-panel] If the corresponding setting is activated, the draggable **Market quick trade panel** is constantly displayed on the Price chart. ### Limit quick trade panel [#limit-quick-trade-panel] If the corresponding setting is activated, the **+** will appear when hovering over price levels on the chart. Clicking it will open the **Limit quick trade panel**: * in the upper half of the chart — to sell; * in the lower half of the chart — to buy. ### Place a new order [#place-a-new-order] To place a new Market or Limit order from the Price chart, when a corresponding panel is displayed: 1. Select the **amount** from configured presets. 2. Select a **leverage** ratio, if trading on CFD or PF markets. 3. Click **Buy** or **Sell**. The order will be placed according to the selected type. ## Summary [#summary] Use this widget to configure alerts that will be delivered to the [Messages](messages) widget when an instrument price reaches the specified level. Price control ## Settings [#settings] ### Configure a new alert [#configure-a-new-alert] To configure a new alert: 1. Click the **Add market** button to select a required market from the list. 2. Click the **+** icon below the instrument name to add a new alert trigger. 3. In the displayed fields, specify the exact price or the price change in percents (positive or negative). The other value will be calculated automatically. 4. Click the **check mark icon** to add the trigger. Now you will receive a notification in the [Messages](messages) widget, once the instrument price hits the specified level. You can configure multiple triggers for each instrument. ### Edit alerts [#edit-alerts] Click the price to edit the existing alert. ### Remove alerts [#remove-alerts] Click the **×** button on the trigger panel to remove it and stop receiving corresponding notifications. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ## Summary [#summary] This widget displays a list of untriggered Stop orders created on the selected account. Once a market price reaches your predetermined Stop price, the Stop order is activated and submitted as either a Market or Limit order. It's then removed from this widget. You can now find it in either the [Open orders](open-orders) or [Order history](order-history) widget, depending on its current status. Stop orders ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the Stop Market and Stop Limit orders for all the time. The most recent order appears at the top of the list. To display orders for a specific time period, use the **Select date range** field. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types): Stop Market or Stop Limit. *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Stop price** The stop price specified when creating an order. When the market reaches this price, the Stop order will be placed (as a Market or Limit order. *** **Limit price** The price of a Limit order that will be placed when the Stop price is triggered. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Order ID** The system identifier of an order. ## Summary [#summary] Use this widget to monitor statistics on multiple instruments at a time. The widget is dynamic and is continuously updated in real time. Watch list ## Settings [#settings] ### Add/remove instruments [#addremove-instruments] Click the **Add market** button to select a required market from the list. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Last price** The price of the last trade. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h low** The lowest trade price over the last 24 hours. *** **24h high** The highest trade price over the last 24 hours. Understand the basics and learn everything you need to start using the B2TRADER API Understand the basics and learn everything you need to start using the B2TRADER API Consult an in-depth reference describing REST API requests and responses Consult an in-depth reference describing REST API requests and responses Explore the supported WebSocket API methods and streams Explore the supported WebSocket API methods and streams Connect to the FIX 4.4 API for market data streaming and order execution Connect to the FIX 4.4 API for market data streaming and order execution ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Trading API: Stop orders for closed markets [#trading-api-stop-orders-for-closed-markets] The **Trading API** now accepts **Stop** orders for markets that are closed according to their trading calendar. The order is stored and activates automatically when the market reopens, instead of being rejected at submission. #### Reports API: full account history [#reports-api-full-account-history] Trading reports can now be generated for the entire account history. The previous **92-day** limit has been removed, and an **All data** range is now available for report generation. #### Trading API: market asset identifiers [#trading-api-market-asset-identifiers] The `baseAssetId` and `quoteAssetId` fields have been added to the v6 `/markets` responses, allowing clients to resolve the base and quote assets of each market without additional lookups. #### Accurate unrealized PnL [#accurate-unrealized-pnl] Unrealized PnL returned by the API is now calculated using the correct order book side for each position direction, improving the accuracy of PnL values in position and margin responses. *** ### Resolved issues [#resolved-issues] * Resolved an issue where `WebhookAlert` order reason and position modifier values were returned as numeric codes instead of API enum strings in History API `/v2/orders` responses. ## April 9, 2026 [#april-9-2026] ### New features [#new-features] #### Trading credit in API responses [#trading-credit-in-api-responses] Broker-issued **trading credit** is now exposed through the API. The account margin data response and the real-time margin stream include the current credit amount in the Reference Asset (`creditInRAT`). Credit is included in the account equity and excluded from the withdrawable amount. *** ### Improvements [#improvements-1] #### Webhook Trading API: webhook URL in key listing [#webhook-trading-api-webhook-url-in-key-listing] The list webhook API keys response now includes the `webhookUrl` field, so the configured webhook endpoint can be retrieved for each key. ## March 16, 2026 [#march-16-2026] ### New features [#new-features-1] #### Webhook Trading API [#webhook-trading-api] A new **Webhook Trading API** has been added, enabling automated order creation via webhook alerts with API key authentication. **Key points:** * Create and manage webhook API keys for secure authentication * Receive trading alerts and create orders automatically * Idempotency supported via deduplication ID * Market type routing by symbol prefix (spot, CFD, perpetual) #### Public Account ID [#public-account-id] A new `publicAccountId` field has been added across all API endpoints, providing a human-readable account identifier as an alternative to internal UUIDs. **Affected APIs:** * Trading API — account-related responses and filters * Settings API — account configuration endpoints * History API — all REST endpoints and WebSocket streams * Reports API — report responses and filters #### Long-term trading data history [#long-term-trading-data-history] Date range restrictions have been removed from **Order History** and **Closed Positions** endpoints, allowing access to full trading history without time-based limitations. *** ### Improvements [#improvements-2] #### Transfer subtype field [#transfer-subtype-field] A new `subtype` field has been added to transfer responses in the History API to distinguish **Negative Balance Protection** transfers from manual ones. #### Rounded position prices [#rounded-position-prices] The `positionPriceInRAT` values are now properly rounded in closed position API responses according to the Reference Asset (RAT) scale. *** ### Resolved issues [#resolved-issues-1] * Resolved an issue where `/total-swaps` requests returned HTTP 504 timeout errors. ## March 11, 2026 [#march-11-2026] ### Added FIX API documentation [#added-fix-api-documentation] Added new FIX API section covering Market Data and Trading sessions via the FIX 4.4 protocol. ## March 11, 2026 [#march-11-2026-1] ### Initial version [#initial-version] ## March 2, 2026 [#march-2-2026] ### New features [#new-features-2] #### Trading Terminal AI assistant [#trading-terminal-ai-assistant] A new **AI assistant** has been added to the Trading Terminal, providing traders with an intelligent widget for market analysis and trading support. *** ### Improvements [#improvements-3] #### Public Account ID (preview) [#public-account-id-preview] The `publicAccountId` field has been added to account-related API responses as a preview, ahead of the full rollout across all endpoints. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-3] #### Funding Rates API [#funding-rates-api] New API endpoints have been added for retrieving funding rate data synchronized from **B2CONNECT**, including funding rates, mark price, and funding interval for Perpetual Futures markets. **Key points:** * Funding rate values streamed in real time * Mark price used for position valuation when available from LP * Funding interval synchronized per market configuration * FIX API contract extended with funding data fields #### OHLC Candlestick API [#ohlc-candlestick-api] A new API endpoint has been added for retrieving OHLC (candlestick) data, supporting both **Spot** and **Perpetual Futures** markets. Minute-level candle data is now stored for up to 5 years. OHLC candle data streaming is also available via the WebSocket API using gRPC transport, providing real-time candlestick updates. #### Favorite markets [#favorite-markets] A new **Favorite markets** feature has been added, allowing traders to manage personalized market lists via the Trading API. #### Comment field for orders and positions [#comment-field-for-orders-and-positions] A new `comment` field has been added to order and position responses across REST, WebSocket, and History APIs. The comment can be set when placing an order and is propagated to the associated position and execution records. #### B2COPY Integration API [#b2copy-integration-api] New API endpoints have been added for **B2COPY** and IB (Introducing Broker) integrations, including special account types for copy trading. The `isCopyTradingAccount` field has been added to the `/api/v1/total-fundings` endpoint. *** ### Improvements [#improvements-4] #### FIX API: enhanced request throughput [#fix-api-enhanced-request-throughput] The FIX API trading request processing has been optimized to support up to 100 requests per second per connection. All `TimeInForce` types are now supported, including **GTD** (Good Till Date). #### Multilingual support [#multilingual-support] Trading API, Settings API, and Reports API endpoints now support multilingual content with full Unicode character support, enabling localized responses for configurable fields, report names, and templates. #### Stop Market order calculation [#stop-market-order-calculation] The **Value** and **Amount** calculation for **Stop Market** orders has been corrected for **Spot** markets. **Slippage Rate** has been removed from **CFD** and **Perpetual Futures** order calculations. #### Trading API: empty categories hidden [#trading-api-empty-categories-hidden] Empty market categories are now automatically excluded from Trading API responses, reducing unnecessary data in category listings. #### Balance API: zero balance for all assets [#balance-api-zero-balance-for-all-assets] Assets without prior balance operations now return a zero balance in API responses instead of being omitted. #### Cross-rate market configuration [#cross-rate-market-configuration] Markets used exclusively for cross-rate calculations can now be disabled for trading while remaining active for rate conversion. #### History API: extended contracts [#history-api-extended-contracts] Positions and Events API responses have been extended with additional fields. The `updatedAt` field is now available as a sorting and filtering parameter in History Server API endpoints. #### Settings API: market update endpoint [#settings-api-market-update-endpoint] The market update endpoint has been changed from `PATCH` to `PUT` semantics, requiring the full market object in the request body. #### Settings API: legacy endpoints removed [#settings-api-legacy-endpoints-removed] Legacy commission and routing rule endpoints have been removed following the tier commission update. Use the current endpoints as documented in the API reference. *** ### Resolved issues [#resolved-issues-2] * Resolved an issue where `takeProfitPrice` and `stopLossPrice` values were missing from the History Server `/v2/orders` endpoint responses. * Resolved an issue where bulk order cancellation returned a successful result for non-existing orders. * Resolved an issue where bulk order cancellation returned a successful result for orders that could not be cancelled. * Resolved incorrect error codes returned when `closePositionLotAmount` was set to `0`, a negative value, or an empty string. * Resolved an issue where the WebSocket Book stream continued sending prices with an outdated tick size after market parameter changes. * Resolved an issue where negative spreads in the **Market Data API** were not handled correctly. * Resolved an issue where orders could not be created when using the default 24/7 calendar. * Resolved an issue where the `/external-orders` API returned `null` for `rejectReason` although the Trading Server received a reason from the LP. Customize your Trading Terminal and configure settings Customize your Trading Terminal and configure settings Explore and manage all available trading widgets Explore and manage all available trading widgets Learn basic terms and values used across the platform Learn basic terms and values used across the platform The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](trading) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `V` — Market Data Request (Client → B2TRADER) * `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER) * `X` — Market Data — Incremental Refresh (Client ← B2TRADER) * `Y` — Market Data Request Reject (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Market Data session, use the following parameters provided by B2TRADER: * **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint) * **SenderCompID**: Your client identifier for the Market Data session * **TargetCompID**: The server identifier for the Market Data session * **Protocol**: FIX 4.4 The Market Data connection does not require SSL. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request. ```text title="Example" 8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Optional. ```text title="Example" 8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^ ``` *** ## Market Data Request (V) [#market-data-request-v] This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol. After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update. To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout. **`262 MDReqID`** `String` The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard. **`263 SubscriptionRequestType`** `int` The type of response expected from the server. Required. Possible values: * `1` — Subscribe: receive updates as the market status changes * `2` — Unsubscribe: stop streaming market data for the specified symbol **`264 MarketDepth`** `int` The market depth for an order book snapshot. Required. Possible values: * `0` — Full order book * `1` — Top-of-the-book prices **`265 MDUpdateType`** `int` The update type. Required. Must be `1` (incremental updates for changed price levels only). **`267 NoMDEntryTypes`** `int` The number of `<269>` MDEntryType entries requested. Required. > Repeating group: **`269 MDEntryType`** `int` The side of the quote. Required. Possible values: * `0` — Bid * `1` — Ask **`146 NoRelatedSym`** `int` The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each. > Repeating group: **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```text title="Example (Client → B2TRADER)" 8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^ ``` ## Market Data — Snapshot/Full Refresh (W) [#market-data--snapshotfull-refresh-w] This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^ ``` ## Market Data — Incremental Refresh (X) [#market-data--incremental-refresh-x] This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. * Must be unique among active entries when `<279>` MDUpdateAction is `0` (New) * Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete) **`279 MDUpdateAction`** `int` The update type. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — New * `1` — Change * `2` — Delete **`58 Text`** `String` Additional context. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^ ``` ## Market Data Request Reject (Y) [#market-data-request-reject-y] This message is sent by the server to reject a Market Data Request due to business or technical reasons. **`262 MDReqID`** `String` The identifier of the rejected Market Data Request. Required. **`281 MDReqRejReason`** `int` The reason why the request is rejected. Optional. Possible values: * `0` — Unknown symbol * `1` — Duplicate MDReqID * `2` — Insufficient bandwidth * `3` — Insufficient permissions * `4` — Unsupported SubscriptionRequestType * `5` — Unsupported MarketDepth * `6` — Unsupported MDUpdateType * `8` — Unsupported MDEntryType **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^ ``` The Trading session enables order placement and execution management via the FIX 4.4 protocol. Use this session to submit orders and receive real-time execution reports for your trading activity. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Trading** session only. For real-time order book streaming, use the [Market Data](market-data) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `D` — New Order Single (Client → B2TRADER) * `8` — Execution Report (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Trading session, use the following parameters provided by B2TRADER: * **Host and port**: The Trading endpoint (provided separately from the Market Data endpoint) * **SenderCompID**: Your client identifier for the Trading session * **TargetCompID**: The server identifier for the Trading session * **Protocol**: FIX 4.4 The Trading connection requires SSL with a self-signed certificate. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=117^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=117^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=93^35=A^1=68a4446ac84827ff5cd35c74^34=225^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=054^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Conditional — required when sent in response to a Test Request. ```text title="Example" 8=FIX.4.4^9=79^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=156^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Required. ```text title="Example" 8=FIX.4.4^9=87^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=250^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=90^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=176^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=105^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=Session terminated by client^10=183^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=81^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=009^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Execution Report with rejected status and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=128^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=11^372=D^373=1^58=Required tag missing: ClOrdID^10=126^ ``` *** ## New Order Single (D) [#new-order-single-d] This message is sent by the client to place a new order. The server responds with an Execution Report confirming the order status. For details on supported order types, see [Order types](../get-started/order-types). For details on time-in-force options, see [Time in force](../get-started/time-in-force). **`11 ClOrdID`** `String` The unique client-assigned order identifier. Required. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`38 OrderQty`** `Qty` The order quantity. Required. Must be greater than zero. The decimal precision must not exceed the market's amount scale, and the value must be at least the market's minimum amount. **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`59 TimeInForce`** `char` The order's time-in-force policy. Required. Possible values: * `0` — Day * `1` — Good Till Cancel (GTC) * `3` — Immediate or Cancel (IOC) * `4` — Fill or Kill (FOK) * `6` — Good Till Date (GTD) **`44 Price`** `Price` The order price. Conditional — required when `<40>` OrdType is `2` (Limit), must not be present when `<40>` OrdType is `1` (Market). Must be greater than zero. The decimal precision must not exceed the market's price scale. **`126 ExpireTime`** `UTCTimestamp` The order expiration time. Conditional — required when `<59>` TimeInForce is `6` (GTD), must not be present otherwise. **`60 TransactTime`** `UTCTimestamp` The time of order creation. Required. ```text title="Limit order example (Client → B2TRADER)" 8=FIX.4.4^9=168^35=D^34=3^52=20231220-09:15:30.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order001^55=spot.btc_usdt^54=1^38=0.5^40=2^44=42500.00^59=1^60=20231220-09:15:30.000^10=123^ ``` ```text title="Market order example (Client → B2TRADER)" 8=FIX.4.4^9=155^35=D^34=4^52=20231220-09:16:00.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order002^55=spot.btc_usdt^54=2^38=0.1^40=1^59=3^60=20231220-09:16:00.000^10=045^ ``` ## Execution Report (8) [#execution-report-8] This message is sent by the server to confirm order status changes, including acknowledgment of new orders, fills, partial fills, cancellations, and rejections. For details on order statuses, see [Order statuses](../get-started/order-statuses). **`37 OrderID`** `String` The server-assigned unique order identifier. Required. **`11 ClOrdID`** `String` The client-assigned order identifier from the original New Order Single. Required. **`17 ExecID`** `String` The unique execution identifier. Present for trade executions. **`150 ExecType`** `char` The type of execution being reported. Required. Possible values: * `0` — New: order has been accepted * `4` — Canceled: order has been canceled by the server (e.g., IOC order partially filled, GTD order expired, or market settings changed) * `8` — Rejected: order has been rejected * `F` — Trade: order has been partially or fully filled **`39 OrdStatus`** `char` The current order status. Required. Possible values: * `0` — New * `1` — Partially filled * `2` — Filled * `4` — Canceled * `8` — Rejected **`1 Account`** `String` The account identifier. Required. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`44 Price`** `Price` The order price. Present for Limit orders. **`6 AvgPx`** `Price` The average price of all fills on this order. Required. **`14 CumQty`** `Qty` The total filled quantity. Required. **`151 LeavesQty`** `Qty` The remaining quantity to be filled. Required. Set to `0` for Canceled or Rejected orders. **`31 LastPx`** `Price` The price of the last fill. Present when `<150>` ExecType is `F` (Trade). **`32 LastQty`** `Qty` The quantity of the last fill. Present when `<150>` ExecType is `F` (Trade). **`15 Currency`** `String` The quote asset identifier. Optional. **`60 TransactTime`** `UTCTimestamp` The transaction time. Required. **`64 SettlDate`** `String` The settlement date in `YYYYMMDD` format. Required. **`58 Text`** `String` Additional information, such as the rejection reason. Optional. ```text title="New order accepted (B2TRADER → Client)" 8=FIX.4.4^9=220^35=8^34=5^52=20231220-09:15:30.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^150=0^39=0^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=0^14=0^151=0.5^60=20231220-09:15:30.100^64=20231220^10=087^ ``` ```text title="Trade execution (B2TRADER → Client)" 8=FIX.4.4^9=245^35=8^34=6^52=20231220-09:15:30.200^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^17=01HBXK5V3R8NQ7YR^150=F^39=2^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=42500.00^14=0.5^151=0^31=42500.00^32=0.5^15=usdt^60=20231220-09:15:30.200^64=20231220^10=154^ ``` ```text title="Order rejected (B2TRADER → Client)" 8=FIX.4.4^9=214^35=8^34=7^52=20231220-09:16:00.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YS^11=order002^150=8^39=8^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=2^40=1^6=0^14=0^151=0^58=Insufficient balance^60=20231220-09:16:00.100^64=20231220^10=201^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard session-level Reject or Execution Report rejection. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=100^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=006^ ``` Each trading account has an `accountStatus` field that determines which operations are permitted on the account. The field is returned on account objects by the API, such as in [Get accounts](../rest-api/settings). An account can be assigned one of the following statuses: * **Active**: All operations are permitted, including placing, modifying, and canceling orders, opening and closing positions, deposits, and withdrawals. * **Halted**: Trader-initiated trading is blocked. Requests to place, modify, or cancel orders and to open or close positions are rejected. Deposits and withdrawals remain allowed. Managed trading through the Management API (MAM, B2COPY) continues to work. * **Frozen**: All operations are blocked. Trading, deposits, and withdrawals are unavailable, and the account is view-only. Stop-out liquidation still executes as a safety mechanism. * **Archived**: The account is decommissioned and hidden from all user-facing surfaces. Real-time profit and loss, equity, margin level, and funding settlement continue for all statuses. Archived accounts are never returned in the trading API account list. They are excluded server-side, so an account that changes to *Archived* stops appearing in [Get accounts](../rest-api/settings) responses. A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. ## Introduction [#introduction] B2TRADER provides developers with three distinct methods for data delivery, each optimized for specific use cases and performance requirements: REST, WebSocket, and FIX APIs. The **REST API** provides read access to market data as well as both read and write access to trading operations. It serves as the foundation for synchronous data operations where immediate confirmation and guaranteed delivery are essential. The **WebSocket API** provides access to public market data streaming as well as private account updates. It delivers real-time updates with low latency, making it ideal for live trading environments. The **FIX API** provides direct access to market data and trading via the FIX 4.4 protocol. It is designed for institutional clients and algorithmic trading systems that require standardized, low-latency connectivity using the industry-standard Financial Information eXchange protocol. This approach provides developers with flexible options for building robust, scalable trading applications that can handle both operational requirements and real-time market dynamics. ### When to use REST API [#when-to-use-rest-api] * **Account configuration and settings**: Managing user preferences and system configurations. * **Order placement and modification**: Creating, updating, and canceling trading orders. * **Historical data retrieval**: Accessing past trading records and market data. * **One-time data requests**: Retrieving specific information that doesn't require continuous updates. * **Administrative operations**: Account management and system administration tasks. ### When to use WebSocket API [#when-to-use-websocket-api] * **Real-time price monitoring**: Live market price feeds and ticker updates. * **Live position tracking**: Continuous monitoring of open and closed positions. * **Order book visualization**: Real-time depth of market data. * **Market data feeds**: Streaming market statistics and trading activity. * **Account balance monitoring**: Live updates of account equity and margin status. ### When to use FIX API [#when-to-use-fix-api] * **Institutional connectivity**: Standardized FIX 4.4 protocol for professional trading infrastructure. * **Algorithmic trading**: Low-latency order execution and market data for automated strategies. * **Market data streaming**: Real-time order book snapshots and incremental updates via FIX protocol. * **Multi-venue integration**: Unified FIX connectivity for systems already integrated with other FIX-based venues. ## General considerations [#general-considerations] The following applies to all interface descriptions provided in this documentation: * **Endpoints**: All endpoints are relative and resolved based on a specified hostname (indicated as `{host}`). * **Authentication**: REST and WebSocket APIs require an access token (see [Authentication](#authentication)). The FIX API uses in-band authentication via the Logon message with Username, Password, and Account fields provided by B2TRADER. * **Data format**: REST and WebSocket APIs return results in JSON format. The FIX API uses the standard FIX 4.4 message format. * **Security**: All communications use secure protocols (HTTPS for REST, WSS for WebSocket, encrypted TCP for FIX). ### Authentication [#authentication] API access requires an access token for both REST and WebSocket connections. Authentication follows a two-step process: 1. Generate an offline token in the Trading terminal. 2. Exchange the offline token for an access token via API call. #### Token types [#token-types] **Offline token** * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time * **Purpose**: Generate access tokens **Access token** * **Type**: Bearer token * **Validity**: 60 minutes * **Purpose**: Authorize API requests ### Generate offline token [#generate-offline-token] To generate an offline token: 1. In the Trading terminal, open **Settings** and select **API token management**. 2. Click **+ Create new**. 3. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 4. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ### Obtain access token [#obtain-access-token] Request an access token using your offline token. **Endpoint**: `POST` `/frontoffice/api/v4/access-token` **Request body**: ```json { "token": "{YOUR_OFFLINE_TOKEN}" } ``` **Response** (Success): ```json { "accessToken": "{YOUR_ACCESS_TOKEN}", "expiresIn": 3600, "tokenType": "Bearer" } ``` **`accessToken`** `string` The access token for API authorization. **`expiresIn`** `integer` The token lifetime, in seconds. **`tokenType`** `string` The authentication type, always `"Bearer"`. ### Using access tokens [#using-access-tokens] Include the access token in API requests: ```http title="REST" Authorization: Bearer {YOUR_ACCESS_TOKEN} ``` ```http title="WebSocket" {URL}?access_token={YOUR_ACCESS_TOKEN} ``` Access tokens must be refreshed before expiration by repeating the Step 2 with your offline token. ## REST API: Synchronous data operations [#rest-api-synchronous-data-operations] The REST API serves as the foundation for synchronous data operations within the B2TRADER platform. This approach follows standard HTTP protocols and is ideal for operations requiring immediate confirmation and guaranteed delivery. ### Key characteristics [#key-characteristics] * **Request-response operations** where immediate confirmation is required. * **Account management** including settings and configuration. * **Order placement and modification** with guaranteed delivery. * **Historical data retrieval** for analysis and reporting. * **Stateless operations** that don't require persistent connections. ### HTTP response codes [#http-response-codes] B2TRADER API uses conventional HTTP response codes to indicate the success or failure of requests. **Success codes:** * `200 OK` — Request successful **Error codes:** * `400 Bad Request` — Invalid request parameters * `401 Unauthorized` — Authentication required * `403 Forbidden` — Insufficient permissions * `404 Not Found` — Resource not found * `429 Too Many Requests` — [Rate limit](#rate-limits) exceeded * `500 Internal Server Error` — Server error In case of an error, an object will be returned with the following structure: ```json { "code": "text", "message": "text", "details": { "source": "text", "message": "text", "stackTrace": "text" } } ``` ### Available endpoints [#available-endpoints] * **[Trading operations](../rest-api/trading)**: Create, modify, and cancel orders; open, close, and modify positions; control price trigger settings. * **[Trading history](../rest-api/history)**: Retrieve detailed execution records for positions and orders. * **[Settings and configurations](../rest-api/settings)**: Access account information, market specifications, trading sessions, and asset details. ### Rate limits [#rate-limits] Rate limits are applied per minute for each unique **AccountId** to ensure fair resource usage and maintain optimal API performance. All limits use the **Fixed Window** strategy. When rate limits are exceeded, the API returns a `429 Too Many Requests` HTTP status code. #### Trading methods [#trading-methods] * **Default limit**: 600 requests per minute for all methods. * **Reduced limit (200 rpm)** applies to: * Get order data methods * Bulk close positions method * Price triggers methods #### History methods [#history-methods] * **All request types**: 60 requests per minute. #### Settings methods [#settings-methods] * **GET requests**: 100 requests per minute. * **POST and DELETE requests**: 60 requests per minute. Rate limits are calculated independently for each method category. For example, you can make 100 GET requests to Settings methods and 60 requests to History methods within the same minute without hitting rate limits. ## WebSocket API: Real-time data streaming [#websocket-api-real-time-data-streaming] The WebSocket API delivers real-time updates with minimal latency, essential for modern trading applications. The implementation uses unidirectional communication from server to client, ensuring efficient data delivery. ### Key characteristics [#key-characteristics-1] * **Unidirectional communication** from server to client for optimal performance. * **Real-time market data** for live trading environments. * **Position and order updates** as they occur in real-time. * **Low-latency data delivery** for time-sensitive trading operations. * **Persistent connections** maintaining continuous data flow. ### SignalR implementation [#signalr-implementation] B2TRADER utilizes **AspNetCore SignalR** for WebSocket message organization and transmission, providing a robust and scalable real-time communication framework. **Resources:** * [Official GitHub Repository](https://github.com/dotnet/aspnetcore/tree/main/src/SignalR) * [Official Documentation](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr) SignalR provides a structured approach to real-time communication through standardized message formatting and connection management. ### Connection lifecycle [#connection-lifecycle] The data transfer process consists of two essential phases: 1. **Connection establishment** — Initial handshake, authentication, and subscription setup. 2. **Data streaming** — Continuous real-time data flow with automatic reconnection handling. ### Message types [#message-types] SignalR utilizes numerical `type` indicators for different operations: ### Available stream types [#available-stream-types] * **[Trading streams](../ws-api/trading)**: Track active orders, open and closed positions. * **[Market data streams](../ws-api/market-data)**: Get real-time order book updates, market statistics and price changes. * **[Account information streams](../ws-api/account-info)**: Get live account balance and margin updates. ## FIX API: Standardized protocol connectivity [#fix-api-standardized-protocol-connectivity] The FIX API provides direct access to B2TRADER via the FIX 4.4 protocol, the industry standard for electronic trading communication. It is designed for institutional clients and algorithmic trading systems. ### Key characteristics [#key-characteristics-2] * **FIX 4.4 protocol** for standardized, vendor-neutral connectivity. * **Dedicated sessions** for Market Data and Trading with separate endpoints. * **In-band authentication** via Logon message (Username, Password, Account). * **Real-time market data** with order book snapshots and incremental updates. * **Session management** with Heartbeat, Test Request, and Sequence Reset support. ### Authentication [#authentication-1] Unlike REST and WebSocket APIs, the FIX API does not use access tokens. Authentication is performed in-band as part of the FIX Logon message using credentials provided by B2TRADER: * **Username** (`<553>`): The client username * **Password** (`<554>`): The client password * **Account** (`<1>`): The account identifier ### Available session types [#available-session-types] * **[Market Data](../fix-api/market-data)**: Subscribe to real-time order book updates, snapshots, and incremental refreshes. * **[Trading](../fix-api/trading)**: Place orders and receive execution reports in real time. ## Integration best practices [#integration-best-practices] ### API selection strategy [#api-selection-strategy] * Use **REST API** for operational tasks requiring confirmation (order placement, account management). * Use **WebSocket API** for real-time monitoring and market data visualization. * Use **FIX API** for institutional connectivity, algorithmic trading, and integration with existing FIX-based infrastructure. * Implement multiple APIs in comprehensive trading applications for optimal functionality. ### Performance optimization [#performance-optimization] * Implement proper connection pooling for REST API requests. * Use WebSocket subscriptions efficiently by subscribing only to required data streams. * Handle reconnection logic for WebSocket connections to ensure data continuity. * Implement appropriate error handling and retry mechanisms. ### Security considerations [#security-considerations] * Store authentication tokens securely and implement token refresh mechanisms. * Use secure connections (HTTPS/WSS) for all API communications. * Implement proper input validation and sanitization. * Monitor API usage and implement rate limiting on the client side. This comprehensive API architecture enables developers to build sophisticated trading applications that can handle both real-time market dynamics and operational trading requirements efficiently. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all Limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the platform, without taking into account the time settings of the devices from which the platform is accessed. ## Get full balance [#get-full-balance] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"FullBalance"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "FullBalance", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of balance objects. **`item.assetId`** `string` The asset identifier. **`item.available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`item.total`** `decimal string` The overall amount of the asset, including locked funds. **`item.locked`** `decimal string` The asset amount locked on the account for execution of all placed Limit orders. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "assetId": "eur", "available": "497838.8", "total": "497838.8", "locked": "0" } ] } ``` ## Get margin data [#get-margin-data] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"MarginData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "MarginData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.marginBalanceInRAT`** `decimal string` The total amount of funds that can be used as a collateral for trading, in RAT. This value is calculated as SUM (*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*) Where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the BP root asset. **`item.creditInRAT`** `decimal string` The promotional trading credit granted to the account by the broker, in RAT. Credit is included in the account equity but excluded from the withdrawable amount. During a rolling deployment, older payloads might omit this field. In that case, default it to `0`. **`item.unrealizedPnlInRAT`** `decimal string` The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) **`item.equityInRAT`** `decimal string` The potential balance if all open positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. **`item.usedMarginInRAT`** `decimal string` The amount of funds that is used for maintaining all open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **`item.freeMarginInRAT`** `decimal string` The amount of funds that can be used for opening new positions. **`item.marginLevel`** `decimal string` The ratio of funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "marginBalanceInRAT": "497838.8", "creditInRAT": "0", "unrealizedPnlInRAT": "-5.25", "equityInRAT": "497833.55", "usedMarginInRAT": "100.18", "freeMarginInRAT": "497733.37", "marginLevel": "4969.3905" } } ``` ## Get order book [#get-order-book] ### Connection [#connection] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Book"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eur_chf" ], "invocationId": "0", "target": "Book", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.askTotalAmount`** `string` The total ask amount. **`item.bidTotalAmount`** `string` The total bid amount. **`item.asks`** `array of objects` The array of ask price objects. **`item.asks.price`** `string` The price, in the quote asset. **`item.asks.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.asks.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.bids`** `array of objects` The array of bid price objects. **`item.bids.price`** `string` The price, in the quote asset. **`item.bids.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.bids.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.version`** `string` The order book version. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eur_chf", "askTotalAmount": "18700000", "bidTotalAmount": "19100000", "asks": [ { "price": "0.93677", "amount": "5000000", "total": "4683850" }, { "price": "0.93676", "amount": "0", "total": "0" }, { "price": "0.93676", "amount": "0", "total": "0" } ], "bids": [ { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93655", "amount": "5000000", "total": "4682750" } ], "version": "12498", "snapshot": false } } ``` ## Get trading data [#get-trading-data] ### Connection [#connection-1] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"TradingData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.bnb_btc" ] ], "invocationId": "0", "target": "TradingData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.markets.displayName`** `string` The market ticker. **`item.markets.fullName`** `string` The market full name or description (optional). **`item.markets.price`** `decimal string` The current top-of-the-book price, in the quote asset. **`item.markets.priceInRAT`** `decimal string` The current top-of-the-book price, in conversion to the root asset of the platform. **`item.markets.priceChange24hr`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.markets.priceChangeAbs24hr`** `decimal string` The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. **`item.markets.highPrice24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.markets.lowPrice24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.markets.markPrice`** `decimal string` *Applicable to Perpetual markets only.* The mid-spread price, in conversion to RAT. **`item.markets.fundingRate`** `decimal string` *Applicable to Perpetual markets only.* The current funding rate. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "cfd.eur_chf", "type": "Cfd", "displayName": "cfd.eur_chf", "fullName": "", "price": "0.93586", "priceInRAT": "1", "priceChange24hr": "-0.0006", "priceChangeAbs24hr": "-0.00049", "highPrice24hr": "0.93695", "lowPrice24hr": "0.93134", "markPrice": null, "fundingRate": null } ], "snapshot": false } } ``` ## Get top of the book [#get-top-of-the-book] ### Connection [#connection-2] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Tob"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.eth_usdt" ] ], "invocationId": "0", "target": "Tob", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.ask`** `decimal string` The top-of-the-book ask price. **`item.markets.bid`** `decimal string` The top-of-the-book bid price. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "spot.eth_usdt", "ask": "2483.82", "bid": "2483.81" } ], "snapshot": false } } ``` ## Get trading chart [#get-trading-chart] ### Connection [#connection-3] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` and `timescale` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Chart"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eth_eur@15m" ], "invocationId": "0", "target": "Chart", "type": 4 } ``` *** ### Message [#message-3] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.low`** `decimal string` The lowest base asset price within the specified time interval. **`item.high`** `decimal string` The highest base asset price within the specified time interval. **`item.open`** `decimal string` The base asset price at the beginning of the specified time interval. **`item.close`** `decimal string` The base asset price at the end of the specified time interval. **`item.start`** `dateTime` The beginning of the specified time interval, in ISO 8601 format. **`item.end`** `dateTime` The end of the specified time interval, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eth_eur", "low": "2240.88", "high": "2270.29", "open": "2265.63", "close": "2255.99", "start": "2025-05-21T15:30:00Z", "end": "2025-05-21T15:45:00Z" } } ``` ## Get market summary [#get-market-summary] ### Connection [#connection-4] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Summary"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "cfd.eur_chf" ] ], "invocationId": "0", "target": "Summary", "type": 4 } ``` *** ### Message [#message-4] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.items`** `array of objects` The array of data objects. **`item.items.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.items.last`** `decimal string` The price of the last trade. **`item.items.high24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.items.low24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.items.percentChange`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "items": [ { "marketId": "cfd.eur_chf", "last": "0.93597", "high24hr": "0.93695", "low24hr": "0.93134", "percentChange": "-0.02" } ], "snapshot": false } } ``` ## Get open orders [#get-open-orders] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenOrders", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of market objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.status`** `string` The current [order status](../get-started/order-statuses). Possible values: * `Started` * `Pending` * `Working` **`item.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`item.reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`item.remainingAmount`** `decimal string` The order amount that hasn't yet been filled, in the base asset. **`item.requestedPrice`** `decimal string` The limit price for Limit orders; `null` for Market orders. **`item.executionPrice`** `decimal string` The volume-weighted average price of the order executions. **`item.createdAt`** `dateTime` The timestamp when the order was created, in ISO 8601 format. **`item.updatedAt`** `dateTime` The timestamp of the most recent update to the order, in ISO 8601 format. **`item.cancellationDate`** `dateTime` The timestamp when the order was cancelled or expired, in ISO 8601 format; `null` if not cancelled. **`item.commissionAssetId`** `string` The currency in which the commission was held. **`item.commissionAmount`** `decimal string` The total commissions put on hold for executing the order. **`item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when placing the order. **`item.fillFactor`** `decimal string` The proportion of the order amount filled so far, where `1` represents 100% fulfillment. **`item.comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.stopLoss`** `decimal string` The Stop Loss price, if set. ```json { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "orderId": "01JVQBFSTVC40VK03A0AY7K016", "timeInForce": "Gtc", "status": "Pending", "source": "Manual", "reason": "Trader", "side": "Buy", "orderType": "Limit", "requestedAmount": "10000", "remainingAmount": "10000", "requestedPrice": "0.9", "executionPrice": "0", "createdAt": "2025-05-20T17:22:31.899Z", "updatedAt": "2025-05-20T17:22:31.9001213Z", "cancellationDate": null, "commissionAssetId": "eur", "commissionAmount": "0", "leverage": 1, "fillFactor": "0", "takeProfit": null, "stopLoss": null, "comment": null } ] } ``` ## Get open positions [#get-open-positions] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenPositions"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenPositions", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.item`** `array of objects` The array of position objects. **`item.item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.item.marketDisplayName`** `string` The market ticker. **`item.item.marketFullName`** `string` The market full name or description (optional). **`item.item.createdAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. **`item.item.updatedAt`** `dateTime` The timestamp of the most recent update to the position, in ISO 8601 format. **`item.item.side`** `string` The position side. Possible values: * `Buy` * `Sell` **`item.item.status`** `string` The current position status. Always `"Open"`. **`item.item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when opening the position. **`item.item.positionLotAmount`** `decimal string` The position volume, in lots. **`item.item.positionPriceInRAT`** `decimal string` The current position price, in conversion to RAT. **`item.item.rateToRAT`** `decimal string` The current exchange rate of a quote asset to RAT. **`item.item.usedMarginInRAT`** `decimal string` The amount of trader’s funds used for maintaining a position, in conversion to RAT. **`item.item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.item.currentMarketPrice`** `decimal string` The current market price of the base asset: bid for Long positions and ask for Short positions. **`item.item.unrealizedPnlDayInRAT`** `decimal string` The potential profit or loss earned for a current day, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. **`item.item.unrealizedPnlDayPercent`** `decimal string` The potential profit or loss earned for a current day, in percents. **`item.item.unrealizedPnlTotalInRAT`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). **`item.item.unrealizedPnlTotalPercent`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT, in percents. **`item.item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.item.stopLoss`** `decimal string` The Stop Loss price, if set. **`item.item.positionModifier`** `string` The reason for the latest position update. **`item.item.comment`** `string | nullable` The text note inherited from the opening order, up to 100 characters. **`snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "item": [ { "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-03-12T06:36:31.257Z", "updatedAt": "2025-03-12T06:36:31.257Z", "side": "Buy", "status": "Open", "leverage": 1, "positionLotAmount": "0.01", "positionPriceInRAT": "1000.46", "rateToRAT": "1.07", "usedMarginInRAT": "1000.53", "openPrice": "0.96304", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "1.86", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-29.93", "unrealizedPnlTotalPercent": "-0.0291", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null }, { "positionId": "01JVQB9ZWJ6G4QV0P98X0QWNA7", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-05-20T17:19:21.49Z", "updatedAt": "2025-05-20T17:19:21.491321Z", "side": "Buy", "status": "Open", "leverage": 100, "positionLotAmount": "0.1", "positionPriceInRAT": "10004.6", "rateToRAT": "1.07", "usedMarginInRAT": "100.06", "openPrice": "0.93666", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "18.61", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-17.02", "unrealizedPnlTotalPercent": "-0.0017", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null } ], "snapshot": false } } ``` ## Get closed positions [#get-closed-positions] ### Connection [#connection-2] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"ClosePositionsOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "ClosePositionsOrders", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of position objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.positionCloseLotAmount`** `decimal string` The closed volume, in lots, which is equivalent to the corresponding filled order volume. **`item.reason`** `string` The reason for position closing. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.realizedPnlInRAT`** `decimal string` The actual profit or loss earned, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). **`item.closedAt`** `dateTime` The timestamp when the position was closed, in ISO 8601 format. **`item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`item.positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`item.rateToRAT`** `decimal string` The conversion rate to RAT. **`item.openedAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketFullName": "", "marketDisplayName": "EUR/CHF", "marketType": "Cfd", "orderId": "01JVSQ8WFA3QZ6AQTKYPXVXDWA", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.01", "reason": "Trader", "realizedPnlInRAT": "-29.25", "closedAt": "2025-05-21T15:26:57.0027785Z", "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "openPrice": "0.96304", "closePrice": "0.93571", "positionPriceInRAT": "1001.2", "rateToRAT": "1.07", "openedAt": "2025-03-12T06:36:31.257Z" } ] } ``` ## Open positions [#open-positions] ### Get executions for an open position [#get-executions-for-an-open-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/executions/list` #### Summary [#summary] Use this method to retrieve execution details for a specific open position using its position identifier. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`positionId`** `required` The position identifier. ##### Body [#body] **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`offset`** `integer · int32 | nullable` The number of items to skip before starting to collect the result set. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PMT0VMJG5B8XBDNZ7FNM1F/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "offset": 0 } ``` #### Response [#response] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VNWB23GSRN2XQAJD6Q", "baseAmount": "0.314", "executionPrice": "4603.5", "commissionAmountInRAT": "0", "commissions": [], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VN1F2JPM14AEV6V8YJ", "baseAmount": "0.045", "executionPrice": "4603.49", "commissionAmountInRAT": "0", "commissions": [], "comment": null } ] } ``` ### Get executions for open positions [#get-executions-for-open-positions] `POST` `/frontoffice/api/v4/positions/executions/list` #### Summary [#summary-1] Use this method to retrieve execution details for multiple open positions by providing an array of position identifiers. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`positionIds`** `array · string[]` The array of position identifiers. **`limit`** `integer · int32 | nullable` The maximum number of items to return. ```http title="Request example" POST /frontoffice/api/v4/positions/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "positionIds": [ "01K2PMT0VMJG5B8XBDNZ7FNM1F", "01K2PMXY63HESK110WT1CHMAFA" ], "limit": 5 } ``` #### Response [#response-1] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMXY63HESK110WT1CHMAFA", "orderId": "01K2PMXY1894RC6E2BYFR00T87", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:38:10.627Z", "executionId": "01K2PMXY63NXM30VNWPDECSFJR", "baseAmount": "15", "executionPrice": "4333.69288", "commissionAmountInRAT": "32.27", "commissions": [ { "assetId": "eur", "amount": "32.27" } ], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.292Z", "executionId": "01K2PMT0VMPCZW0JB2C9J6B405", "baseAmount": "0.141", "executionPrice": "4602.3", "commissionAmountInRAT": "5", "commissions": [ { "assetId": "eur", "amount": "5" } ], "comment": null } ] } ``` ## Closed positions [#closed-positions] ### Get orders for closed positions [#get-orders-for-closed-positions] `POST` `/frontoffice/api/v4/orders/closed-positions` #### Summary [#summary-2] Use this method to retrieve orders associated with closed positions within specified date ranges and market filters. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`createdAtFrom`** `string · date-time | nullable` The start date of the period when the positions were opened. **`createdAtTo`** `string · date-time | nullable` The end date of the period when the positions were opened. **`closedAtFrom`** `string · date-time | nullable` The start date of the period when the positions were closed. **`closedAtTo`** `string · date-time | nullable` The end date of the period when the positions were closed. **`marketId`** `string | nullable` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`marketType`** `string | nullable` The market type. Possible values: * `Cfd` * `Perp` **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastOrderId`** `string | nullable` The identifier of the final order to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/closed-positions HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "createdAtFrom": "2025-08-01T12:00:32.886Z", "createdAtTo": "2025-08-15T12:00:32.886Z" } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier. **`marketFullName`** `string | nullable` The market full name or description (optional). **`marketDisplayName`** `string | nullable` The market ticker. **`marketType`** `string` The market type. Possible values: * `Cfd` * `Perp` **`orderId`** `string` The order identifier. **`orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`timeInForce`** `string` The [time-in-force setting](../get-started/time-in-force) of the order. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`side`** `string` The order side. Possible values: * `Buy` * `Sell` **`positionCloseLotAmount`** `decimal string` The position amount closed by the order, in lots. **`reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`closedAt`** `string · date-time | nullable` The date and time when the position was closed. **`positionId`** `string` The position identifier. **`openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`rateToRAT`** `decimal string` The conversion rate to RAT. **`openedAt`** `string · date-time` The date and time when the position was opened. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "data": [ { "marketId": "cfd.eth_eur", "marketFullName": null, "marketDisplayName": "CFD ETH/EUR", "marketType": "Cfd", "orderId": "01K2PNGX50SR1FRE6P14PJC17E", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "15", "reason": "Trader", "realizedPnlInRAT": "-144.64", "closedAt": "2025-08-15T10:48:32.393Z", "positionId": "01K2PMXY63HESK110WT1CHMAFA", "openPrice": "4333.69288", "closePrice": "3370.58389", "positionPriceInRAT": "50558.75", "rateToRAT": "1", "openedAt": "2025-08-15T10:38:10.628Z", "comment": null }, { "marketId": "perp.eth_usdt", "marketFullName": "ETH/USDT_4s8hKqiPXmXOEhsO1J6W", "marketDisplayName": "ETH/USDT_jC6Im5PxwgZLrwyccRcI", "marketType": "Perpetual", "orderId": "01K2PNG3N6NKAJVV4RV5E2V0HK", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.5", "reason": "Trader", "realizedPnlInRAT": "13.42", "closedAt": "2025-08-15T10:48:06.234Z", "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "openPrice": "4603.1607", "closePrice": "4634.3915", "positionPriceInRAT": "1992.78", "rateToRAT": "0.86", "openedAt": "2025-08-15T10:36:02.293Z", "comment": null } ], "isExceeded": true } ``` ### Get executions for a closing order [#get-executions-for-a-closing-order] `POST` `/frontoffice/api/v5/orders/``{orderId}``/executions/list` #### Summary [#summary-3] Use this method to retrieve execution details for a specific position-closing order using its identifier. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The order identifier. ##### Body [#body-3] **`positionId`** `string | nullable` The position identifier. **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastExecutionId`** `string | nullable` The identifier of the final execution to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/01K2PNG3N6NKAJVV4RV5E2V0HK/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 5 } ``` #### Response [#response-3] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed amount of the base asset. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T19:02:22.196Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true } ], "isExceeded": true } ``` ### Get executions for closing orders [#get-executions-for-closing-orders] `POST` `/frontoffice/api/v5/orders/executions/list` #### Summary [#summary-4] Use this method to retrieve execution details for multiple position-closing orders by providing an array of order identifiers. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`orderId`** `string` The order identifier. **`positionId`** `string` The order identifier. ```http title="Request example" POST /frontoffice/api/v4/orders/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "orderPositionPairs": [ { "orderId": "01K31APDKZCVGWZA3XTF5JPAMD", "positionId": "01K31APDWF2EBHRKHH15VGB1ST" } ], "limit": 0 } ``` #### Response [#response-4] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T18:53:15.657Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true, "comment": null } ], "isExceeded": true } ``` ## Accounts [#accounts] ### Get accounts [#get-accounts] `GET` `/frontoffice/api/v3/accounts` #### Summary [#summary] Use this method to retrieve a list of all trading accounts with their basic information including account type and total balance. #### Request [#request] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/accounts HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response] In case of success, an array of objects will be returned. Each object contains the following information: **`accountId`** `string` The trading account identifier. **`publicAccountId`** `integer` The public account identifier for display purposes. **`accountName`** `string` The account name. **`accountType`** `string` The account type. Possible values: * `Hedging` * `Netting` **`accountStatus`** `string` The account status, which determines the permitted operations. For a description of each value, see [Account statuses](../get-started/account-statuses). Possible values: * `Active` * `Halted` * `Frozen` **`totalBalanceInRAT`** `decimal string` The total balance, in RAT. **`isCopyTradingAccount`** `boolean` Indicates if the account is `Copy`. ```json title="Response example — 200: OK" [ { "accountId": "685a7eaa360f9e7416221a61", "publicAccountId": 1234567, "accountName": "B2TRADER Hedging account", "accountType": "Hedging", "accountStatus": "Active", "totalBalanceInRAT": "6020.12", "isCopyTradingAccount": false }, { "accountId": "6891e70db552ff9c6fbbccf5", "publicAccountId": 1234568, "accountName": "B2TRADER Netting account", "accountType": "Netting", "accountStatus": "Halted", "totalBalanceInRAT": "10987.39", "isCopyTradingAccount": false } ] ``` ## Assets [#assets] ### Get assets [#get-assets] `GET` `/frontoffice/api/v3/assets` #### Summary [#summary-1] Use this method to retrieve a list of available assets on the platform. #### Request [#request-1] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-1] In case of success, an array of objects will be returned. Each object contains the following information: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`isRootAsset`** `boolean` Indicates whether this is a root asset. ```json title="Response example — 200: OK" [ { "assetId": "usdt", "assetName": "Tether", "isRootAsset": true }, { "assetId": "xrp", "assetName": "Ripple", "isRootAsset": false } ] ``` ## Markets [#markets] ### Get markets [#get-markets] `GET` `/frontoffice/api/v6/markets` #### Summary [#summary-2] Use this method to retrieve a list of available markets with their type, subtype, and favorite status. #### Request [#request-2] ##### Query parameters [#query-parameters] **`categoryId`** The market category identifier. **`dynamicCommissionGroupId`** The dynamic commission group identifier. **`isFavorite`** `boolean` Filter by favorite status. If set to `true`, only markets marked as favorites are returned. ```http title="Request example" GET /frontoffice/api/v6/markets?isFavorite=true HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} ``` #### Response [#response-2] In case of success, an array of market objects is returned. Each market object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description. **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" [ { "marketId": "spot.btc_usdt", "displayName": "BTC/USDT", "fullName": null, "type": "Spot", "subtype": null, "isFavorite": true }, { "marketId": "cfd.eth_btc", "displayName": "ETH/BTC", "fullName": "Ethereum to Bitcoin", "type": "Cfd", "subtype": "Crypto", "isFavorite": false }, { "marketId": "perp.trx_usdt", "displayName": "TRX/USDT", "fullName": "TRX to Tether Perpetual", "type": "Perpetual", "subtype": null, "isFavorite": false } ] ``` ### Get market [#get-market] `GET` `/frontoffice/api/v6/markets/``{marketId}` #### Summary [#summary-3] Use this method to retrieve detailed information about a specific market using its market identifier. #### Request [#request-3] ##### Path parameters [#path-parameters] **`marketId`** `required` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```http title="Request example" GET /frontoffice/api/v6/markets/{marketId} HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description (optional). **`baseAssetId`** `string` The base asset identifier. **`quoteAssetId`** `string` The quote asset identifier. **`minAmount`** `decimal string | nullable` *Applicable to Spot markets only.* The minimum tradable amount of the base asset. **`maxBaseAmount`** `decimal string | nullable` The maximum tradable amount of the base asset. **`priceDeviation`** `decimal string` The allowed price deviation for Limit orders placed on the market. Supports decimal values in the range `[0, 1]`, with up to 4 decimal places, for example: * `0.1` = 10% * `0.01` = 1% * `0.001` = 0.1% * `0.0001` = 0.01% If set to `0`, no restriction is applied, the price deviation is ignored. **`priceScale`** `integer` The price precision, which is the number of digits after a decimal separator. Also determines the minimum allowed trade price. Supports only integer values in the range `[2, 8]`. For example, `2` means the following price format: `0.01`, and `8`: `0.00000001`. **`amountScale`** `integer | nullable` *Applicable to Spot markets only.* The amount precision, which is the number of digits after a decimal separator. Also determines the minimum trade amount. Supports only integer values in the range `[0, 8]`. For example: * `0` means `1` (no digits after the decimal separator) * `5` means `0.00001` (five digits after the decimal separator) * `8` means `0.00000001` (eight digits after the decimal separator) **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`swapSettings`** `object | nullable` *Applicable to CFD markets only.* The fee type charged for holding open positions overnight. The amount can be negative for rebates. Possible values: * `FixPerLot`: The fixed amount per lot. * `Percent`: The fixed amount in points which is applied to the position size, in the range `[-1, 1]`, with up to 5 decimal places. * `Points`: The fixed amount of percents which is applied to the position size, with up to 3 decimal places. Structure: * **`type`** `string` — Swap calculation type. Possible values: `FixPerLot`, `Percent`, `Points`. * **`shortPositionSettings`** `object` — Settings for Short positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` * **`longPositionSettings`** `object` — Settings for Long positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` **`lotSize`** `integer | nullable` *Not applicable to Spot markets.* The standardized quantity of the base asset per lot. Supports only integer values in the range `[1, 1000000]`. **`minLotAmount`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum order amount, in lots, that can be placed and executed. Supports values in the range `[0.00000001, 1]`. **`maxLotAmount`** `integer | nullable` *Not applicable to Spot markets.* The maximum order amount, in lots, that can be placed and executed. Supports only integer values in the range `[1, 10000]`. **`tickSize`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum price increment. **`lotStep`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum lot amount increment. Supports values in the range `[0.00000001, 1]`. By default, equals to the `minLotAmount`. **`slippageRate`** `decimal string` The expected slippage, that is, the difference between the expected execution price and the actual one. This value is used as a multiplier to calculate the funds to be put on hold for a market order execution. Supports values in the range `[1, 10]`, including decimal values with up to 4 decimal places. The default value is `1` which means that only the current bid/ask price is put on hold. For example, `1.1` means that the current bid or ask price + 10% is put on hold for each order, to cover the 10% slippage. **Mind that** the total amount funds to be held depends on the order parameters and takes into account many conditions, the slippage rate is only one of them. **`calendar`** `object` The trading calendar defining market trading hours. Structure: * **`timeZoneId`** `string` — IANA time zone identifier. * **`tradingSessions`** `array` — Weekly trading sessions: * **`dayOfWeek`** `string` — One of: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. * **`timeIntervals`** `array` — List of intervals with: * **`start`** `string` (time) — Start time in `calendar.timeZoneId`. * **`end`** `string` (time) — End time in `calendar.timeZoneId`. * **`sessionOverrides`** `array` — Optional specific-date overrides: * **`date`** `string` (date) — In `YYYY-MM-DD` format. * **`timeIntervals`** `array | nullable` — Intervals for that date. **`fundingStartTime`** `string | nullable` *Applicable to Perpetual markets only.* The time of the first funding settlement, in the following format: `HH:MM:SS`. **`fundingIntervalInHours`** `integer | nullable` *Applicable to Perpetual markets only.* The funding settlement interval, in hours. Possible values: 1, 2, 3, 4, 6, 8, 12, 24. **`leverageProfile`** `object` *Not applicable to Spot markets.* The leverage profile. Structure: * **`leverageType`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`leverage`** `object` * **`useOnlyMaxLeverage`** `boolean` * **`maxLeverage`** `integer` — For `Fixed` leverage type only. * **`tiers`** `array` — For `Dynamic` leverage type only. * **`maxLeverage`** `integer` — The maximum allowed leverage for this tier. * **`maxNotionalValueInRAT`** `string | nullable` — The maximum position notional for this tier. **`commissionSettings`** `object` The commission settings. Structure: * **`type`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`charge`** `object` * **`type`** `string` — Possible values: `Percent`, `FixPerLot`. * **`assetId`** `string | nullable` — For `Fixed` commission type only. * **`size`** `decimal string` — For `Fixed` commission type only. * **`tiers`** `array` — For `Dynamic` commission type only. * **`size`** `string` — The commission amount for this tier. * **`minTradingVolumeInRAT`** `string` — The minimum required trading volume for this tier. * **`minCommissionInRAT`** `decimal string | nullable` * **`dynamicCommissionGroupId`** **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" { "marketId": "string", "displayName": "string", "fullName": "string", "baseAssetId": "string", "quoteAssetId": "string", "minAmount": "string", "maxBaseAmount": "string", "minQuoteAmount": "string", "priceDeviation": "string", "priceScale": 0, "amountScale": 0, "type": "Spot", "subtype": "Cash", "swapSettings": { "type": "FixPerLot", "shortPositionSettings": { "size": "string", "assetId": "string" }, "longPositionSettings": { "size": "string", "assetId": "string" } }, "lotSize": 0, "minLotAmount": "string", "maxLotAmount": 0, "tickSize": "string", "lotStep": "string", "slippageRate": "string", "calendar": { "timeZoneId": "string", "tradingSessions": [ { "dayOfWeek": "Monday", "timeIntervals": [ { "start": "string", "end": "string" } ] } ], "sessionOverrides": [ { "date": "2025-12-18", "timeIntervals": [ { "start": "string", "end": "string" } ] } ] }, "fundingStartTime": "string", "fundingIntervalInHours": 0, "leverageProfile": { "leverageType": "Fixed", "leverage": { "useOnlyMaxLeverage": true, "maxLeverage": 0 } }, "commissionSettings": { "type": "Dynamic", "сharge": { "type": "Percent", "tiers": [ { "size": "string", "minTradingVolumeInRAT": "string" }, { "size": "string", "minTradingVolumeInRAT": "string" } ], "minCommissionInRAT": "string" }, "dynamicCommissionGroupId": "string" }, "isFavorite": true } ``` *** ### Add favorite market [#add-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/add` #### Summary [#summary-4] Add a market to the current user's favorites list. #### Request [#request-4] ##### Body [#body] **`marketId`** `string` `required` The market identifier to add to favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/add HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-4] In case of success (`200`), an empty object is returned. *** ### Remove favorite market [#remove-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/delete` #### Summary [#summary-5] Remove a market from the current user's favorites list. #### Request [#request-5] ##### Body [#body-1] **`marketId`** `string` `required` The market identifier to remove from favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/delete HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-5] In case of success (`200`), an empty object is returned. ## Account margin settings [#account-margin-settings] ### Get margin assets [#get-margin-assets] `GET` `/frontoffice/api/v4/account-margin-settings/assets` #### Summary [#summary-6] Use this method to retrieve a list of assets that can be used as collateral for margin trading. #### Request [#request-6] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v4/account-margin-settings/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`assets`** `array` A list of assets that can be used as a collateral for margin trading. Each array item contains: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`total`** `decimal string` The overall amount of the asset, including locked funds. **`marginRatio`** `decimal string` The percentage of the asset value used as a collateral. Supports values in the range `[0, 1]`, where `1` represents 100.00%. **`isSelected`** `boolean` Indicates whether the asset is selected to be used as collateral. Can be `true` only for assets with the `marginRatio` more than `0`. ```json title="Response example — 200: OK" { "assets": [ { "assetId": "btc", "assetName": "btc", "available": "0.031", "total": "0.031", "marginRatio": "1", "isSelected": true }, { "assetId": "eth", "assetName": "eth", "available": "0", "total": "0", "marginRatio": "1", "isSelected": false } ] } ``` ### Select margin asset [#select-margin-asset] `POST` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-7] Use this method to enable a particular asset to be used as collateral for margin trading. Only assets with the `marginRatio` more than `0` can be selected. #### Request [#request-7] ##### Path parameters [#path-parameters-1] **`assetId`** `required` The asset identifier. ```http title="Request example" POST /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json Accept: */* {} ``` #### Response [#response-7] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ### Disable margin asset [#disable-margin-asset] `DELETE` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-8] Use this method to prohibit a specific asset from being used as collateral for margin trading. #### Request [#request-8] ##### Path parameters [#path-parameters-2] **`assetId`** `required` The asset identifier. ```http title="Request example" DELETE /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-8] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ## Info [#info] ### Get server info [#get-server-info] `GET` `/frontoffice/api/v3/info` #### Summary [#summary-9] Use this method to retrieve current server time and timezone information. #### Request [#request-9] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`serverTime`** `string` The server time, in the Unix timestamp format. **`serverTimeZone`** `string` The server time zone. ```json title="Response example — 200: OK" { "serverTime": "1755190380", "serverTimeZone": "+00:00" } ``` ### Get server time zones [#get-server-time-zones] `GET` `/frontoffice/api/v3/info/time-zones` #### Summary [#summary-10] Use this method to retrieve available server time zones. #### Request [#request-10] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info/time-zones HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-10] In case of success, an array of objects will be returned. Each object contains the following information: **`id`** `string` The time zone identifier. **`offset`** `string` The UTC offset, in the following format: `HH:MM:SS`. **`offsetInMinutes`** `integer · int32` The UTC offset in minutes. **`shortLabel`** `string` The short label for the time zone. **`label`** `string` The display label for the time zone. ```json title="Response example — 200: OK" [ { "id": "Africa/Abidjan", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Abidjan", "label": "(UTC+00:00) Côte d’Ivoire Time" }, { "id": "Africa/Algiers", "offset": "01:00:00", "offsetInMinutes": 60, "shortLabel": "Africa/Algiers", "label": "(UTC+01:00) Central European Time (Algiers)" }, { "id": "Africa/Bissau", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Bissau", "label": "(UTC+00:00) Guinea-Bissau Time" }, ... ] ``` ## Webhooks [#webhooks] ### Create webhook API key [#create-webhook-api-key] `POST` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-11] Create a new webhook API key for receiving TradingView alerts. #### Request [#request-11] ##### Header parameters [#header-parameters] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Body [#body-2] **`name`** `string` `required` A descriptive name for the API key, up to 100 characters. ```http title="Request example" POST /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "name": "My TradingView Key" } ``` #### Response [#response-11] In case of success (`201`), the created API key object is returned. **`id`** `string` The unique identifier of the API key. **`apiKey`** `string` The full API key value. The key is shown only once at creation. **`name`** `string` The name assigned to the key. **`userId`** `string` The user identifier the key is bound to. **`status`** `string` The key status: `Active`. **`createdAt`** `string` The timestamp when the key was created. **`expiresAt`** `string` The timestamp when the key expires (one year from creation). ```json title="Response example" { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "apiKey": "wh_key_abc123def456...", "name": "My TradingView Key", "userId": "01JZ3CVZKN20410JPYYH1YZJSK", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ``` The API key is shown only once in the creation response. It can't be retrieved again after this call. *** ### List webhook API keys [#list-webhook-api-keys] `GET` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-12] Retrieve all webhook API keys for the authenticated user along with the webhook URL. #### Request [#request-12] ##### Header parameters [#header-parameters-1] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ```http title="Request example" GET /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-12] In case of success (`200`), the webhook URL and a list of API keys are returned. **`webhookUrl`** `string` The webhook URL to configure in TradingView alerts. **`apiKeys`** `array of objects` The list of API keys. **`apiKeys[].id`** `string` The unique identifier of the API key. **`apiKeys[].name`** `string` The name assigned to the key. **`apiKeys[].status`** `string` The key status. Possible values: * `Active` * `Revoked` * `Expired` **`apiKeys[].createdAt`** `string` The timestamp when the key was created. **`apiKeys[].expiresAt`** `string` The timestamp when the key expires. ```json title="Response example" { "webhookUrl": "https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3...", "apiKeys": [ { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "name": "My TradingView Key", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ] } ``` *** ### Revoke webhook API key [#revoke-webhook-api-key] `DELETE` `/frontoffice/api/v3/webhook/api-keys/{id}` #### Summary [#summary-13] Revoke an active webhook API key. After revocation, the key can no longer be used to authenticate webhook requests. #### Request [#request-13] ##### Header parameters [#header-parameters-2] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Path parameters [#path-parameters-3] **`id`** `string` `required` The unique identifier of the API key to revoke. ```http title="Request example" DELETE /frontoffice/api/v3/webhook/api-keys/01JZ3CVZKN20410JPYYH1YZJSK HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-13] In case of success (`200`), a confirmation object is returned. **`success`** `boolean` Indicates whether the key was revoked successfully. **`message`** `string` A description of the result. ```json title="Response example" { "success": true, "message": "API key revoked successfully" } ``` *** ### Receive TradingView alert [#receive-tradingview-alert] `POST` `/frontoffice/api/v3/webhook/alerts/{userId}` #### Summary [#summary-14] Accept a webhook alert from TradingView and place an order on the specified trading account. TradingView calls this endpoint when an alert triggers. #### Request [#request-14] ##### Path parameters [#path-parameters-4] **`userId`** `string` `required` The B2TRADER user identifier (ULID format). ##### Body [#body-3] **`apiKey`** `string` `required` The webhook API key for authentication. **`accountId`** `string` `required` The trading account identifier. **`symbol`** `string` `required` The market symbol with a type prefix (`spot.`, `cfd.`, or `perp.`) followed by the pair name. For example: `spot.btc_usdt`, `cfd.eur_usd`, `perp.btc_usdt`. **`side`** `string` `required` The order side. Possible values: * `buy` * `sell` **`quantity`** `decimal string` `required` The order quantity in the base asset. **`orderType`** `string` The order type. Default: `market`. Possible values: * `market` * `limit` * `stop` * `stop_limit` **`price`** `decimal string` The limit price. Required for `limit` and `stop_limit` orders. **`stopPrice`** `decimal string` The stop price. Required for `stop` and `stop_limit` orders. **`leverage`** `decimal string` The leverage ratio. Applicable to CFD and Perpetual Futures markets only. **`takeProfit`** `decimal string` The take profit trigger price. **`stopLoss`** `decimal string` The stop loss trigger price. **`timeInForce`** `string` The time-in-force policy. Default: `gtc`. Possible values: * `gtc` * `ioc` * `fok` * `day` **`comment`** `string` A custom comment, up to 256 characters. **`deduplicationId`** `string` A UUID for idempotency. Duplicate requests with the same ID within five minutes return a cached response. ```http title="Request example" POST /frontoffice/api/v3/webhook/alerts/01JZ3CVZKN... HTTP/1.1 Host: {host} Content-Type: application/json { "apiKey": "wh_key_abc123def456...", "accountId": "01JZ3CVZKN20410JPYYH1YZJSK", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01", "comment": "TV Strategy Signal" } ``` #### Response [#response-14] In case of success (`200`), an order confirmation is returned. **`success`** `boolean` Indicates whether the order was placed successfully. **`orderId`** `string` The unique identifier of the created order. **`orderStatus`** `string` The initial status of the order. **`message`** `string` A description of the result. **`timestamp`** `string` The timestamp of the response. ```json title="Response example" { "success": true, "orderId": "01JZ3CVZKN20410JPYYH1YZJSK", "orderStatus": "Working", "message": "Order placed successfully", "timestamp": "2026-02-02T12:34:56.789Z" } ``` #### Rate limits [#rate-limits] Webhook requests are limited to five requests per second per user. If the limit is exceeded, the response returns a `429` status code with the following headers: * `X-RateLimit-Limit`: Maximum requests per window * `X-RateLimit-Remaining`: Remaining requests in the current window * `X-RateLimit-Reset`: Unix timestamp when the window resets ## Orders [#orders] ### Place SPOT order [#place-spot-order] `POST` `/frontoffice/api/v3/orders` #### Summary [#summary] Use this method to create and submit a new order for SPOT markets. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Body [#body] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Limit", "timeInForce": "Gtc", "requestedAmount": 0.02, "requestedPrice": 115193.35, "comment": "Strategy A" } } ``` #### Response [#response] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. Right after the order is created commission is `0`. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K1ZTB4DB0S6Y2NH81S781BQX", "orderType": "Limit", "side": "Buy", "status": "Pending", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.02", "remainingAmount": "0.02", "requestedPrice": "115193.35", "executionPrice": "0", "createdAt": "2025-08-06T13:50:13.931Z", "updatedAt": "2025-08-06T13:50:13.9325008Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Place CFD order [#place-cfd-order] `POST` `/frontoffice/api/cfd/v4/orders` #### Summary [#summary-1] Use this method to create and submit a new order for CFD markets. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "timeInForce": "Gtd", "requestedLotAmount": 1, "requestedPrice": 3280, "leverage": 75, "cancellationDate": "2025-08-10T00:00:00Z", "stopLoss": { "price": 3320, "isTrailing": false }, "takeProfit": { "price": 3200 }, "comment": "Strategy A" } } ``` #### Response [#response-1] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2253Q9X3VTJ68PNWY40JC6Q", "status": "Pending" } } ``` ### Place PF order [#place-pf-order] `POST` `/frontoffice/api/perpetual/v4/orders` #### Summary [#summary-2] Use this method to create and submit a new order for Perpetual markets. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `perp.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "perp.eth_usdt", "side": "Buy", "orderType": "Market", "timeInForce": "Ioc", "requestedLotAmount": 10, "leverage": 159, "comment": "Strategy A" } } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K228VN55N7WFZRG70M24T9J1", "status": "Working" } } ``` ### Cancel order [#cancel-order] `DELETE` `/frontoffice/api/v3/orders/``{orderId}` #### Summary [#summary-3] Use this method to cancel an active order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`orderId`** `required` The order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/orders/01K2PF9XS29WN4JZRHMCTTQYJB HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` * `StopOrder` * `FixApi` * `System` **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.eth_usdt", "marketDisplayName": "SPOT ETH/USDT", "orderId": "01K2PF9XS29WN4JZRHMCTTQYJB", "orderType": "Limit", "side": "Buy", "status": "Cancelled", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.1", "remainingAmount": "0.1", "requestedPrice": "4450", "executionPrice": "0", "createdAt": "2025-08-15T08:59:51.97Z", "updatedAt": "2025-08-15T09:00:06.2791048Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Get SPOT order data [#get-spot-order-data] `POST` `/frontoffice/api/v3/order-data` #### Summary [#summary-4] Use this method to retrieve and validate order data for SPOT market orders before placing. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-3] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.requestedBaseAmount`** `decimal string | nullable` The requested amount in base asset units. **`order.requestedQuoteAmount`** `decimal string | nullable` The requested amount in quote asset units. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. ```http title="Request example" POST /frontoffice/api/v3/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=3.0 Accept: */* { "order": { "marketId": "spot.eth_usdt", "side": "Buy", "orderType": "Limit", "requestedBaseAmount": 0.2, "requestedPrice": 4600 } } ``` #### Response [#response-4] In case of success, an object will be returned. Each object contains the following information: **`baseAmount`** `decimal string` The calculated base asset amount for the order. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmount`** `decimal string` The estimated commission amount to be charged. **`total`** `decimal string` The total quote asset amount, including the estimated commission. ```json title="Response example — 200: OK" { "order": { "baseAmount": "0.2", "quoteAmount": "920", "commissionAmount": "9.2", "total": "929.2" } } ``` ### Get CFD order data [#get-cfd-order-data] `POST` `/frontoffice/api/cfd/v4/order-data` #### Summary [#summary-5] Use this method to retrieve and validate order data for CFD market orders before placing. #### Request [#request-5] ##### Header parameters [#header-parameters-5] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables the Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/cfd/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": 15000, "triggerType": "points" }, "stopLoss": { "triggerSize": "4020", "triggerType": "price", "isTrailing": false }, "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Market", "leverage": 135, "requestedLotAmount": 1 } } ``` #### Response [#response-5] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "34.4613643", "quoteAmount": "4004.345", "commissionAmountInRAT": "0", "marginLevel": "5.3015", "takeProfit": { "price": "3989.345", "rate": "0.0037", "points": 15000, "pnl": "17.42713545" }, "stopLoss": { "price": "4020", "rate": "-0.0039", "points": -15655, "pnl": "-18.18812036" } } } ``` ### Get PF order data [#get-pf-order-data] `POST` `/frontoffice/api/perpetual/v4/order-data` #### Summary [#summary-6] Use this method to retrieve and validate order data for Perpetual market orders before placing. #### Request [#request-6] ##### Header parameters [#header-parameters-6] **`accountId`** `required` The trading account identifier. ##### Body [#body-5] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/perpetual/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": "0.01", "triggerType": "rate" }, "stopLoss": { "triggerSize": "-100", "triggerType": "pnl", "isTrailing": false }, "marketId": "perp.btc_usdt", "side": "Buy", "orderType": "Limit", "leverage": 100, "requestedLotAmount": 0.5, "requestedPrice": 118450 } } ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "592.25", "quoteAmount": "59225", "commissionAmountInRAT": "0", "marginLevel": "0.3582", "takeProfit": { "price": "119634.5", "rate": "0.01", "points": 11845, "pnl": "592.25" }, "stopLoss": { "price": "118250", "rate": "-0.0016", "points": -2000, "pnl": "-100" } } } ``` ## Stop orders [#stop-orders] ### Place SPOT Stop order [#place-spot-stop-order] `POST` `/frontoffice/api/v3/stop-orders` #### Summary [#summary-7] Use this method to create and submit a new Stop order for SPOT markets. #### Request [#request-7] ##### Header parameters [#header-parameters-7] **`accountId`** `required` The trading account identifier. ##### Body [#body-6] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Market", "activationPrice": 128000, "requestedAmount": 0.01, "timeInForce": "Ioc", "comment": "Strategy A" } } ``` #### Response [#response-7] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order, same as in the request. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K2MNC3BVR5WRTBEE9YWAS91K", "orderType": "Market", "side": "Buy", "requestedPrice": "0", "activationPrice": "128000", "requestedAmount": "0.01", "timeInForce": "Ioc", "status": "WaitingForActivation", "createdAt": "2025-08-14T16:07:25.8193038Z", "updatedAt": "2025-08-14T16:07:25.8193044Z", "cancellationDate": null, "comment": null } } ``` ### Place CFD Stop order [#place-cfd-stop-order] `POST` `/frontoffice/api/cfd/v4/stop-orders` #### Summary [#summary-8] Use this method to create and submit a new Stop order for CFD markets. #### Request [#request-8] ##### Header parameters [#header-parameters-8] **`accountId`** `required` The trading account identifier. ##### Body [#body-7] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "activationPrice": 3200, "requestedLotAmount": 0.5, "timeInForce": "Gtd", "leverage": 76, "requestedPrice": 3500, "cancellationDate": "2025-08-18T00:00:00Z", "stopLoss": { "price": "3900", "isTrailing": false }, "takeProfit": { "price": "3100" }, "comment": "Strategy A" } } ``` #### Response [#response-8] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNRWP2J1S8T9TKTCXWYY87", "status": "WaitingForActivation" } } ``` ### Place PF Stop order [#place-pf-stop-order] `POST` `/frontoffice/api/perpetual/v4/stop-orders` #### Summary [#summary-9] Use this method to create and submit a new Stop order for Perpetual markets. #### Request [#request-9] ##### Header parameters [#header-parameters-9] **`accountId`** `required` The trading account identifier. ##### Body [#body-8] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "perp.btc_usdt", "side": "Sell", "orderType": "Market", "activationPrice": 115000, "requestedLotAmount": 1, "timeInForce": "Fok", "leverage": 22, "stopLoss": { "price": "118020", "isTrailing": true }, "takeProfit": { "price": "113873" }, "comment": "Strategy A" } } ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNM0S8B2R9DS7BWJ8PGYPR", "status": "WaitingForActivation" } } ``` ### Cancel Stop order [#cancel-stop-order] `DELETE` `/frontoffice/api/v3/stop-orders/``{orderId}` #### Summary [#summary-10] Use this method to cancel an active Stop order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-10] ##### Header parameters [#header-parameters-10] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The Stop order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/stop-orders/01K2MNGAWPMQJ7WGATFSCAS1G4 HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-10] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. ```json title="Response example — 200: OK" { "order": { "marketId": "perp.btc_usdt", "marketDisplayName": "Perpetual BTC/USDT", "orderId": "01K2MNGAWPMQJ7WGATFSCAS1G4", "orderType": "Limit", "side": "Sell", "requestedPrice": "115100", "activationPrice": "115000", "requestedAmount": "1", "timeInForce": "Gtc", "status": "Rejected", "createdAt": "2025-08-14T16:09:44.5986099Z", "updatedAt": "2025-08-14T16:09:44.5986103Z", "cancellationDate": null } } ``` ## Positions [#positions] ### Close position [#close-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/close` #### Summary [#summary-11] Use this method to close a specific position entirely or partially. #### Request [#request-11] ##### Header parameters [#header-parameters-11] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-2] **`positionId`** `required` The position identifier to close. ##### Body [#body-9] **`closePositionLotAmount`** `decimal string | nullable` The portion of the position to close, in lots. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PFXDP1FWCJSGTX4GJ6JHM0/close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-11] In case of success, an object will be returned. Each object contains the following information: **`positionId`** `string` The position identifier. ```json title="Response example — 200: OK" { "positionId": "01K2PFXDP1FWCJSGTX4GJ6JHM0" } ``` ### Bulk close positions [#bulk-close-positions] `POST` `/frontoffice/api/v4/positions/bulk-close` #### Summary [#summary-12] Use this method to close multiple positions simultaneously based on different criteria such as all positions, positive PnL only, or negative PnL only. #### Request [#request-12] ##### Header parameters [#header-parameters-12] **`accountId`** `required` The trading account identifier. ##### Body [#body-10] **`mode`** `string` `required` The bulk close mode. Possible values: * `AllPositions` — close all positions. * `PositivePnl` — close only positions with positive PnL. * `NegativePnl` — close only positions with negative PnL. ```http title="Request example" POST /frontoffice/api/v4/positions/bulk-close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "mode": "AllPositions" } ``` #### Response [#response-12] In case of success, an object will be returned containing identifiers of closed positions. ```json title="Response example — 200: OK" { "status": "accepted", "positionIds": [ "01K228VNC2Q7E7K9W8GABWBZ5Z", "01K22BZ2DCETJZKW6MK81N1T8Y", "01K2CXF06A3A5SK2YFJT67CMZ5", "01K2CXF2ZJ6MJYMEK663TBBY8K", "01K2PFXDP1FWCJSGTX4GJ6JHM0" ] } ``` ### Get trigger data [#get-trigger-data] `POST` `/frontoffice/api/v4/positions/``{positionId}``/trigger-data` #### Summary [#summary-13] Use this method to retrieve Stop loss and Take profit settings for an open position. #### Request [#request-13] ##### Header parameters [#header-parameters-13] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-3] **`positionId`** `required` The position identifier. ##### Body [#body-11] **`stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`stopLoss.isTrailing`** `boolean | nullable` Indicates if Stop loss is Trailing. **`takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/trigger-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "triggerSize": "-0.01", "triggerType": "rate", "isTrailing": true }, "takeProfit": { "triggerSize": 2500, "triggerType": "points" } } ``` #### Response [#response-13] In case of success, an object will be returned. Each object contains the following information: **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "takeProfit": { "price": "248.27", "rate": "0.1119", "points": 2500, "pnl": "21.5" }, "stopLoss": { "price": "221.04", "rate": "-0.01", "points": -223, "pnl": "-1.91" } } ``` ### Submit triggers [#submit-triggers] `PUT` `/frontoffice/api/v4/positions/``{positionId}``/triggers` #### Summary [#summary-14] Use this method to modify Stop loss and Take profit settings for an open position. #### Request [#request-14] ##### Header parameters [#header-parameters-14] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-4] **`positionId`** `required` The position identifier. ##### Body [#body-12] **`stopLoss.price`** `decimal string` The Stop loss trigger price. **`stopLoss.isTrailing`** `boolean` If `true`, enables the Trailing behavior for Stop loss. **`takeProfit.price`** `decimal string` The Take profit trigger price. ```http title="Request example" PUT /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/triggers HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "price": "165.13", "isTrailing": true }, "takeProfit": { "price": 250 } } ``` #### Response [#response-14] In case of success, an object will be returned containing the identifier of the updated position. ```json title="Response example — 200: OK" { "positionId": "01K2HYXA7N2G9NHTFEWYVM9SEQ" } ``` ## Commissions [#commissions] ### Get account trading volume [#get-account-trading-volume] `GET` `/frontoffice/api/v3/commission/``{dynamicCommissionGroupId}``/account-trading-volume` #### Summary [#summary-15] Use this method to obtain a cumulative account trading volume used for calculating the commission tier. #### Request [#request-15] ##### Header parameters [#header-parameters-15] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-5] **`dynamicCommissionGroupId`** `required` The dynamic commission group identifier. Use [Get market](settings#get-market) to obtain. ```http title="Request example" GET /frontoffice/api/v3/commission/{dynamicCommissionGroupId}/account-trading-volume HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-15] In case of success, an object will be returned containing current trading volume, in RAT, for the account. ```json title="Response example — 200: OK" { "currentTradingVolumeInRAT": "string" } ``` You can connect B2Trader to **ChatGPT** as a **connector**. It uses the same B2Trader MCP URL and OAuth sign-in as every other agent. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in ChatGPT's connector directory. Connector availability depends on your ChatGPT plan. ## Connect the B2Trader connector [#connect-the-b2trader-connector] 1. In ChatGPT, open **Settings** → **Connectors**. 2. Choose to add a connector by **URL** (custom connector). 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Confirm. ChatGPT reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — no API key is pasted into ChatGPT. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. ChatGPT lists the connector as connected, and the B2Trader tools become available to it. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — ChatGPT receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and ChatGPT stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector appears as connected in ChatGPT's settings. * B2Trader tools are available to ChatGPT in your chats. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In ChatGPT, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). You can connect B2Trader to **Claude** in two places: * **claude.ai** (web and desktop app) — add B2Trader as a **custom connector**. * **Claude Desktop** — add B2Trader as an MCP server; the OAuth sign-in completes through Claude's hosted redirect (`https://claude.ai/api/mcp/auth_callback`). Both use the same B2Trader MCP URL and the same OAuth sign-in. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in Claude's connector directory. ## Connect on claude.ai [#connect-on-claudeai] 1. Open **Settings** → **Connectors** in claude.ai. 2. Click **Add custom connector**. 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Click **Add**. Claude reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — you are **not** pasting an API key into Claude. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. Claude shows the connector as **Connected**, and the B2Trader tools appear in the tool list for your conversations. ## Connect in Claude Desktop [#connect-in-claude-desktop] 1. Open **Claude Desktop** → **Settings** → **Connectors**. 2. Add a new MCP server pointing at the B2Trader MCP URL for your surface. 3. Claude Desktop opens your browser for OAuth sign-in and completes the flow through Claude's **hosted** redirect (`https://claude.ai/api/mcp/auth_callback`), a pre-registered redirect URI. 4. Sign in and — for full access — approve the consent screen. 5. The B2Trader tools appear in Claude Desktop once the connector reports **Connected**. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — Claude receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and Claude stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector is listed as **Connected** in Claude's settings. * B2Trader tools (for example `trader_get_accounts`, plus platform market-data and portfolio tools) are available to Claude in your conversations. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In Claude, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). If you are building your own agent (for example with an Agent SDK) or using an MCP client that is not Claude or ChatGPT, you connect to the same two B2Trader endpoints and the same OAuth flow. This page covers the OAuth details a custom client needs. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` `` is the domain you open your B2Trader terminal on, not a separate API address. ## OAuth discovery [#oauth-discovery] Your client needs no B2Trader-specific configuration beyond the MCP URL. B2Trader is an OAuth 2.1 protected resource and advertises everything a compliant client needs: 1. Your client calls the MCP endpoint without a token and receives `401 Unauthorized` with a `WWW-Authenticate: Bearer resource_metadata="…"` header. 2. That header points at the protected-resource metadata (RFC 9728) for the surface you called — each surface has its own document: `https:///.well-known/oauth-protected-resource/mcp-read-only` and `https:///.well-known/oauth-protected-resource/mcp-full-access`. Fetching it returns the resource identifier, the authorization server (your broker's Keycloak realm), and `scopes_supported` — one scope only, matching the surface: `[mcp:read]` for `/mcp-read-only`, `[mcp:trade]` for `/mcp-full-access`. 3. Your client runs the standard OAuth 2.1 **authorization-code flow with PKCE** against that authorization server, requesting the scope for the surface you want. 4. B2Trader validates the token's audience (`bbp-mcp`) and the required scope (`mcp:read` for read-only, `mcp:trade` for full access) before serving any tool. Use a compliant MCP client library — it performs discovery, PKCE, and token refresh for you. You only supply the MCP URL. ## Pre-registered OAuth clients [#pre-registered-oauth-clients] B2Trader ships two pre-registered public OAuth clients. Use the one matching your surface: | Surface | `client_id` | Scope | Consent | | ----------- | ----------------- | ----------- | ---------------------------- | | Read-only | `mcp-read-only` | `mcp:read` | None | | Full access | `mcp-full-access` | `mcp:trade` | Explicit trade-scope consent | Both are **public** clients (no client secret) and require **PKCE (S256)**. A custom client authenticates as one of these `client_id`s and completes the browser sign-in as any other agent does. Depending on how your broker set up your platform, the page that opens is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account — your client behaves the same either way. ## Command-line agents (Codex CLI, Claude Code) [#command-line-agents-codex-cli-claude-code] Command-line MCP clients default to **Dynamic Client Registration (DCR)** — on first connect they try to register a brand-new OAuth client with the authorization server instead of using a fixed `client_id`. The B2Trader Keycloak realm does not permit anonymous DCR, so these tools must be told to use one of the pre-registered `client_id`s above: * **Codex CLI:** ```bash codex mcp add --url --oauth-client-id mcp-full-access codex mcp login ``` Use `mcp-read-only` in place of `mcp-full-access` for the read-only surface. * **Claude Code:** ```bash claude mcp add --transport http --client-id mcp-full-access --callback-port 8080 ``` Without an explicit `client_id`, both tools fall back to anonymous DCR, which the authorization server rejects — the connection fails before you reach the sign-in page. ## Redirect URIs [#redirect-uris] The pre-registered clients accept these redirect URIs: | Redirect URI | Use | | ------------------------------------------------------- | ----------------------------------------------------- | | `https://claude.ai/api/mcp/auth_callback` | Claude (claude.ai) | | `https://chatgpt.com/connector_platform_oauth_redirect` | ChatGPT | | `http://localhost:8080/*` | Claude Code — fixed callback port | | `http://127.0.0.1/*` | Codex CLI and other loopback clients — ephemeral port | If your custom agent runs locally, use one of the loopback redirects above. Most Agent SDKs and MCP client libraries (including Codex CLI) default to an ephemeral-port loopback callback on `127.0.0.1`, matching `http://127.0.0.1/*`, so no configuration change is needed. Claude Code is the exception: it needs a **fixed** callback port to match a registered redirect, so pass `--callback-port 8080` (matching `http://localhost:8080/*`) as shown above. ## Adding a custom redirect URI (broker step) [#adding-a-custom-redirect-uri-broker-step] If your agent runs on a hosted callback URL that is **not** one of the above (for example a server-side agent with its own public redirect), your broker must add that redirect URI to the pre-registered client in Keycloak before sign-in will succeed. A redirect URI that is not registered on the client fails at the sign-in step with an "Invalid redirect URI" error from Keycloak. Send your broker the exact callback URL your agent uses and which surface it needs (read-only or full access). Adding a redirect URI is a broker-side change to the MCP client registration. It requires no product change and is the documented path for onboarding custom, non-marketplace agents. ## Full access [#full-access] If your custom agent uses the full-access surface, the same [full-access safety](full-access-safety) rules apply: no per-action confirmation, irreversible actions, and the prompt-injection risk of an autonomous agent. Read that page before granting `mcp:trade`. The full-access surface (`/mcp-full-access`) lets a connected AI agent trade on your account **directly**. This page explains exactly what that means and how to stay in control. Read it before you approve the full-access consent screen. Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. ## No per-action confirmation [#no-per-action-confirmation] The in-terminal **AI Assistant chat** asks you to confirm each trade before it executes. The full-access MCP surface does **not**. Once connected, the agent can place, cancel, and close orders and set price triggers on its own, as fast as it decides to — there is no confirmation dialog and no "are you sure?" step. ## Actions are irreversible [#actions-are-irreversible] Trades execute against the live market. A filled order, a closed position, or a cancelled order **cannot be undone**. If your agent makes a mistake — or is manipulated into one — the market result stands. ## Prompt-injection risk [#prompt-injection-risk] An autonomous agent acts on the text it reads. If your agent processes untrusted content — a web page, an email, a chat message, a document — that content can contain hidden instructions telling the agent to trade against your interest. This is called **prompt injection**. Because the full-access surface has no confirmation gate, a successful injection can move real money before you notice. To reduce the risk: * Prefer the **read-only** surface unless you specifically need the agent to trade. * Only grant full access to agents and workflows you trust and control. * Be cautious about letting a full-access agent read untrusted external content in the same session it can trade. ## How to stop your agent [#how-to-stop-your-agent] You have two independent controls. Use either — or both. 1. **Stop it in the agent (fastest).** Disconnect or remove the B2Trader connector in your agent (Claude, ChatGPT, or your custom client). The agent immediately stops making new calls. 2. **Revoke the grant in B2Trader.** Open your **account console** (your broker's Keycloak account page) → **Applications**, find the connected MCP application, and **revoke** its access. This removes your consent so the agent cannot obtain a new token. There is no broker-side "kill switch" that instantly voids a token already in the agent's hands. A token the agent already holds stays valid until it expires (see [Access tokens are short-lived](#access-tokens-are-short-lived)). Revoking in the account console stops **new** tokens; disconnecting in the agent stops it using the one it has. Do both to be certain. ## You still get execution notifications [#you-still-get-execution-notifications] Every order the agent places, cancels, or closes fires the **same account notifications** you already receive for terminal activity. Your normal notification channels keep working, so a full-access agent cannot act silently — watch them to see what your agent is doing. ## Access tokens are short-lived [#access-tokens-are-short-lived] The agent's access token has a **short lifetime**. If you revoke consent in the account console, the agent can finish using its current token but cannot get a new one once it expires — so a revoked grant fully lapses within the token's short window, without any forced server-side revocation. ## Choosing read-only instead [#choosing-read-only-instead] If you do not need the agent to trade, connect the **read-only** surface (`/mcp-read-only`) instead. Its tools cannot place or change anything — the trading tools are not part of that surface at all. See [Overview](overview) for the comparison. B2Trader can expose your trading account to external AI agents through the **Model Context Protocol (MCP)** — an open standard that lets AI applications such as Claude and ChatGPT call a defined set of tools on your behalf. Once you connect an agent, it can read your market data and portfolio, and — on the full-access surface — place and manage orders directly. This is different from the **in-terminal AI Assistant chat**, which runs inside the B2Trader terminal and confirms each trade with you before it executes. An external MCP agent runs in *its own* application (Claude, ChatGPT, or your own client) and connects to B2Trader over the internet using your account sign-in. Connecting an AI agent is optional — it's your choice whether to use it. The MCP surfaces are available by default, though your broker can restrict or disable them for your platform. The MCP endpoints live on the same domain you use to open your B2Trader terminal, so wherever these pages show `https:///…`, that means your terminal address — not a separate API address. If a connection URL below doesn't work, contact your broker. ## Two surfaces [#two-surfaces] B2Trader publishes **two** separate MCP endpoints. You choose one when you connect your agent. | | Read-only | Full access | | ------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Endpoint path** | `/mcp-read-only` | `/mcp-full-access` | | **What the agent can do** | View market data, your portfolio, order and position history, and analytics | Everything in read-only **plus** place, cancel, and close orders and set price triggers | | **Tools exposed** | 23 | 39 | | **Trading** | None — mutating tools are not present at all | Full trading, with **no per-action confirmation** | | **OAuth scope** | `mcp:read` | `mcp:trade` | | **Consent screen** | No extra consent | Explicit trade-scope consent (see [Full-access safety](full-access-safety)) | | **Marketplace-listed** | Yes | No — connect by URL | The **read-only** surface is the one listed in AI marketplaces (for example the Claude and ChatGPT connector directories). It is safe to connect broadly: the trading tools are **structurally absent** — the agent cannot see or call them. The **full-access** surface is connected by pasting its URL directly. It grants your agent the ability to trade with no confirmation gate. Read [Full-access safety](full-access-safety) before you connect it. ## Tool categories [#tool-categories] Both surfaces expose the same read tools; the full-access surface adds the mutating ones. | Category | Read-only | Full access | | ------------------------------------------------------------------------------ | --------- | ----------- | | Market data — B2Trader platform prices (tickers, order book, market summaries) | Yes | Yes | | Portfolio & account (balances, margin, open positions) | Yes | Yes | | Order & position history | Yes | Yes | | Analytics & reference data | Yes | Yes | | Place / cancel / close orders (single) | No | Yes | | Bulk order / position actions | No | Yes | | Set & edit price triggers, other account mutations | No | Yes | | **Total tools** | **23** | **39** | The 16 tools that the full-access surface adds are the mutating actions: single trading actions, bulk trading actions, and non-trading account mutations. ## Which surface to choose [#which-surface-to-choose] * **Choose read-only** if you want an agent to analyze markets, summarize your portfolio, or answer questions about your trading history. This is the recommended default and the safest option. * **Choose full access** only if you deliberately want your agent to trade for you without confirming each action, and you understand the risks in [Full-access safety](full-access-safety). ## Prerequisites [#prerequisites] Before connecting any agent you need: * A **B2Trader account** on a platform that offers the MCP surfaces. They are available by default; a broker can restrict or disable them. * Your account must be **active** (`bbp.spot.status = Active`) — the same status required to trade in the terminal. A non-active account can sign in, but its tool calls are rejected by the platform. * An AI application that supports MCP with OAuth — for example [Claude](connect-claude), [ChatGPT](connect-chatgpt), or a [custom agent](connect-custom-agent). ## How connecting works [#how-connecting-works] You never paste an API key or password into your agent. Connection uses **OAuth 2.1 with PKCE**: 1. You add the B2Trader MCP URL to your agent. 2. The agent discovers B2Trader's authorization server automatically — it reads the endpoint's protected-resource metadata at `/.well-known/oauth-protected-resource/mcp-read-only` or `/.well-known/oauth-protected-resource/mcp-full-access`, depending on the surface. 3. Your browser opens the sign-in page for your platform, where you sign in with the credentials you normally use. 4. For the full-access surface, you approve an explicit consent screen describing what the agent may do. 5. The agent receives a short-lived access token and is connected. No long-lived secret is stored in the agent. The sign-in page you see depends on how your broker set up your platform: either the B2Trader sign-in form, or the sign-in page of the portal you normally use to access your account, which opens automatically. If you are already signed in there in the same browser, no sign-in prompt appears. The per-client steps are covered in the connection guides: * [Connect Claude](connect-claude) * [Connect ChatGPT](connect-chatgpt) * [Connect a custom agent](connect-custom-agent) * [Full-access safety](full-access-safety) ## Global interface controls [#global-interface-controls] ### Account selection [#account-selection] The **Account select** is located in the topbar and enables you to switch between your trading accounts. Each account shows its type: `H` (Hedging) or `N` (Netting). Once you switch the account, all the widgets automatically adjust to show relevant information for the selected account. Account select #### Account status [#account-status] An account can have a status that limits what you can do with it. When a status applies, a status indicator is shown on the account, and a banner explains the restriction. Account status is managed by your administrator. The following statuses are visible to you: * **Halted**: A banner reads *Account is locked for trading. Contact your administrator.* The trading controls are disabled, but you can still deposit and withdraw funds, and your balances, positions, and history stay visible. * **Frozen**: A banner reads *Account is frozen. Contact your administrator.* The account is view-only. All controls are disabled, while your balances, positions, and history stay visible. To restore trading on an account that is Halted or Frozen, contact your administrator. Archived accounts don't appear in the account list. ### Instrument selection [#instrument-selection] The **Instrument select** is located in the topbar and enables you to switch between various markets and trading pairs. Once you change the market, all the widgets automatically adjust to show relevant information for the selected instrument. Instrument select #### Favorite markets [#favorite-markets] Mark instruments as favorites for quick access. To add or remove a market from favorites, click the **star icon** next to the market name in the instrument selection list. Favorite markets can be accessed in two ways: * **Favorites tab** in the instrument selection panel — filters the list to show only your favorite markets. * **Favorites dropdown** in the topbar — provides quick access to favorite markets from anywhere in the terminal. ### Settings [#settings] Use this control to access interface and system settings. Refer to [Settings](settings) for details. Settings ### Other controls [#other-controls] * **Introduction tour**: Access the interactive platform walkthrough. Introduction tour * **Alerts**: View new system notifications. Unread alerts * **Analytics**: Open the **Account Analytics** view with the **Equity Curve** chart — your account balance and equity dynamics over time (Margin Balance, Equity, Total Equity, Unrealized PnL, Deposits / Withdrawals) for a selected period and granularity. The data updates hourly. Click **Back to Trading** to return to the terminal. Analytics * **Log out**: Log out of the system to securely terminate the session. After that you’re navigated to the Login page. Log out ## Working with widgets [#working-with-widgets] > For more information about available widgets, refer to the **Widgets** section of this guide. ### Add widgets to your workspace [#add-widgets-to-your-workspace] **To add a new widget**: 1. Click the **Add Widget** button. 2. Browse the available widgets. 3. Click any widget to add it to your workspace. Add Widget **To add widgets to existing panels**: 1. Look for the **+** button next to the tabs in a panel's header. 2. Click it to open the widget catalog. 3. Select a widget to add it as a new tab to that panel. Add widget tabs ### Move and position widgets [#move-and-position-widgets] **To move a widget**: 1. Click and hold the **move handle** in the top-right corner of the panel header. 2. Drag it to desired location on the page. 3. Drop it. Move widgets **To rearrange widget tabs within a panel**: 1. Click and hold any widget tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ### Resize widgets [#resize-widgets] **To resize a widget panel**: * **Single edge**: Hover over any edge until you see the resize cursor, then drag. * **Corner resize**: Drag a corner to adjust both width and height simultaneously. * **Precision**: Use edge dragging for fine-tuned sizing. Resize widgets ### Remove widgets and tabs [#remove-widgets-and-tabs] **To remove a tab**: 1. Click the **×** button in the top-right corner of the widget tab. 2. The tab will be removed immediately. 3. When you remove the last tab from a panel, the entire panel disappears. Remove tabs and widget panels ### Link panels to a group [#link-panels-to-a-group] Each panel header has a **Link to group** button — the circle icon **next to the move handle** in the top-right corner. Linking panels to the same colored group keeps them in sync: when you select an instrument in one linked panel, the other panels in the same group switch to it automatically. **To link a panel to a group**: 1. Click the **Link to group** button (next to the move handle) in the panel's top-right corner. 2. Select one of the color groups (Group 1–5). 3. Repeat for other panels, choosing the same group to keep them synchronized. Link to group ### Customize widget content [#customize-widget-content] Certain widgets let you customize which columns to display and their order: Look for the **column settings** button in the widget header. **To customize columns**: 1. Click the **column settings** button. 2. **Show/hide columns**: Check or uncheck boxes (grayed-out columns are required). 3. **Reorder columns**: Drag and drop items in the list. 4. **Reset**: Click *Reset to default* to restore original settings. Configure columns ## Managing workspaces [#managing-workspaces] ### Create new workspaces [#create-new-workspaces] **To create a workspace**: 1. Click the **+** tab next to your existing workspaces. 2. Choose a template: * **Pre-built templates**: Start with common widget combinations. * **Empty**: Build completely from scratch. 3. Enter a name for your workspace. 4. Start customizing. Add a new workspace ### Workspace management [#workspace-management] **To rename or delete a workspace**: 1. Click the menu icon on the workspace tab. 2. Select **Rename** or **Remove**. Workspace menu **To reorder workspaces**: 1. Click and hold any workspace tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ## Market info panel [#market-info-panel] Click the **info icon** next to a market symbol in widgets to view: * Detailed market information. * Trading session schedules. * Leverage details (for CFD and PF markets). * Fee details. * Funding details (for PF markets). Market info ## Pro tips [#pro-tips] ### Efficient layout building [#efficient-layout-building] * Start with a template that is close to your needs, then customize. * Group related widgets in tabs to save screen space. * Use larger panels for charts, smaller ones for order books. ### Layout best practices [#layout-best-practices] * **Save multiple workspaces** for different trading strategies. * **Test your layout** during low-activity periods. * **Keep essential widgets visible** (account info, positions, alerts). Access settings by clicking the **gear icon** in the topbar of the Trading terminal. Settings Settings are organized into tabs: * [Interface](#interface): Configure language, time display, and visual theme. * [Widgets](#widgets): Customize widget display options. * [Action Confirmation](#action-confirmation): Choose which actions require additional confirmation. * [Account margin](#account-margin): Manage collateral assets for margin trading. * [Trading report](#trading-report): Generate comprehensive trading and account reports. * [API token management](#api-token-management): Generate and manage tokens for accessing the Trading API. * [TradingView Webhooks](#tradingview-webhooks): Configure TradingView webhook alerts for automated order execution. ## Interface [#interface] Configure global interface preferences: **Language** Select the interface language from the dropdown menu. **24 hour mode** * Enable: Display time in 24-hour format. * Disable: Display time in 12-hour format with AM/PM. **Dark theme** * Enable: Apply dark color scheme. * Disable: Apply light color scheme. ## Widgets [#widgets] Configure display options for the following widgets. ### Price chart [#price-chart] **Display positions** When enabled, open positions are shown on the chart along with: * Position size and current PnL. * Quick access to edit price triggers and close positions. * Color coding: Long positions (green), Short positions (red). **Display orders and triggers** When enabled, the following orders and triggers are displayed on the chart: * Active Limit and Stop orders with order type, price, and amount. * Stop loss, Take profit, and Trailing stop triggers. * Quick access to edit triggers and cancel orders. * Color coding: Buy orders (green), Sell orders (red). **Display executed orders** When enabled, executed orders are shown on the chart with order type indicators: * Green `B` tag for Buy orders. * Red `S` tag for Sell orders. Clicking `B` or `S` will open details of one or more orders that were executed during the candle interval. **Market quick trade panel** When enabled, a panel is displayed on the chart for placing Market orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. **Limit quick trade panel** When enabled, a panel is displayed on the chart for placing Limit orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. ## Action Confirmation [#action-confirmation] Choose which trading actions require an additional confirmation dialog before execution. **Cancel orders** * Enable: A confirmation dialog is displayed before canceling orders. * Disable: Orders are canceled immediately without confirmation. This setting applies to single and bulk order cancellations from the **Open Orders** widget and the **Price chart**. The confirmation dialog includes a **"Don't ask again"** checkbox. To skip the confirmation for future order cancellations, check this box. **Full Close Positions** * Enable: A confirmation dialog is displayed before closing positions. * Disable: Positions are closed immediately without confirmation. This setting applies to single and bulk position closures from the **Open Positions** widget. **Limit order cross-TOB warning** * Enable: A confirmation dialog is displayed before a Limit order is submitted if its price crosses the current top-of-book — that is, when a Buy price is at or above the best ask, or a Sell price is at or below the best bid. The dialog shows the entered price and the current best bid/ask, and includes a **Do not show this warning again** checkbox. * Disable: Crossing Limit orders are submitted immediately without the warning. The warning is enabled by default. The dialog checkbox and this toggle share the same global setting and stay in sync. The warning is informational only — it does not block the order. If you confirm, the order is submitted with the original price. The warning applies only to standard Limit orders; Stop-limit, Take-profit-limit, IOC, FOK, and other order types are not affected. If best bid or best ask data is unavailable (empty book or disconnected feed), the order is submitted without the warning. ## Account margin [#account-margin] Control which assets can be used as collateral for margin trading. ### Asset list [#asset-list] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance available for trading, calculated as *Total – Halted*, where *Halted* represents funds locked for pending Limit orders. *** **Total** The complete asset balance including locked funds. *** **Margin ratio** The percentage of asset value that can be used as collateral for margin trading. *** **Use as margin** Enable this toggle to use the asset as collateral for margin trading. Configure which assets can be used as collateral for margin trading by toggling the **Use as margin** setting for each asset. Only assets with **Margin ratio** greater than 0 (zero) can be enabled. The platform root asset is enabled by default and can't be disabled. ### Filtering options [#filtering-options] Click the **funnel icon** to configure the asset list display: * **Show/Hide zero balances**: Control visibility of assets with zero balance. By default, hidden. * **Show/Hide assets unused as margin**: Control visibility of assets with disabled margin usage. * **Show/Hide assets with zero margin ratio**: Control visibility of assets that can't be used as collateral. By default, hidden. ## Trading report [#trading-report] Generate comprehensive reports containing: * **Trade history** * Closed positions * Executed orders * Individual trades * **Transfers history** * All account transfers * **Account statistics** * Total balance * Realized PnL * Position swaps * Position funding * Commissions To generate a report: 1. Select a custom period of time (UTC time), or generate a report for your entire account history using the **All data** range. The following timeframe presets have been implemented for your convenience: * **Today** * **Current**: week, month, quarter * **Previous**: week, month, quarter * **All data**. 2. Click **Download**. Once generated, the report will be automatically downloaded to your computer as a zipped CSV file. ## API token management [#api-token-management] Generate tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/): * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time To generate a token: 1. Click **+ Create new**. 2. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 3. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ## TradingView Webhooks [#tradingview-webhooks] Use TradingView Webhooks to automatically execute orders on your trading account based on alerts from TradingView. When a TradingView alert triggers, it sends a webhook request to B2TRADER, which places an order according to the parameters specified in the alert message. This feature supports all market types: Spot, CFD, and Perpetual Futures. ### Set up the webhook [#set-up-the-webhook] #### Step 1: Create a webhook API key [#step-1-create-a-webhook-api-key] To create a webhook API key in the Trading terminal: 1. Click the **gear icon** in the topbar to open Settings. 2. Navigate to the **TradingView Webhooks** tab. 3. Click **+ Create new**. 4. In the popup, fill in a **Name** for the key. 5. Click **Create**. The popup displays the generated API key and the webhook URL. Copy both values and store them securely. The API key is shown only once at creation. It can't be retrieved after closing the popup. The following limits apply: * Maximum 10 active keys per user * Each key is valid for 1 year from creation * Keys can be revoked at any time #### Step 2: Configure the alert in TradingView [#step-2-configure-the-alert-in-tradingview] 1. In TradingView, create a new alert or edit an existing one. 2. In the **Notifications** section, enable **Webhook URL**. 3. Paste the webhook URL copied from the terminal. 4. In the **Message** field, enter the alert body in JSON format (see [Alert message format](#alert-message-format)). 5. Save the alert. When the alert triggers, TradingView sends the message to B2TRADER, and the order is placed automatically. ### Alert message format [#alert-message-format] The alert message is a JSON object with the following fields: | Field | Required | Description | | ----------------- | ----------- | -------------------------------------------------------------------------- | | `apiKey` | Yes | Webhook API key generated in the terminal | | `accountId` | Yes | Trading account ID | | `symbol` | Yes | Market symbol with type prefix (see [Symbol format](#symbol-format)) | | `side` | Yes | Order side: `buy` or `sell` | | `quantity` | Yes | Order quantity in base asset | | `orderType` | No | `market` (default), `limit`, `stop`, or `stop_limit` | | `price` | Conditional | Limit price. Required for `limit` and `stop_limit` orders | | `stopPrice` | Conditional | Stop price. Required for `stop` and `stop_limit` orders | | `leverage` | No | Leverage ratio. Applicable to CFD and Perpetual Futures markets only | | `takeProfit` | No | Take profit trigger price | | `stopLoss` | No | Stop loss trigger price | | `timeInForce` | No | `gtc` (default), `ioc`, `fok`, or `day` | | `comment` | No | Custom comment, up to 256 characters | | `deduplicationId` | No | UUID for idempotency. Duplicates within 5 minutes return a cached response | #### Symbol format [#symbol-format] The symbol must include a market type prefix: | Market type | Prefix | Example | | ----------------- | ------- | --------------- | | Spot | `spot.` | `spot.btc_usdt` | | CFD | `cfd.` | `cfd.eur_usd` | | Perpetual Futures | `perp.` | `perp.btc_usdt` | #### Examples [#examples] **Market buy order (Spot):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01" } ``` **Limit sell order with TP/SL (CFD):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "cfd.eur_usd", "side": "sell", "orderType": "limit", "price": "1.0900", "quantity": "1000", "leverage": "10", "takeProfit": "1.0800", "stopLoss": "1.0950", "timeInForce": "gtc" } ``` ### Manage webhook API keys [#manage-webhook-api-keys] To view or manage your webhook API keys, navigate to **Settings** > **TradingView Webhooks**. The following information is provided about each key: | Column | Description | | ----------- | ----------------------------------------------- | | **Name** | The name assigned to the key at creation | | **Status** | Current key status: Active, Revoked, or Expired | | **Created** | The date and time the key was generated | | **Expires** | The date and time the key expires | To revoke a key, click the **Revoke** button next to the key entry. ### Rate limits [#rate-limits] Webhook requests are limited to 5 requests per second per user. If this limit is exceeded, the request returns a `429` error code and the order isn't placed. ### Troubleshooting [#troubleshooting] The following table describes common error scenarios and their solutions: | Issue | Cause | Solution | | -------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | | `Invalid API key` | The API key is incorrect or wasn't copied in full | Generate a new key and update the TradingView alert | | `API key expired` | The key has passed its 1-year validity period | Generate a new key | | `API key revoked` | The key was manually revoked | Generate a new key | | `Invalid symbol format` | The symbol is missing a market type prefix | Add the prefix: `spot.`, `cfd.`, or `perp.` | | `Price required for limit order` | A `limit` or `stop_limit` order is missing the `price` field | Add the `price` field to the alert message | | `Rate limit exceeded` | More than 5 requests were sent within 1 second | Reduce the alert frequency in TradingView | | `Account not found` | The `accountId` doesn't exist or isn't accessible | Verify the account ID in the terminal | A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to limit and stop limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to limit and stop limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the BP, without taking into account the time settings of the devices from which the BP is accessed. ## iOS v1.35 [#ios-v135] This version includes: * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. Select a time period and granularity level to filter performance data, and switch between accounts using the built-in account selector. * **AI Assistant** A new **AI Assistant** widget provides AI-powered market analysis for each instrument, including trade recommendations, market sentiment, signal drivers, suggested actions, and key metrics. * **Quick order from the chart** You can now place orders directly from the **Price chart** by tapping a price pin. The **Quick Order** panel opens pre-filled at the selected price level for faster order placement. * **Customizable workspace** You can now reorder and show or hide bottom tabs in **Settings**, allowing you to tailor the terminal layout to your trading preferences. * **Adaptive interface by market type** Tabs, **Margin Level**, and perpetual funding indicators are now automatically hidden for accounts that do not have access to the corresponding market types, providing a cleaner and more focused interface. * **Landscape mode for the chart** Tapping the **Expand** button on the **Price chart** now automatically rotates the chart to landscape mode for a wider view. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.34 [#ios-v134] This version includes: * **Drag Take Profit and Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be adjusted by dragging their lines directly on the **Price chart**. Changes are applied to the order immediately, with automatic rollback if an error occurs. * **Demo accounts** Demo trading accounts are now supported, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets appear as chips in the market list and are indicated with an icon in the terminal. * **Credit in margin details** A dedicated **Credit** row has been added to the margin details section, providing visibility into credit amounts allocated to your trading account. * **Comments for orders, positions, and trades** You can now add a comment when placing an order or managing a position. The comment is visible throughout the trading lifecycle — on open orders, open positions, and in trade history. * **Margin Level display** When **Margin Level** data is unavailable, the field now displays "–" instead of 0% for clearer data visibility. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.33 [#ios-v133] This version includes: * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Hide zero balances settings relocated** The **Hide zero balances** toggle has been moved to the **Assets** tab for more intuitive access. * **Improved backend error messages** Backend error messages are now mapped to user-friendly descriptions, providing clearer feedback when issues occur. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.32 [#ios-v132] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Quick cancel button for open orders** The **Open orders** widget now features a quick **Cancel** button on each order card, enabling faster order cancellation directly from the list view. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Redesigned account selection header** The account selection section in the terminal header has been redesigned for improved navigation and a cleaner appearance. * **Updated closed positions design** The **Closed positions** widget has been updated with a refreshed layout for better readability and consistency with other trading widgets. * **Confirmation bottom sheet** Order and position actions now display a confirmation bottom sheet, helping to prevent accidental trades and providing a clearer review step before execution. * **Settings button relocated** The **Settings** button has been moved from the **Price chart** widget to the terminal header for easier access across all views. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.31 [#ios-v131] This version includes: Experience an advanced trading workflow with the introduction of our new **tiered leverage system**, offering dynamic leverage based on position size and enhanced margin visibility. This update also brings improved commission transparency with a dedicated Fees tab, enhanced market info, a new deposit shortcut, and updated screens for tiered commissions. We've also refined formatters to respect your selected app language for a more consistent experience. *** ## iOS v1.30 [#ios-v130] This version includes: * **Notifications widget** A new **Notifications** widget has been implemented providing quick access to system notifications related to price changes, Margin calls, Stop outs, Take profit and Stop loss triggers. * **Closing open positions from the Price chart** Open positions can now be closed directly on the **Price chart** screen ensuring quick reaction to volatile market conditions and efficient trade management. This feature is available if the **Display positions** setting is activated for the Price chart. * **Closing all open positions** The **Open positions** tab now features the **Close all** button that liquidates all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Canceling all active orders** The **Open orders** tab now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * **Trading session status** The **Trading session status** in the **Position details** is now accompanied by an info icon and an explanatory tooltip. * **Automatic horizontal scrolling for tabs** The horizontal auto scroll has been added to tabs. Active tabs are now automatically centered for optimal visibility and better accessibility to all available tabs. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.29 [#ios-v129] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding**/**Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Updated account creation process** When creating a trading account in the app, the **account type** can now be selected: **Hedging** or **Netting**, enabling traders to plan and adjust their trading strategies to maximize profit or reduce risk. Depending on the platform settings, the option may be prefilled or require manual selection. The account type can’t be changed after the account is created. * **Support for Take Profit, Stop Loss, and Trailing Stop** The **Take Profit**, **Stop Loss**, and **Trailing Stop** triggers are now supported in the app for CFD and PF trading. They can be applied to Market, Limit, and Stop orders, as well as to currently open positions. * **Support for price alerts** Price alerts are now fully supported in the app: * Multiple alerts can be added to monitor different price levels for any instrument. * Configure alerts based on a fixed price or a percentage change. * View a list of all configured alerts for each instrument. * Adjust or delete existing alerts as needed. * Triggered alerts are automatically removed to keep the list up to date. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order history widget. * **Admin-managed orders and positions** On the **Open positions**, **Closed positions**, and **Order history** widgets, if BP Admins have managed positions or orders, this is now indicated in the **Reason** field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, mitigate risks, or resolve outstanding positions before account termination. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.28 [#ios-v128] This version includes: * **Performance upgrade** Streamlined top-of-the-book ask and bid prices in the Place Order widget are now received through a dedicated socket for faster obtaining and display. * **Mobile and Web Consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** Placeholders are now displayed for empty fields and widgets for improved UX clarity. * **Internal improvements** Enhanced system logs for better diagnostics. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## Android v2.12.0 [#android-v2120] This version includes: * **AI Assistant** A new **AI Assistant** provides AI-powered market analysis for each market, including trade recommendations, a 12-month price forecast, market sentiment, signal drivers, suggested actions, and key metrics. * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. * **Account status indicators** Account statuses such as **Halted** and **Frozen** are now shown with badges and a warning banner, and the related trading actions are restricted accordingly. * **Quick order from the chart** You can now place orders directly from the **Price chart**, enabling faster reaction to market movements. * **Take Profit / Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be set by dragging their lines directly on the **Price chart**, with support for trailing Stop Loss. * **Cross-price limit order warning** A warning is now displayed before you place a **Limit** order whose price crosses the top of the **Order book**. This warning can be enabled or disabled in **Settings**. * **Customizable trading terminal** You can now customize the trading terminal layout and tab order from the new **Workspace** settings. * **Adaptive interface by market type** Margin- and perpetual-related tabs and indicators are now hidden for accounts with access to **Spot** markets only, providing a cleaner interface tailored to the account type. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.11.0 [#android-v2110] This version includes: * **Comment field in Place Order** An optional **Comment** field has been added to the **Place order** form in **Advanced Mode**. The field supports up to 100 characters and is available for all order types across Spot, CFD, and Perpetual markets. * **Full-screen chart mode** The **Price chart** widget now supports full-screen mode. Tap the **Expand** button to switch to a landscape view for a more detailed chart analysis. * **Credit information in margin details** A **Credit** row has been added to the margin section, providing visibility into credit amounts allocated to trading accounts. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.10.0 [#android-v2100] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Demo accounts** Demo trading accounts are now supported in the app, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets are synchronized between the web and mobile terminals. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Improved market status display** The **Market Closed** label is now automatically removed once live data starts updating, providing a more accurate representation of market availability. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.9.0 [#android-v290] This version includes: This update introduces the new **tiered leverage system**, enhanced fee transparency and fully redesigned Fees tab, quick Deposit/Trade shortcuts on account cards for faster navigation and various UI improvements across the app. *** ## Android v2.8.0 [#android-v280] This version includes: * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.7.0 [#android-v270] This version includes: * **Key position parameters on the TP/SL editing** Key position parameters, such as **Name**, **Side**, **Amount**, **Open price**, **Current price**, and **Leverage** are displayed at the top of the Take Profit/Stop Loss configuration screen to give you immediate, accurate context and reduce input errors. Values are updated in real time. * **Closing positions on the Price chart** You can now close positions directly on the **Price chart** widget, by tapping a position indicator. * **Canceling all active orders** The **Open orders** widget now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Closing all open positions** The **Open positions** widget now features the **Close all** button allowing to liquidate all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Closed position details** The **Order type** and **Time in force** values are now displayed for every closed position to improve trade execution transparency. * **Price chart settings saved** The **Price chart** widget now remembers your preferred timeframe and chart type settings. Each time you open the terminal, it displays the chart with your last selected settings. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.6.0 [#android-v260] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding/Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order History widget. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * Expanded capabilities for account administration and risk management for Brokers have been added. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.5.0 [#android-v250] This version includes: * **Stop Loss and Take Profit on the Price chart widget** * Introduction of Stop-Loss (SL) and Take-Profit (TP) lines on the Price chart for enhanced trading insights. * TP and SL are displayed as color-coded lines with only abbreviations visible. * Tap to view prices on the Y-axis and access deletion options. * **Full support for price alerts in the app** * Alerts can be set for specific price levels. * Alerts can be configured based on either a set price or a percentage change. * A list of configured alerts is available for each instrument. * Options to delete or adjust alerts are provided. * Triggered alerts are automatically removed from the list. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.4.0 [#android-v240] This version includes: * **New mobile features** * Introduction of Take Profit, Stop Loss, and Trailing Stop functionalities in the Mobile app. * Support for Netting accounts in the Mobile app. * **Mobile and Web consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** For order lists, the All/Spot/CFD filter is only displayed when there are both Spot and CFD orders, for improved UX clarity. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## June 10, 2026 [#june-10-2026] ### New features [#new-features] #### Guest mode [#guest-mode] A new **Guest mode** lets you explore the Trading terminal without signing in. As a guest you can browse markets and market categories, follow live price streams and interactive charts, and open the **AI Assistant** widget for market analysis. A dedicated guest workspace is provided, and the [Place order](../widgets/place-order) panel opens in the advanced view by default. A **Sign in** action is always available so you can switch to a full trading session at any time. ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Full account history in Trading reports [#full-account-history-in-trading-reports] You can now generate [Trading reports](../get-started/settings) for your entire account history. The previous **92-day** limit has been removed, and a new **All data** range has been added to the report period selector alongside the existing presets. #### Stop orders during closed market sessions [#stop-orders-during-closed-market-sessions] You can now place **Stop** orders while a market is closed according to its trading schedule. The order is accepted and activates automatically once the market reopens, instead of being rejected at placement. #### More accurate unrealized PnL [#more-accurate-unrealized-pnl] Unrealized PnL is now calculated using the correct order book side for each position direction, improving the accuracy of the PnL shown across your widgets. #### Limit price crossing warning [#limit-price-crossing-warning] When you place a limit order at a price that crosses the current top of book, the terminal now shows a warning, helping you avoid an unintended immediate execution. ## April 9, 2026 [#april-9-2026] ### New features [#new-features-1] #### Trading credit [#trading-credit] Your broker can now grant you **trading credit** — a promotional bonus balance you can use for trading. Credit appears as a separate **Credit Balance** alongside your own funds and becomes available for placing trades immediately upon issuance. You are notified when credit is granted or revoked. Trading credit is a trading-only bonus and cannot be withdrawn as cash, so it is excluded from your withdrawable balance. *** ### Improvements [#improvements-1] #### Fee-aware 100% allocation [#fee-aware-100-allocation] The **100%** button in the [Place order](../widgets/place-order) widget now accounts for commissions and margin requirements when allocating funds, so the calculated amount reflects what is actually available for the trade. #### Faster price updates [#faster-price-updates] The price update frequency in terminal widgets has been increased, providing more responsive market data across your workspace. ## March 18, 2026 [#march-18-2026] ### New features [#new-features-2] #### Webhook API for TradingView alerts [#webhook-api-for-tradingview-alerts] A new **Webhook API** has been added, enabling you to connect **TradingView** alerts to your trading workflow. You can generate and copy authentication tokens directly from the Trading terminal to configure webhook-based alerts in **TradingView**. *** ### Resolved issues [#resolved-issues] There have been no customer-facing issues reported in this release. ## March 3, 2026 [#march-3-2026] ### New features [#new-features-3] #### Long-term trading data history [#long-term-trading-data-history] The three-month limit on trading data history has been removed. You can now access the full history of your orders, positions, and trades without time restrictions, enabling deeper analysis of past trading activity. #### AI Assistant widget [#ai-assistant-widget] A new **AI Assistant** widget is now available in the Trading terminal. The widget provides AI-powered market analysis for the selected instrument, including: * A recommendation gauge displaying a score from **Strong Sell** to **Strong Buy** * A 12-month price forecast with target price and percentage change * A market sentiment bar showing the bullish/bearish ratio * Signal drivers section with technical, on-chain, and sentiment factors * Suggested trading actions and key market metrics The widget can be added to any workspace like other terminal widgets. *** ### Improvements [#improvements-2] #### Updated order cancellation confirmation [#updated-order-cancellation-confirmation] The order cancellation confirmation dialog now includes a **Don't ask again** checkbox when canceling triggers from the **TradingView** chart. This allows you to skip the confirmation step for future trigger cancellations, streamlining the trading workflow. *** ### Resolved issues [#resolved-issues-1] There have been no customer-facing issues reported in this release. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-4] #### Redesigned Market Depth widget [#redesigned-market-depth-widget] The [Market Depth](../widgets/market-depth) widget has been completely redesigned with an updated visual layout. Bid and ask labels are now displayed when hovering over a price level, providing better visibility into the order book at a glance. #### Redesigned widget adding experience [#redesigned-widget-adding-experience] The process of adding widgets to workspaces has been redesigned with a more intuitive and streamlined flow. The new interface makes it easier to customize your trading workspace layout by providing a clearer visual selection of available widgets. #### Order and position comments [#order-and-position-comments] A new **Comment** field has been added to orders, positions, and trades throughout the Trading terminal. You can now attach notes directly to your trading activities, making it easier to annotate trading decisions and keep records of your reasoning. #### Favorites [#favorites] You can now mark instruments as favorites for quick access across the Trading terminal. The [Favorite markets](../get-started/customizing-your-terminal#favorite-markets) feature integrates with the instrument selection panel, making it faster to locate and trade your preferred instruments. #### Multi-language support [#multi-language-support] The Trading terminal now supports additional languages: **Chinese (Simplified)**, **Spanish**, **Portuguese**, **French**, **Turkish**, and **Farsi**. Existing translations have also been updated to reflect the latest interface changes. *** ### Improvements [#improvements-3] #### Updated order calculations [#updated-order-calculations] The **Value** and **Amount** calculation logic has been improved for more accurate order handling: * For **Stop Market** orders, the estimated values are now calculated using updated formulas that align with the actual execution logic. * For **Spot** market orders, the **Slippage Rate** is now correctly applied only to buy orders and has been removed from sell order calculations. * The **Slippage Rate** attribute has been removed from **CFD** and **PF** market forms and information displays, as it is not applicable to these market types. #### Improved TP/SL trigger management [#improved-tpsl-trigger-management] Removing Take Profit and Stop Loss triggers is now easier in the TradingView charting widget. Instead of opening a dialog and unchecking the trigger, you can now click the close button directly on the trigger to remove it immediately. #### Updated default columns [#updated-default-columns] The default columns displayed in the [Open positions](../widgets/open-positions) and [Open orders](../widgets/open-orders) widgets have been updated to show the most relevant information by default, reducing the need for manual customization. #### Account margin value formatting [#account-margin-value-formatting] Account margin values such as **Balance**, **Equity**, **Margin**, and **Free margin** in the [Margin](../widgets/margin) widget are now formatted according to the **Root Asset Scale**. This ensures that numerical precision matches the asset's defined scale, eliminating misleading decimal places. #### Updated Settings experience [#updated-settings-experience] The [Settings](../get-started/settings) experience has been improved: * The **Action Confirmation** section text has been rewritten for clarity. The description now reads: "Choose which actions will require additional confirmation," making the toggle behavior immediately clear. * The **One-click trading** configuration has been updated with improved toggle controls and clearer options for enabling or disabling confirmation dialogs on trading actions. #### Improved order validation [#improved-order-validation] Order validation logic has been updated across the Trading terminal, providing clearer feedback on invalid inputs and reducing errors during order placement and management. #### Workspace tab styling [#workspace-tab-styling] Visual improvements have been applied to workspace tabs: gaps have been added between tabs for better visual separation, tab padding has been corrected, and hovered tabs now display a proper card-style fill matching the updated design system. ## December 19, 2025 [#december-19-2025] ### New features [#new-features-5] #### Volume-based tiered commissions [#volume-based-tiered-commissions] You can now benefit from **volume-based commission tiers** that automatically reduce your trading fees as your monthly volume grows. **Key points**: * **Trade more, pay less**: For markets with tiered fees, your 30‑day trading volume (in the root asset, for example USD) is tracked across all markets included in the same group. As you move into higher tiers, your commission percentage decreases. * **Clear fee overview**: Open [Market info](../get-started/customizing-your-terminal#market-info-panel) and switch to the **Fees** tab to see your **Current volume** for the month, the configured **Min. fee**, and the full **Commission tiers** table with volume ranges and fee %. A check mark highlights the tier you are currently in. * **Grouped volume**: Your traded volume is aggregated across markets to which the dynamic commission is applied. * **No surprises**: Orders on markets without tiered fees continue to use the existing flat commission model. Tiered markets simply adjust your fee according to the tier that matches your current trading volume. #### New settings [#new-settings] The [Settings](../get-started/settings) menu has been enriched with the following configuration options: * **Widgets**: This updated section now provides access to multiple widgets’ display settings. Along with existing [Price chart](../widgets/price-chart), you can now configure: * One-click trading for [Open positions](../widgets/open-positions): When enabled, single and bulk position closing are executed immediately, without going through additional confirmation dialogs. * One-click trading for [Open orders](../widgets/open-orders): When enabled, single and bulk order cancellations are executed immediately, without going through additional confirmation dialogs. * **API token management**: This new section allows you to generate and manage tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/). Up to 10 tokens can be generated per account. The validity period for each token is one year. The tokens can be revoked or deleted anytime. *** ### Improvements [#improvements-4] #### Responsive widget layout [#responsive-widget-layout] Widget content now adapts dynamically to the available space, ensuring that key information such as primary values, titles, and critical actions remains visible even when widgets are resized or minimized. Layouts have been refined to avoid unnecessary empty areas while preventing clipping of important elements, delivering a more readable and informative experience across all widget sizes. #### Clearer margin level display [#clearer-margin-level-display] The [Margin](../widgets/margin) widget has been updated to provide a clearer signal. Now, whenever no margin is used (for example, when you have no open positions), the **used margin** value displays **–** instead of 0%. This aligns with common brokerage practices and helps you better understand the current risk state at a glance. #### Smarter default filters for Assets and Account margin [#smarter-default-filters-for-assets-and-account-margin] Certain default filters are now applied automatically when the Trading terminal is opened for the first time. In the [Assets](../widgets/assets) widget, **Hide zero balances** is enabled by default, so assets with zero balance are not shown. In the [Account margin](../get-started/settings#account-margin) settings, **Hide zero balances** and **Hide assets with zero margin ratio** are enabled by default, hiding assets that carry no margin or balance. If you change any of these filters, the platform remembers their states. #### Improved quick trade panels [#improved-quick-trade-panels] The **Market quick trade panel** has been moved not to cover the important controls of the [Price chart](../widgets/price-chart). Additionally, it now displays the **cross icon** to quickly close the panel if needed. *** ### Resolved issues [#resolved-issues-2] There have been no customer-facing issues reported in this release. ## November 7, 2025 [#november-7-2025] ### New features [#new-features-6] #### Tiered leverage system [#tiered-leverage-system] With this release, we're excited to introduce the **tiered leverage system** that provides more sophisticated leverage options based on your position sizes, offering better risk management. **Key points:** * **Dynamic leverage tiers**: Markets can now offer tiered leverage where your maximum available leverage decreases as your position size increases. This allows you to access higher leverage on smaller positions while maintaining appropriate risk controls on larger trades. * **Enhanced market information**: Markets with tiered leverage now display comprehensive leverage information in the **Market info** panel. A new **Leverage** tab shows all available tiers, including the notional value ranges and maximum leverage for each tier. * **Improved position tracking**: Your open positions now display both the leverage you selected when opening the position (**Requested leverage**) and the actual leverage being applied (**Leverage**). Detailed tooltips explain how these values are calculated, giving you better visibility into your margin usage. * **Smart leverage selection**: When placing orders on markets with tiered leverage, the system automatically calculates your margin requirements across all applicable tiers. You can see the exact margin required before placing your order. **How it works** For markets with dynamic leverage, your position is allocated across different tiers based on its notional value. Each tier has its own maximum leverage limit, typically starting with higher leverage for smaller positions and decreasing as position size grows. This allows you to maintain appropriate risk management. **Order placement** When trading on tiered markets, you can still select your preferred leverage (up to the maximum allowed for the first tier), and the system will automatically apply the appropriate leverage limits. The margin calculator shows you the exact requirements before you place your order. All existing positions continue to operate normally with no changes to your current trading experience. Markets without tiered leverage continue to work exactly as before. *** ### Improvements [#improvements-5] #### Improved documentation experience [#improved-documentation-experience] The documentation window is now fully resizable, allowing traders to adjust both vertical and horizontal dimensions independently. All screenshots can now be zoomed, making detailed interface elements clearly visible. #### Streamlined market selection [#streamlined-market-selection] The market selection control is now displayed as the **chevron icon** directly next to the market name in widgets. The magnifying glass icon has been removed. Both the market name and chevron are now clickable and open the market selector. #### Reorganized market information access [#reorganized-market-information-access] The market info popover has been relocated under the **info icon** in the widget header to maintain accessibility while keeping the market name area focused solely on selection functionality, creating a cleaner and more consistent user interface. #### Enhanced workspace tab design [#enhanced-workspace-tab-design] A clear distinction between active and inactive workspace tabs has been achieved due to intuitive styling. Workspace option buttons are now hidden by default to reduce visual clutter and only appear when tabs are active or being hovered over. This applies to both default and custom workspace tabs, creating a cleaner interface while maintaining full functionality when needed. *** ### Resolved issues [#resolved-issues-3] There have been no customer-facing issues reported in this release. ## October 9, 2025 [#october-9-2025] ### New features [#new-features-7] #### Placing orders from the Price chart [#placing-orders-from-the-price-chart] The [Price chart](../widgets/price-chart) widget now supports direct order placement with two new quick trading panels. The **Market quick trade panel** provides a persistent interface for instant buy/sell orders, while the **Limit quick trade panel** allows hover-based order placement at specific price levels. When enabled through **Price chart settings**, both panels offer configurable amount presets and leverage ratio selection for margin trading (when applicable), creating a seamless trading experience without leaving the chart view. #### Bulk order canceling [#bulk-order-canceling] The [Open orders](../widgets/open-orders) widget introduces a **Cancel all** button that closes all active orders simultaneously. This feature provides better risk management capabilities during volatile market conditions. #### In-platform documentation [#in-platform-documentation] User documentation is now integrated directly within the Trading terminal interface. This eliminates the need to switch between applications when accessing help materials or reference guides, keeping essential information readily available during trading sessions. #### New market subtype [#new-market-subtype] The new **Commodities** subtype has been added for CFD markets, enhancing the market categorization system. *** ### Improvements [#improvements-6] #### Enhanced position tracking [#enhanced-position-tracking] A new **Direction** column has been added to **Trades** info in the [Open positions](../widgets/open-positions) and [Closed positions](../widgets/closed-positions) widgets. It indicates whether a position size increased (In) or decreased (Out) as a result of each trade. This enhancement provides clearer visibility into position movement patterns. #### Cross rates calculation precision [#cross-rates-calculation-precision] Accuracy for cross-rate calculations has been improved by introducing a new cross-rate scale parameter. It has a default value of 8 and can be adjusted in configuration files. This addresses the previous limitation where cross rates were rounded to the root asset type scale (typically 2 decimal places), causing incorrect zero values in certain scenarios. The improvement ensures accurate cross-rate calculations across all currency and cryptocurrency pairs, regardless of their relative values. #### Redesigned Settings interface [#redesigned-settings-interface] The **Settings** menu has been restructured with a new tabbed popup interface. Related configuration options are now logically grouped, making settings easier to navigate and manage. #### Pre-filled Limit order price [#pre-filled-limit-order-price] Limit order placement now includes automatic price pre-population using the best bid or ask price from the order book. This static pre-fill reduces manual entry requirements and helps prevent pricing errors during order submission. #### Updated sorting of open positions [#updated-sorting-of-open-positions] [Open positions](../widgets/open-positions) are now sorted chronologically with the newest positions displayed at the top, improving visibility of recent trading activity. #### Improved messages [#improved-messages] User communications have been updated throughout the platform, including improved Introduction tour messaging for better onboarding and clearer system notifications. #### UI enhancements [#ui-enhancements] UI improvements for this release include: * **Support for dynamic resizing of the trading interface layout**: The trading interface now features a responsive layout system that dynamically adjusts to browser window resizing. Widgets automatically scale and reposition to maintain optimal viewing regardless of screen size changes. * **Loader**: [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now display loading indicators when fetching additional data. * **Improved PnL representation**: When displayed on charts, the PnL values are now accompanied by "+" or "–" signs for immediate profit/loss recognition. * **Improved scrollbars**: Scrollbar positioning has been refined to prevent overlay of table content, ensuring all data remains visible and accessible. *** ### Resolved issues [#resolved-issues-4] There have been no customer-facing issues reported in this release. ## July 2, 2025 [#july-2-2025] ### New features [#new-features-8] #### Trading reports [#trading-reports] We've implemented a new feature enabling you to generate trading reports for a specific period of time and download them as zipped CSV files to your computer. The report includes a detailed information on: * **Trade history** * Closed positions * Executed orders * Trades * **Transfers history** * **Account statistics** * Total balance * Realized PnL * Swaps * Funding * Commissions The data is available for any period within the last **92 days** (UTC time). The following timeframe presets have been implemented for your convenience: * Today * Current: week, month, quarter * Previous: week, month, quarter Access the new **Trading report** menu under the **Settings** icon on the topbar of the Trading terminal. *** ### Improvements [#improvements-7] #### Admin-managed orders and positions [#admin-managed-orders-and-positions] In the [Open positions](../widgets/open-positions), [Closed positions](../widgets/closed-positions), and [Order history](../widgets/order-history) widgets, if BP Admins have managed positions or orders, this is now indicated in the Reason field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, and mitigate risks. *** ### Resolved issues [#resolved-issues-5] There have been no customer-facing issues reported in this release. ## May 30, 2025 [#may-30-2025] ### New features [#new-features-9] #### PF trading [#pf-trading] We are excited to introduce **Perpetual Futures (PF) trading** on our platform. These contracts feature a funding fee mechanism based on the Mark price and Funding rate. A positive rate means Long positions pay Shorts, and a negative rate means the reverse. You can see the countdown to the next funding fee settlement in the [Market summary](../widgets/market-summary) widget. This update also includes a new market type — Perpetual — enhancing your trading opportunities. *** ### Improvements [#improvements-8] #### Price chart setting [#price-chart-setting] The [Price chart](../widgets/price-chart) widget now supports displaying of open positions, as well as open and executed orders. Click the **gear icon** in the topbar to access Price chart settings and enable desired options. #### Close all positions [#close-all-positions] The [Open positions](../widgets/open-positions) widget now features a new **Close all** option, offering enhanced management capabilities. This update provides a more efficient way to handle multiple positions by allowing you to simultaneously close: * All open positions * All open positions with positive PnL * All open positions with negative PnL #### Enhanced price control [#enhanced-price-control] The following enhancements have been implemented for the [Price control](../widgets/price-control) widget: * **Editable price alerts**: You can now adjust existing price alerts by clicking a price. * **Enhanced market additions**: Price and percentage fields now automatically open for editing when a new market is added to the widget. * **Visual indicators**: Arrows near price triggers aren’t shown if the price feed is unavailable, reducing clutter and potential confusion. #### Historical data limits [#historical-data-limits] The [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now provide historical data with a limit of **92 days**. *** ### Resolved issues [#resolved-issues-6] There have been no customer-facing issues reported in this release. ## April 17, 2025 [#april-17-2025] ### New features [#new-features-10] #### Netting account type [#netting-account-type] With this release, a new **Netting** account type has been enabled. It intelligently consolidates all orders placed on the same market into a single position. Previously, the system supported only Hedging, where each order opens a separate position. **Key points of netting** * **Reduced margin requirements**: Instead of calculating margin requirements separately for each position, netting combines them, lowering overall capital needs. * **Lower trading costs**: By holding opposing positions, traders often incur double position swaps. Netting treats these positions as one, reducing unnecessary costs. * **Streamlined position management**: Managing multiple positions manually can become complicated, especially when balancing between different trade sizes, directions, leverages and margin requirements. Netting helps with it by combining positions into a single one. **Netting VS Hedging** Netting may sometimes lack the flexibility required for complex hedging strategies. In contrast, hedging excels by allowing traders to hold both long and short positions simultaneously without offsetting them. This enhances the ability to track and adjust individual trades easily while permitting precise margin management for separate positions. The Hedging type is perfectly suited for traders seeking detailed control over their positions. On the other hand, the Netting type ensures simplicity and reduced margin requirements, making it the perfect choice for straightforward trading strategies. **Workflow changes** When opening a new trading account, you must now choose its type: either Hedging or Netting. This choice is permanent and influences all future trades in the account. In the account selection interface, each account displays its type: `H` for Hedging or `N` for Netting. All existing accounts are automatically assigned to the Hedging type. *** ### Improvements [#improvements-9] #### Improved widget control [#improved-widget-control] With this release, you now have enhanced control over the viewing experience: * **Configuring widget columns**: Certain widgets allow you to configure widget columns in a way that best suits your needs, offering you the flexibility to select which columns you wish to display or hide. Additionally, you can arrange the order of these columns for your convenience, ensuring that the information you prioritize is always at your fingertips. * **Rearranging widget tabs**: All widgets now feature drag-and-drop functionality for rearranging tabs effortlessly. This user-friendly feature offers a more customized and organized interface, making it easier than ever to personalize your widget experience. #### Enhanced Order book [#enhanced-order-book] The Order book widget has been upgraded with new customizable settings. This update introduces intuitive controls, empowering you to adjust the widget view according to your preference: * **Full view**: Shows both buy and sell orders along with the market spread. * **Buy only view**: Displays only buy orders and the market spread. * **Sell only view**: Displays only sell orders and the market spread. *** ### Resolved issues [#resolved-issues-7] There have been no customer-facing issues reported in this release. ## January 15, 2025 [#january-15-2025] ### New features [#new-features-11] #### Take profit, Stop loss, Trailing stop [#take-profit-stop-loss-trailing-stop] With this release, the following new triggers for open positions have been implemented on the platform: * **Take profit**: A take-profit trigger is used to close a position automatically once the market hits a predefined price, ensuring the trader locks in profits. * **Stop loss**: A stop-loss order is a trigger to limit potential losses. It automatically closes a position when its price changes to a predetermined level. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified value. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. These settings can be used when trading on CFD markets and can be applied to Market, Limit, and Stop orders, as well as for currently open positions. The new settings can be enabled when placing an order via the [Place order](../widgets/place-order) widget (Advanced mode). Until a position is fully closed, they can also be adjusted or canceled via the [Open positions](../widgets/open-positions) widget. The information about applied settings is also available in the corresponding widgets: [Closed positions](../widgets/closed-positions), [Open orders](../widgets/open-orders), and [Order history](../widgets/order-history). *** ### Resolved issues [#resolved-issues-8] There have been no customer-facing issues reported in this release. *** ## Past releases [#past-releases] ### December, 2024 [#december-2024] #### New features [#new-features-12] ##### CFD trading [#cfd-trading] With this release, we're excited to announce the support for CFD (Contract for Difference) trading on our brokerage platform. This empowers you to trade with dynamic leverage, using your funds as collateral to secure positions confidently. Enjoy the flexibility to go both long and short, capitalizing on both bullish and bearish markets. Our CFD trading support boasts an intuitive interface, robust risk management tools, and real-time data. ##### Innovative market approach and instrument picker [#innovative-market-approach-and-instrument-picker] * **Market type**: Markets are now classified into Spot and CFD, reflecting their differing parameters. A panel indicating CFD or Spot is now included in all widgets. * **Market parameters and trading schedule**: Click a market name to access its key parameters and scheduled trading sessions. * **Market categories**: Now accessible via the top bar, offering a hierarchical view for easier selection and switching between markets. ##### Account margin settings [#account-margin-settings] Access the new [Account margin settings](../get-started/settings) to monitor your balances and configure assets to be used as collateral for CFD trading. ##### Reworked Place order widget [#reworked-place-order-widget] Place any order with a [single widget](../widgets/place-order) now. Choose Quick IOC Market or Stop with adjusted leverage — all conveniently in one place, along with an order summary. ##### Positions [#positions] Discover two new widgets for position monitoring: * [Open positions](../widgets/open-positions): Offers real-time monitoring of currently open positions with price changes, PnL, used margin, and other parameters. * [Closed positions](../widgets/closed-positions): Provides historical data on position details, prices, and realized PnL. ##### Risk management [#risk-management] You now have three essential widgets to maintain control: * [Margin](../widgets/margin): Monitor your margin account parameters in real time and respond swiftly to changes. * [Price control](../widgets/price-control): Set price alerts tailored to your specific needs and parameters. * [Messages](../widgets/messages): Receive system notifications and price alerts directly. ##### Market data [#market-data] Two new widgets have been introduced to enhance market monitoring: * [Market summary](../widgets/market-summary): Provides detailed information and updates on price changes for a specific market. * [All markets](../widgets/all-markets): Displays price change statistics across all markets simultaneously. #### Improvements [#improvements-10] * Performance has increased significantly, allowing each trader to hold up to 1,000 CFD positions open. * Limits have been increased to 3,000 requests per second. #### Resolved issues [#resolved-issues-9] There have been no customer-facing issues reported in this release. *** ### June 20, 2024 [#june-20-2024] #### Improvements [#improvements-11] * Account selection is now available from the topbar of the Trading terminal. Once you change your account, all the widgets will automatically adjust to show relevant information for the selected account. * Tabs are now available in the Trading terminal. You can place up to 10 tabs to open multiple workspaces simultaneously for better information organization. You can utilize pre-configured layouts for your workspaces or create custom ones. *** ### June 13, 2024 [#june-13-2024] #### New features [#new-features-13] ##### iOS mobile application [#ios-mobile-application] With this release, our team is thrilled to announce the launch of the brand-new iOS mobile app. The mobile app is closely integrated with B2CORE mobile. Along with single sign-on implemented, it allows you to seamlessly navigate between the apps, without re-entering credentials. In the mobile app, just like in the web version of the Trading terminal, you can access all of your BP accounts, place orders, monitor market data, and so on. For your convenience, it all can be done in a very similar way as in the web version. A consistent and user-friendly interface makes using the app easy and intuitive. Among the key features and services that the new BP mobile offers: * The account list with detailed balances, to always keep your funds under control. Creation and renaming of accounts, to keep your funds well organized. * Asset balances screen, with the amounts of free and frozen funds specified and with the possibility to hide assets with zero balances. * The Order book and price chart, to monitor and analyze trading data and make buy or sell decisions, with a quick and easy jump to the order placing screen. * Candles and line charts, with easy switching and the possibility to scroll the data for historical values. * Limit & Market order placing, with all time in force options supported in the Web version (Market: IOC, FOK; Limit: IOC, FOK, GTC, GTD, Day). * Open and history orders lists, with easy access to order parameters and details, quick canceling or repeating an order. * Light and dark themes and many more. ### October 18, 2023 [#october-18-2023] #### New features [#new-features-14] With this initial release, our team is happy to announce the launch of our new Trading terminal. ##### Placing orders [#placing-orders] The platform currently supports placing Market, Limit, Stop Market, and Stop Limit orders (refer to [Order types](../knowledge-base/order-types)). You can also choose from various [Time in force](../knowledge-base/time-in-force) options such as FOK, IOC, GTC, GTD, and DAY. ##### Widgets [#widgets] The platform provides you with enhanced widgets that are specifically designed for convenient trading. These widgets allow you to easily place orders, access the Order book, monitor open orders and order history, and much more. Refer to [Place order](../widgets/place-order) and the other pages of the Widgets section for more information. ##### Dashboard [#dashboard] The customizable dashboard allows you to personalize the layout to suit your needs and keep you focused on what's important. Refer to [Interface overview](../get-started/customizing-your-terminal) to learn more about workspace customization. ## Summary [#summary] This widget provides AI-powered market analysis and trading recommendations for the selected market. AI Assistant The widget is organized into the following sections: * [AI Recommendation](#ai-recommendation): Overall recommendation score. * [Forecast](#forecast): Price target and market sentiment. * [Signal Drivers](#signal-drivers): Technical, on-chain, and sentiment signals. * [Suggested Actions](#suggested-actions): AI-generated trading suggestions. * [Key Metrics](#key-metrics): Market data overview. ## AI Recommendation [#ai-recommendation] Displays a numeric score from 0 to 100 representing the overall AI assessment of the market, along with a label such as **Strong Buy**, **Buy**, **Neutral**, **Sell**, or **Strong Sell**. A higher score indicates a more favorable outlook. ## Forecast [#forecast] **1Y Price Target** The forecasted price in one year and the expected percentage change from the current price. *** **Market Sentiment** A visual bar showing the ratio between bullish and bearish sentiment among market participants. ## Signal Drivers [#signal-drivers] Signals that influence the AI recommendation, categorized into three types: * **Technical**: Signals based on technical analysis indicators such as RSI and Moving Averages. * **On-Chain**: Signals based on blockchain data such as ETF inflows, active addresses, and total value locked (TVL). * **Sentiment**: Signals based on community and analyst opinions. Each signal includes a description and an impact assessment: **Bullish**, **Bearish**, or **Neutral**. ## Suggested Actions [#suggested-actions] A list of AI-generated trading suggestions based on the current market conditions. These are informational recommendations, not automated trading signals. ## Key Metrics [#key-metrics] The following market data is displayed: **All-Time High** The highest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **All-Time Low** The lowest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **24h Volume** The total trading volume over the last 24 hours in USD. *** **Market Cap** The total market capitalization of the asset in USD. AI-generated insights are for informational purposes only. The AI Assistant widget can be enabled or disabled by the platform administrator. If the widget isn't available in the **Add Widget** menu, contact your broker. ## Summary [#summary] Use this widget to monitor price data on all markets available on the platform. The widget is dynamic and is continuously updated in real time. All markets ## Fields [#fields] The following information is provided about each market: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current market price, in the quote asset and in the platform root asset. This value is green if the price is rising and red if it's falling. *** **24h change** The price change over the last 24 hours, in absolute and percentage values. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. ## Summary [#summary] This widget displays the list of all asset balances on your account. Assets ## Settings [#settings] ### Hide zero balances [#hide-zero-balances] Use this option to hide all assets with zero balances from the list. It's enabled by default. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance at your disposal, meaning the difference between your total assets and a sum of all limit orders placed by this time. This value is calculated as *Total – Halted*, where *Halted* is the asset amount frozen on the account for execution of placed Limit orders. *** **Available, \{RAT}** The available balance, in conversion to the platform root asset. *** **Total** The overall amount of the asset available in your wallet, including locked funds. *** **Total, \{RAT}** The total balance, in conversion to the platform root asset. ## Summary [#summary] This widget displays a list of your closed positions on the selected account. The entire history of your closed positions is available. Closed positions The widget lists only closed positions. For a list of currently open positions, use the [Open positions](open-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists closed positions for the last three months. To display positions closed during a specific time period, use the **Select date range** field. The most recently closed positions appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related orders [#view-related-orders] Click the **chevron icon** in a position row to expand a list of position-closing orders. As positions can be partially closed, there may be more than one line. For each executed position-closing order, a separate line is added. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Pos. closed size** The closed volume, in lots, which is equivalent to the corresponding filled order volume. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Close price** The volume-weighted average price (VWAP) of trades related to a position-closing order. *** **Close order ID** The identifier of an order closing the position. *** **Realized PnL, \{RAT}** The actual profit or loss earned, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). *** **\{RAT} notional** The equivalent of the closed volume in the platform root asset. *** **History rate to \{RAT}** The rate to the platform root asset at the moment of position closing. *** **Reason** The reason for closing a position. Possible values: * **Trader**: The position was closed by you. * **Admin**: The position was closed by an Admin. * **Stop-out**: The position was automatically closed by the system, as a result of Stop out. * **Stop loss**: The position was closed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The position was closed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The position was closed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. *** **Open date, time** The date and time when a position was opened. *** **Closed date, time** The date and time when a position-closing order was last updated (fully executed). ## Summary [#summary] This widget helps you monitor margin parameters and statistics. Margin ## Fields [#fields] All values are in displayed in conversion to the platform root asset: **Your margin level** The ratio of your funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. Possible values: * **Empty**: No open positions. * **Low risk**: Everything is ok. * **Margin call**: Your margin level fell below the set Margin call value. You received a notification urging you to increase the margin level to avoid a Stop out. Remember that if you ignore this warning, the margin level may continue to decrease. During the Margin call, you can only close existing positions; opening new positions isn’t possible. * **Stop out level**: Your margin level fell below the set Stop out value; the platform started a process of liquidating your positions. This process continues until the margin level exceeds this required value. **ANY** currently open position can be closed regardless of its side and volume. *** **Margin balance** The total amount of your funds that can be used as a collateral for CFD trading. It’s calculated as Σ(*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*), where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the platform root asset. The Margin balance is continually recalculated based on price fluctuations. An increase in the prices of assets boosts available Balance & Free margin. Conversely, a decrease in asset prices may reduce the available Balance and Free margin. Additionally, a decline in the prices of assets with open positions may trigger Margin calls and Stop outs. *** **Credit** A promotional bonus granted by your broker for margin (CFD and Perpetual) trading, shown in the platform root asset (RAT). When you have no credit, this row shows 0. Credit increases your Equity and Free margin and can be used as collateral to open positions. It becomes available immediately when granted and never expires. However, credit cannot be withdrawn as cash, so it is excluded from your withdrawable balance. Your broker can revoke credit at any time, and the row updates in real time when this happens. The row includes an info tooltip that reads: *Promotional credit for margin trading only. Cannot be withdrawn.* *** **Equity** The potential balance of your account if all your positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. *** **Used margin** The amount of funds that is used for maintaining all your open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **Example** **Step 1: Initial balance** * Margin balance: $10,000 * Opened positions: 0 * Free margin: $10,000 * Used margin: $0 **Step 2: Open a long position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 100 = $1,001 * After opening: * Free margin: $8,999 * Used margin: $1,001 **Step 3: Open a long position (Leverage 1:20)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 20 = $5,005 * After opening: * Free margin: $3,994 * Used margin: $6,006 **Step 4: Open a short position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 9 lots (900,000 units) * Current price: $1 * Required margin: $(900,000 × 1.001) / 100 = $9,009. The system verifies that upon opening this position, the MarketUsedMargin remains valid by satisfying the condition: **MarketUsedMargin** = MAX(*MarketPositionLong*, *MarketPositionShort*) = MAX(6,006, 9,009) = 9,009. Since the condition is met, the position opens. * After opening: * Free margin: $991 * Used margin: $9,009 As a result, you can open multiple opposite positions without significantly increasing the Used margin. Furthermore, closing positions never increases the Used margin. *** **Free margin** The amount of funds that can be used for opening new positions. *** **Unrealized PnL** The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) ## Summary [#summary] Use this widget to assess the current market depth indicating the actual liquidity of an asset, which is evaluated based on the number of currently open orders to buy and sell it as well asset prices and volumes at various price levels. Market depth The widget is dynamic and is continuously updated in real time. The widget displays a chart indicating the overall volume of buy (green) and sell (red) orders at various price levels awaiting execution at the moment. You can hover the mouse pointer over the chart to learn the exact price and volume of an asset traded at a specific price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ## Summary [#summary] Use this widget to monitor statistics on a specific instrument. The widget is dynamic and is continuously updated in real time. Market summary To monitor multiple instruments at a time, use the [Watch list](watch-list) widget. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the first column. To change the market, click the market symbol and select a different one from the list. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current top-of-the-book price, in the quote asset. *** **Current price, \{RAT}** The current top-of-the-book price, in conversion to the platform root asset. *** **24h change** The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h high** The highest trade price over the last 24 hours. This value is always green. *** **24h low** The lowest trade price over the last 24 hours. This value is always red. *** **Info icon** Click this icon to view market details and trading sessions schedule. ## Summary [#summary] This widget displays a list of received notifications, both system and configured via the [Price control](price-control) widget. Messages ## Settings [#settings] ### Mark as read [#mark-as-read] Unread alerts are marked with a red dot in the list: * Click the dot to mark the notification as read. * Click **Mark all as read** to mark all new notifications as read at once. * Click the **three dots** icon in the upper right corner of the widget to access the **Hide read notifications option**. The counter of unread alerts is also displayed on the **bell icon** in the topbar. ## Summary [#summary] This widget displays a list of Limit orders that have been placed from this specific account and are currently open and assigned one of the following [statuses](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. Open orders The widget lists only open orders, that are currently not filled or partially filled. For a list of orders in the final statuses, use the [Order history](order-history) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders for all the time. To display orders for a specific time period, use the **Select date range** field. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled so far. *** **Fee** The total commission paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that hasn’t yet been filled. *** **Limit price** For Limit orders, the Limit price set when placing the order. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set. *** **Used leverage** For margin trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Valid until** The date and time when an order expires. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Admin**: The order was placed by an Admin. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Cancel orders [#cancel-orders] To cancel an order, click the **×** in the corresponding row. To cancel all active orders at once, click the **Cancel all** button in the widget header. ## Summary [#summary] This widget displays a list of your positions currently open on the selected account. Open positions The widget lists only open positions. For a list of closed positions, use the [Closed positions](closed-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists open positions for all the time. To display positions opened during a specific time period, use the **Select date range** field. The most recent position appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related trades [#view-related-trades] Click the **chevron icon** in a position row to expand a list of related trades. ### Close positions [#close-positions] To close a position, hover over it and click the **CLOSE** button that appears. To close all/multiple positions at once, click **Close all** and select the desired option: close all positions or close positions with positive/negative PnL. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Position size** The current position volume, in lots. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Current price** The current market price of the base asset: bid for Long positions and ask for Short positions. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Unrealized PnL, DAY, \{RAT}** The potential profit or loss earned for a current day, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. *** **Unrealized PnL, DAY, %** The potential profit or loss earned for a current day, in percents. *** **Unrealized PnL, Total, \{RAT}** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). *** **Unrealized PnL, Total, %** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset, in percents. *** **Used margin, \{RAT}** The amount of your funds used for maintaining a position, in conversion to the platform root asset. *** **Leverage** The actual leverage ratio used for opening a position. *** **Req. leverage** The leverage ratio you requested when opening a position. *** **\{RAT} notional** The current position size equivalent in the platform root asset. *** **Rate to \{RAT}** The current exchange rate of a quote asset to the platform root asset. *** **Open date, time** The date and time when a position was opened. *** **Updated date, time** The date and time of the latest position-related trade. *** **Reason** The reason for opening a position: * **Trader**: The position was opened by you. * **Admin**: The position was opened by an Admin. * **Webhook alert**: The position was opened via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. ## Summary [#summary] This widget displays a list of currently open buy and sell limit orders for a selected asset along with the current bid-ask spread. Order book The widget is dynamic and is continuously updated in real time. It provides three different sections displaying the following information: * Open sell orders are highlighted in red and listed in the top section. The best ask, which is the sell order with the lowest price, is displayed at the bottom of this list. * Open buy orders are highlighted in green and listed in the bottom section. The best bid, which is the buy order with the highest price, is displayed at the top of this list. * The middle section displays the current bid-ask spread indicating the gap between the best ask and bid prices declared for an asset. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Display only asks/bids [#display-only-asksbids] In the upper part of the widget, you can choose how to display the Order book: * Full view. * Buy orders only + spread. * Sell orders only + spread. ## Fields [#fields] Each row of the Order book provides the following information about a selected market: **Price, \{QUOTE}** The price, in the quote asset. *** **Amount, \{BASE}** The total amount of the base asset available at a corresponding price level. *** **Total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. In addition, you can use the [Market depth](market-depth) widget to evaluate the liquidity of a specific asset based on the overall volume of orders traded at various price levels. For Spot markets, hover over Order book rows to view additional information and buy or sell assets in click: **Average price** The average price, in the quote asset. *** **Total volume** The total amount of the base asset available at a corresponding price level. *** **Grand total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. *** **Buy** / **Sell** Click the button to instantly place a Market order to buy or sell the asset at the selected price level. ## Summary [#summary] This widget provides up-to-date information about the orders executed on a selected market partially or in full, as well as the orders that were canceled, rejected, and expired. The entire order history of your account is available. Order history The widget lists only the orders to which final statuses are assigned. For a list of orders that are still being executed, use the [Open orders](open-orders) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders with the *Completed* status for the last three months. To display orders for a specific time period, use the **Select date range** field. To display orders with specific statuses, select one or more from the dropdown above the list. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled. *** **Fee** The total commissions paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that wasn't filled. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Completed*, *Cancelled*, *Rejected*, or *Expired*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Stop loss**: The order was placed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The order was placed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Summary [#summary] Use this widget to place new orders. Place order The widget has two states: ### The PRO toggle is disabled [#the-pro-toggle-is-disabled] In this state, you can quickly place **IOC Market** and **GTC Limit** orders by selecting the order side (Buy/Sell) and type (Market/Limit), and specifying the order size (in lots) and price (for Limit orders). You can also place orders on CFD markets with the maximum leverage automatically applied. ### The PRO toggle is enabled [#the-pro-toggle-is-enabled] In this state, you get access to more precise order settings, such as: * **Stop orders** * **Time in force** * **Leverage** * **Take profit, Stop loss, Trailing stop** * **Comment** * **Complete order information** The **Comment** field allows you to attach a text note to the order (up to 100 characters). The comment is inherited by the resulting position and can't be edited after the order is placed. ## Settings [#settings] ### Select a market [#select-a-market] The market on which the order will be placed is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Place an order [#place-an-order] To place an order, fill in the parameters, review order details and preliminary calculated values, and then confirm the order by clicking the **Place** button. For a Limit order whose price crosses the current top-of-book — Buy at or above the best ask, or Sell at or below the best bid — the platform shows a confirmation dialog before submission. The dialog shows the entered price and the current best bid/ask, and lets you confirm or cancel the order. This warning is enabled by default; you can disable it from the dialog (**Do not show this warning again**) or from the **Limit order cross-TOB warning** toggle in [Settings](../get-started/settings#action-confirmation). ### Set price triggers [#set-price-triggers] If using **Take profit, Stop loss, Trailing stop**, set the prices in consideration of the current highest market bid/ask or a specified Limit price: These values can be adjusted any time until the position is fully closed via the [Open positions](open-positions) widget. You can't place orders during non-trading hours, according to the trading calendar schedule. The order controls are disabled when the selected account is Halted or Frozen. For more information, see [Account status](../get-started/customizing-your-terminal#account-status). You will not be able to place an order if the execution of the order causes your margin level to fall below the *Margin call* level. The same conditions apply to withdrawal operations. ## Summary [#summary] This widget displays a price chart showing fluctuation of prices for a selected market over a certain time period. Price chart The horizontal axis (X-axis) represents the time scale, and the vertical axis (Y-axis) indicates the price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Customization [#customization] Multiple customization options are provided, allowing you to configure the chart according to your preferences. You can switch between bar, candle, Heikin Ashi, line, area and baseline views, as well as specify the time period for which data should be displayed. The chart supports numerous financial indicators, such as moving averages and regressions, and can feature a variety of custom shapes, including arrows and lines, pitchforks, and various ranges, allowing you to perform an in-depth market analysis. ### Display options [#display-options] The widget supports displaying of open positions, price triggers, open and executed orders. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart) to enable desired options. ## Placing orders [#placing-orders] ### Enable placing orders [#enable-placing-orders] To enable placing orders directly from the Price chart, you need to activate the corresponding settings: 1. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart). 2. Activate the **Market quick trade panel** or **Limit quick trade panel** toggle, or both. 3. If needed, adjust the amount presets. These amounts will be available for quick selection when placing an order. ### Market quick trade panel [#market-quick-trade-panel] If the corresponding setting is activated, the draggable **Market quick trade panel** is constantly displayed on the Price chart. ### Limit quick trade panel [#limit-quick-trade-panel] If the corresponding setting is activated, the **+** will appear when hovering over price levels on the chart. Clicking it will open the **Limit quick trade panel**: * in the upper half of the chart — to sell; * in the lower half of the chart — to buy. ### Place a new order [#place-a-new-order] To place a new Market or Limit order from the Price chart, when a corresponding panel is displayed: 1. Select the **amount** from configured presets. 2. Select a **leverage** ratio, if trading on CFD or PF markets. 3. Click **Buy** or **Sell**. The order will be placed according to the selected type. ## Summary [#summary] Use this widget to configure alerts that will be delivered to the [Messages](messages) widget when an instrument price reaches the specified level. Price control ## Settings [#settings] ### Configure a new alert [#configure-a-new-alert] To configure a new alert: 1. Click the **Add market** button to select a required market from the list. 2. Click the **+** icon below the instrument name to add a new alert trigger. 3. In the displayed fields, specify the exact price or the price change in percents (positive or negative). The other value will be calculated automatically. 4. Click the **check mark icon** to add the trigger. Now you will receive a notification in the [Messages](messages) widget, once the instrument price hits the specified level. You can configure multiple triggers for each instrument. ### Edit alerts [#edit-alerts] Click the price to edit the existing alert. ### Remove alerts [#remove-alerts] Click the **×** button on the trigger panel to remove it and stop receiving corresponding notifications. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ## Summary [#summary] This widget displays a list of untriggered Stop orders created on the selected account. Once a market price reaches your predetermined Stop price, the Stop order is activated and submitted as either a Market or Limit order. It's then removed from this widget. You can now find it in either the [Open orders](open-orders) or [Order history](order-history) widget, depending on its current status. Stop orders ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the Stop Market and Stop Limit orders for all the time. The most recent order appears at the top of the list. To display orders for a specific time period, use the **Select date range** field. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types): Stop Market or Stop Limit. *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Stop price** The stop price specified when creating an order. When the market reaches this price, the Stop order will be placed (as a Market or Limit order. *** **Limit price** The price of a Limit order that will be placed when the Stop price is triggered. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Order ID** The system identifier of an order. ## Summary [#summary] Use this widget to monitor statistics on multiple instruments at a time. The widget is dynamic and is continuously updated in real time. Watch list ## Settings [#settings] ### Add/remove instruments [#addremove-instruments] Click the **Add market** button to select a required market from the list. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Last price** The price of the last trade. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h low** The lowest trade price over the last 24 hours. *** **24h high** The highest trade price over the last 24 hours. Understand the basics and learn everything you need to start using the B2TRADER API Understand the basics and learn everything you need to start using the B2TRADER API Consult an in-depth reference describing REST API requests and responses Consult an in-depth reference describing REST API requests and responses Explore the supported WebSocket API methods and streams Explore the supported WebSocket API methods and streams Connect to the FIX 4.4 API for market data streaming and order execution Connect to the FIX 4.4 API for market data streaming and order execution ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Trading API: Stop orders for closed markets [#trading-api-stop-orders-for-closed-markets] The **Trading API** now accepts **Stop** orders for markets that are closed according to their trading calendar. The order is stored and activates automatically when the market reopens, instead of being rejected at submission. #### Reports API: full account history [#reports-api-full-account-history] Trading reports can now be generated for the entire account history. The previous **92-day** limit has been removed, and an **All data** range is now available for report generation. #### Trading API: market asset identifiers [#trading-api-market-asset-identifiers] The `baseAssetId` and `quoteAssetId` fields have been added to the v6 `/markets` responses, allowing clients to resolve the base and quote assets of each market without additional lookups. #### Accurate unrealized PnL [#accurate-unrealized-pnl] Unrealized PnL returned by the API is now calculated using the correct order book side for each position direction, improving the accuracy of PnL values in position and margin responses. *** ### Resolved issues [#resolved-issues] * Resolved an issue where `WebhookAlert` order reason and position modifier values were returned as numeric codes instead of API enum strings in History API `/v2/orders` responses. ## April 9, 2026 [#april-9-2026] ### New features [#new-features] #### Trading credit in API responses [#trading-credit-in-api-responses] Broker-issued **trading credit** is now exposed through the API. The account margin data response and the real-time margin stream include the current credit amount in the Reference Asset (`creditInRAT`). Credit is included in the account equity and excluded from the withdrawable amount. *** ### Improvements [#improvements-1] #### Webhook Trading API: webhook URL in key listing [#webhook-trading-api-webhook-url-in-key-listing] The list webhook API keys response now includes the `webhookUrl` field, so the configured webhook endpoint can be retrieved for each key. ## March 16, 2026 [#march-16-2026] ### New features [#new-features-1] #### Webhook Trading API [#webhook-trading-api] A new **Webhook Trading API** has been added, enabling automated order creation via webhook alerts with API key authentication. **Key points:** * Create and manage webhook API keys for secure authentication * Receive trading alerts and create orders automatically * Idempotency supported via deduplication ID * Market type routing by symbol prefix (spot, CFD, perpetual) #### Public Account ID [#public-account-id] A new `publicAccountId` field has been added across all API endpoints, providing a human-readable account identifier as an alternative to internal UUIDs. **Affected APIs:** * Trading API — account-related responses and filters * Settings API — account configuration endpoints * History API — all REST endpoints and WebSocket streams * Reports API — report responses and filters #### Long-term trading data history [#long-term-trading-data-history] Date range restrictions have been removed from **Order History** and **Closed Positions** endpoints, allowing access to full trading history without time-based limitations. *** ### Improvements [#improvements-2] #### Transfer subtype field [#transfer-subtype-field] A new `subtype` field has been added to transfer responses in the History API to distinguish **Negative Balance Protection** transfers from manual ones. #### Rounded position prices [#rounded-position-prices] The `positionPriceInRAT` values are now properly rounded in closed position API responses according to the Reference Asset (RAT) scale. *** ### Resolved issues [#resolved-issues-1] * Resolved an issue where `/total-swaps` requests returned HTTP 504 timeout errors. ## March 11, 2026 [#march-11-2026] ### Added FIX API documentation [#added-fix-api-documentation] Added new FIX API section covering Market Data and Trading sessions via the FIX 4.4 protocol. ## March 11, 2026 [#march-11-2026-1] ### Initial version [#initial-version] ## March 2, 2026 [#march-2-2026] ### New features [#new-features-2] #### Trading Terminal AI assistant [#trading-terminal-ai-assistant] A new **AI assistant** has been added to the Trading Terminal, providing traders with an intelligent widget for market analysis and trading support. *** ### Improvements [#improvements-3] #### Public Account ID (preview) [#public-account-id-preview] The `publicAccountId` field has been added to account-related API responses as a preview, ahead of the full rollout across all endpoints. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-3] #### Funding Rates API [#funding-rates-api] New API endpoints have been added for retrieving funding rate data synchronized from **B2CONNECT**, including funding rates, mark price, and funding interval for Perpetual Futures markets. **Key points:** * Funding rate values streamed in real time * Mark price used for position valuation when available from LP * Funding interval synchronized per market configuration * FIX API contract extended with funding data fields #### OHLC Candlestick API [#ohlc-candlestick-api] A new API endpoint has been added for retrieving OHLC (candlestick) data, supporting both **Spot** and **Perpetual Futures** markets. Minute-level candle data is now stored for up to 5 years. OHLC candle data streaming is also available via the WebSocket API using gRPC transport, providing real-time candlestick updates. #### Favorite markets [#favorite-markets] A new **Favorite markets** feature has been added, allowing traders to manage personalized market lists via the Trading API. #### Comment field for orders and positions [#comment-field-for-orders-and-positions] A new `comment` field has been added to order and position responses across REST, WebSocket, and History APIs. The comment can be set when placing an order and is propagated to the associated position and execution records. #### B2COPY Integration API [#b2copy-integration-api] New API endpoints have been added for **B2COPY** and IB (Introducing Broker) integrations, including special account types for copy trading. The `isCopyTradingAccount` field has been added to the `/api/v1/total-fundings` endpoint. *** ### Improvements [#improvements-4] #### FIX API: enhanced request throughput [#fix-api-enhanced-request-throughput] The FIX API trading request processing has been optimized to support up to 100 requests per second per connection. All `TimeInForce` types are now supported, including **GTD** (Good Till Date). #### Multilingual support [#multilingual-support] Trading API, Settings API, and Reports API endpoints now support multilingual content with full Unicode character support, enabling localized responses for configurable fields, report names, and templates. #### Stop Market order calculation [#stop-market-order-calculation] The **Value** and **Amount** calculation for **Stop Market** orders has been corrected for **Spot** markets. **Slippage Rate** has been removed from **CFD** and **Perpetual Futures** order calculations. #### Trading API: empty categories hidden [#trading-api-empty-categories-hidden] Empty market categories are now automatically excluded from Trading API responses, reducing unnecessary data in category listings. #### Balance API: zero balance for all assets [#balance-api-zero-balance-for-all-assets] Assets without prior balance operations now return a zero balance in API responses instead of being omitted. #### Cross-rate market configuration [#cross-rate-market-configuration] Markets used exclusively for cross-rate calculations can now be disabled for trading while remaining active for rate conversion. #### History API: extended contracts [#history-api-extended-contracts] Positions and Events API responses have been extended with additional fields. The `updatedAt` field is now available as a sorting and filtering parameter in History Server API endpoints. #### Settings API: market update endpoint [#settings-api-market-update-endpoint] The market update endpoint has been changed from `PATCH` to `PUT` semantics, requiring the full market object in the request body. #### Settings API: legacy endpoints removed [#settings-api-legacy-endpoints-removed] Legacy commission and routing rule endpoints have been removed following the tier commission update. Use the current endpoints as documented in the API reference. *** ### Resolved issues [#resolved-issues-2] * Resolved an issue where `takeProfitPrice` and `stopLossPrice` values were missing from the History Server `/v2/orders` endpoint responses. * Resolved an issue where bulk order cancellation returned a successful result for non-existing orders. * Resolved an issue where bulk order cancellation returned a successful result for orders that could not be cancelled. * Resolved incorrect error codes returned when `closePositionLotAmount` was set to `0`, a negative value, or an empty string. * Resolved an issue where the WebSocket Book stream continued sending prices with an outdated tick size after market parameter changes. * Resolved an issue where negative spreads in the **Market Data API** were not handled correctly. * Resolved an issue where orders could not be created when using the default 24/7 calendar. * Resolved an issue where the `/external-orders` API returned `null` for `rejectReason` although the Trading Server received a reason from the LP. Customize your Trading Terminal and configure settings Customize your Trading Terminal and configure settings Explore and manage all available trading widgets Explore and manage all available trading widgets Learn basic terms and values used across the platform Learn basic terms and values used across the platform The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](trading) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `V` — Market Data Request (Client → B2TRADER) * `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER) * `X` — Market Data — Incremental Refresh (Client ← B2TRADER) * `Y` — Market Data Request Reject (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Market Data session, use the following parameters provided by B2TRADER: * **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint) * **SenderCompID**: Your client identifier for the Market Data session * **TargetCompID**: The server identifier for the Market Data session * **Protocol**: FIX 4.4 The Market Data connection does not require SSL. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request. ```text title="Example" 8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Optional. ```text title="Example" 8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^ ``` *** ## Market Data Request (V) [#market-data-request-v] This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol. After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update. To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout. **`262 MDReqID`** `String` The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard. **`263 SubscriptionRequestType`** `int` The type of response expected from the server. Required. Possible values: * `1` — Subscribe: receive updates as the market status changes * `2` — Unsubscribe: stop streaming market data for the specified symbol **`264 MarketDepth`** `int` The market depth for an order book snapshot. Required. Possible values: * `0` — Full order book * `1` — Top-of-the-book prices **`265 MDUpdateType`** `int` The update type. Required. Must be `1` (incremental updates for changed price levels only). **`267 NoMDEntryTypes`** `int` The number of `<269>` MDEntryType entries requested. Required. > Repeating group: **`269 MDEntryType`** `int` The side of the quote. Required. Possible values: * `0` — Bid * `1` — Ask **`146 NoRelatedSym`** `int` The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each. > Repeating group: **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```text title="Example (Client → B2TRADER)" 8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^ ``` ## Market Data — Snapshot/Full Refresh (W) [#market-data--snapshotfull-refresh-w] This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^ ``` ## Market Data — Incremental Refresh (X) [#market-data--incremental-refresh-x] This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. * Must be unique among active entries when `<279>` MDUpdateAction is `0` (New) * Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete) **`279 MDUpdateAction`** `int` The update type. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — New * `1` — Change * `2` — Delete **`58 Text`** `String` Additional context. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^ ``` ## Market Data Request Reject (Y) [#market-data-request-reject-y] This message is sent by the server to reject a Market Data Request due to business or technical reasons. **`262 MDReqID`** `String` The identifier of the rejected Market Data Request. Required. **`281 MDReqRejReason`** `int` The reason why the request is rejected. Optional. Possible values: * `0` — Unknown symbol * `1` — Duplicate MDReqID * `2` — Insufficient bandwidth * `3` — Insufficient permissions * `4` — Unsupported SubscriptionRequestType * `5` — Unsupported MarketDepth * `6` — Unsupported MDUpdateType * `8` — Unsupported MDEntryType **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^ ``` The Trading session enables order placement and execution management via the FIX 4.4 protocol. Use this session to submit orders and receive real-time execution reports for your trading activity. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Trading** session only. For real-time order book streaming, use the [Market Data](market-data) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `D` — New Order Single (Client → B2TRADER) * `8` — Execution Report (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Trading session, use the following parameters provided by B2TRADER: * **Host and port**: The Trading endpoint (provided separately from the Market Data endpoint) * **SenderCompID**: Your client identifier for the Trading session * **TargetCompID**: The server identifier for the Trading session * **Protocol**: FIX 4.4 The Trading connection requires SSL with a self-signed certificate. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=117^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=117^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=93^35=A^1=68a4446ac84827ff5cd35c74^34=225^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=054^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Conditional — required when sent in response to a Test Request. ```text title="Example" 8=FIX.4.4^9=79^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=156^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Required. ```text title="Example" 8=FIX.4.4^9=87^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=250^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=90^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=176^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=105^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=Session terminated by client^10=183^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=81^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=009^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Execution Report with rejected status and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=128^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=11^372=D^373=1^58=Required tag missing: ClOrdID^10=126^ ``` *** ## New Order Single (D) [#new-order-single-d] This message is sent by the client to place a new order. The server responds with an Execution Report confirming the order status. For details on supported order types, see [Order types](../get-started/order-types). For details on time-in-force options, see [Time in force](../get-started/time-in-force). **`11 ClOrdID`** `String` The unique client-assigned order identifier. Required. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`38 OrderQty`** `Qty` The order quantity. Required. Must be greater than zero. The decimal precision must not exceed the market's amount scale, and the value must be at least the market's minimum amount. **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`59 TimeInForce`** `char` The order's time-in-force policy. Required. Possible values: * `0` — Day * `1` — Good Till Cancel (GTC) * `3` — Immediate or Cancel (IOC) * `4` — Fill or Kill (FOK) * `6` — Good Till Date (GTD) **`44 Price`** `Price` The order price. Conditional — required when `<40>` OrdType is `2` (Limit), must not be present when `<40>` OrdType is `1` (Market). Must be greater than zero. The decimal precision must not exceed the market's price scale. **`126 ExpireTime`** `UTCTimestamp` The order expiration time. Conditional — required when `<59>` TimeInForce is `6` (GTD), must not be present otherwise. **`60 TransactTime`** `UTCTimestamp` The time of order creation. Required. ```text title="Limit order example (Client → B2TRADER)" 8=FIX.4.4^9=168^35=D^34=3^52=20231220-09:15:30.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order001^55=spot.btc_usdt^54=1^38=0.5^40=2^44=42500.00^59=1^60=20231220-09:15:30.000^10=123^ ``` ```text title="Market order example (Client → B2TRADER)" 8=FIX.4.4^9=155^35=D^34=4^52=20231220-09:16:00.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order002^55=spot.btc_usdt^54=2^38=0.1^40=1^59=3^60=20231220-09:16:00.000^10=045^ ``` ## Execution Report (8) [#execution-report-8] This message is sent by the server to confirm order status changes, including acknowledgment of new orders, fills, partial fills, cancellations, and rejections. For details on order statuses, see [Order statuses](../get-started/order-statuses). **`37 OrderID`** `String` The server-assigned unique order identifier. Required. **`11 ClOrdID`** `String` The client-assigned order identifier from the original New Order Single. Required. **`17 ExecID`** `String` The unique execution identifier. Present for trade executions. **`150 ExecType`** `char` The type of execution being reported. Required. Possible values: * `0` — New: order has been accepted * `4` — Canceled: order has been canceled by the server (e.g., IOC order partially filled, GTD order expired, or market settings changed) * `8` — Rejected: order has been rejected * `F` — Trade: order has been partially or fully filled **`39 OrdStatus`** `char` The current order status. Required. Possible values: * `0` — New * `1` — Partially filled * `2` — Filled * `4` — Canceled * `8` — Rejected **`1 Account`** `String` The account identifier. Required. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`44 Price`** `Price` The order price. Present for Limit orders. **`6 AvgPx`** `Price` The average price of all fills on this order. Required. **`14 CumQty`** `Qty` The total filled quantity. Required. **`151 LeavesQty`** `Qty` The remaining quantity to be filled. Required. Set to `0` for Canceled or Rejected orders. **`31 LastPx`** `Price` The price of the last fill. Present when `<150>` ExecType is `F` (Trade). **`32 LastQty`** `Qty` The quantity of the last fill. Present when `<150>` ExecType is `F` (Trade). **`15 Currency`** `String` The quote asset identifier. Optional. **`60 TransactTime`** `UTCTimestamp` The transaction time. Required. **`64 SettlDate`** `String` The settlement date in `YYYYMMDD` format. Required. **`58 Text`** `String` Additional information, such as the rejection reason. Optional. ```text title="New order accepted (B2TRADER → Client)" 8=FIX.4.4^9=220^35=8^34=5^52=20231220-09:15:30.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^150=0^39=0^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=0^14=0^151=0.5^60=20231220-09:15:30.100^64=20231220^10=087^ ``` ```text title="Trade execution (B2TRADER → Client)" 8=FIX.4.4^9=245^35=8^34=6^52=20231220-09:15:30.200^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^17=01HBXK5V3R8NQ7YR^150=F^39=2^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=42500.00^14=0.5^151=0^31=42500.00^32=0.5^15=usdt^60=20231220-09:15:30.200^64=20231220^10=154^ ``` ```text title="Order rejected (B2TRADER → Client)" 8=FIX.4.4^9=214^35=8^34=7^52=20231220-09:16:00.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YS^11=order002^150=8^39=8^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=2^40=1^6=0^14=0^151=0^58=Insufficient balance^60=20231220-09:16:00.100^64=20231220^10=201^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard session-level Reject or Execution Report rejection. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=100^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=006^ ``` Each trading account has an `accountStatus` field that determines which operations are permitted on the account. The field is returned on account objects by the API, such as in [Get accounts](../rest-api/settings). An account can be assigned one of the following statuses: * **Active**: All operations are permitted, including placing, modifying, and canceling orders, opening and closing positions, deposits, and withdrawals. * **Halted**: Trader-initiated trading is blocked. Requests to place, modify, or cancel orders and to open or close positions are rejected. Deposits and withdrawals remain allowed. Managed trading through the Management API (MAM, B2COPY) continues to work. * **Frozen**: All operations are blocked. Trading, deposits, and withdrawals are unavailable, and the account is view-only. Stop-out liquidation still executes as a safety mechanism. * **Archived**: The account is decommissioned and hidden from all user-facing surfaces. Real-time profit and loss, equity, margin level, and funding settlement continue for all statuses. Archived accounts are never returned in the trading API account list. They are excluded server-side, so an account that changes to *Archived* stops appearing in [Get accounts](../rest-api/settings) responses. A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. ## Introduction [#introduction] B2TRADER provides developers with three distinct methods for data delivery, each optimized for specific use cases and performance requirements: REST, WebSocket, and FIX APIs. The **REST API** provides read access to market data as well as both read and write access to trading operations. It serves as the foundation for synchronous data operations where immediate confirmation and guaranteed delivery are essential. The **WebSocket API** provides access to public market data streaming as well as private account updates. It delivers real-time updates with low latency, making it ideal for live trading environments. The **FIX API** provides direct access to market data and trading via the FIX 4.4 protocol. It is designed for institutional clients and algorithmic trading systems that require standardized, low-latency connectivity using the industry-standard Financial Information eXchange protocol. This approach provides developers with flexible options for building robust, scalable trading applications that can handle both operational requirements and real-time market dynamics. ### When to use REST API [#when-to-use-rest-api] * **Account configuration and settings**: Managing user preferences and system configurations. * **Order placement and modification**: Creating, updating, and canceling trading orders. * **Historical data retrieval**: Accessing past trading records and market data. * **One-time data requests**: Retrieving specific information that doesn't require continuous updates. * **Administrative operations**: Account management and system administration tasks. ### When to use WebSocket API [#when-to-use-websocket-api] * **Real-time price monitoring**: Live market price feeds and ticker updates. * **Live position tracking**: Continuous monitoring of open and closed positions. * **Order book visualization**: Real-time depth of market data. * **Market data feeds**: Streaming market statistics and trading activity. * **Account balance monitoring**: Live updates of account equity and margin status. ### When to use FIX API [#when-to-use-fix-api] * **Institutional connectivity**: Standardized FIX 4.4 protocol for professional trading infrastructure. * **Algorithmic trading**: Low-latency order execution and market data for automated strategies. * **Market data streaming**: Real-time order book snapshots and incremental updates via FIX protocol. * **Multi-venue integration**: Unified FIX connectivity for systems already integrated with other FIX-based venues. ## General considerations [#general-considerations] The following applies to all interface descriptions provided in this documentation: * **Endpoints**: All endpoints are relative and resolved based on a specified hostname (indicated as `{host}`). * **Authentication**: REST and WebSocket APIs require an access token (see [Authentication](#authentication)). The FIX API uses in-band authentication via the Logon message with Username, Password, and Account fields provided by B2TRADER. * **Data format**: REST and WebSocket APIs return results in JSON format. The FIX API uses the standard FIX 4.4 message format. * **Security**: All communications use secure protocols (HTTPS for REST, WSS for WebSocket, encrypted TCP for FIX). ### Authentication [#authentication] API access requires an access token for both REST and WebSocket connections. Authentication follows a two-step process: 1. Generate an offline token in the Trading terminal. 2. Exchange the offline token for an access token via API call. #### Token types [#token-types] **Offline token** * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time * **Purpose**: Generate access tokens **Access token** * **Type**: Bearer token * **Validity**: 60 minutes * **Purpose**: Authorize API requests ### Generate offline token [#generate-offline-token] To generate an offline token: 1. In the Trading terminal, open **Settings** and select **API token management**. 2. Click **+ Create new**. 3. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 4. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ### Obtain access token [#obtain-access-token] Request an access token using your offline token. **Endpoint**: `POST` `/frontoffice/api/v4/access-token` **Request body**: ```json { "token": "{YOUR_OFFLINE_TOKEN}" } ``` **Response** (Success): ```json { "accessToken": "{YOUR_ACCESS_TOKEN}", "expiresIn": 3600, "tokenType": "Bearer" } ``` **`accessToken`** `string` The access token for API authorization. **`expiresIn`** `integer` The token lifetime, in seconds. **`tokenType`** `string` The authentication type, always `"Bearer"`. ### Using access tokens [#using-access-tokens] Include the access token in API requests: ```http title="REST" Authorization: Bearer {YOUR_ACCESS_TOKEN} ``` ```http title="WebSocket" {URL}?access_token={YOUR_ACCESS_TOKEN} ``` Access tokens must be refreshed before expiration by repeating the Step 2 with your offline token. ## REST API: Synchronous data operations [#rest-api-synchronous-data-operations] The REST API serves as the foundation for synchronous data operations within the B2TRADER platform. This approach follows standard HTTP protocols and is ideal for operations requiring immediate confirmation and guaranteed delivery. ### Key characteristics [#key-characteristics] * **Request-response operations** where immediate confirmation is required. * **Account management** including settings and configuration. * **Order placement and modification** with guaranteed delivery. * **Historical data retrieval** for analysis and reporting. * **Stateless operations** that don't require persistent connections. ### HTTP response codes [#http-response-codes] B2TRADER API uses conventional HTTP response codes to indicate the success or failure of requests. **Success codes:** * `200 OK` — Request successful **Error codes:** * `400 Bad Request` — Invalid request parameters * `401 Unauthorized` — Authentication required * `403 Forbidden` — Insufficient permissions * `404 Not Found` — Resource not found * `429 Too Many Requests` — [Rate limit](#rate-limits) exceeded * `500 Internal Server Error` — Server error In case of an error, an object will be returned with the following structure: ```json { "code": "text", "message": "text", "details": { "source": "text", "message": "text", "stackTrace": "text" } } ``` ### Available endpoints [#available-endpoints] * **[Trading operations](../rest-api/trading)**: Create, modify, and cancel orders; open, close, and modify positions; control price trigger settings. * **[Trading history](../rest-api/history)**: Retrieve detailed execution records for positions and orders. * **[Settings and configurations](../rest-api/settings)**: Access account information, market specifications, trading sessions, and asset details. ### Rate limits [#rate-limits] Rate limits are applied per minute for each unique **AccountId** to ensure fair resource usage and maintain optimal API performance. All limits use the **Fixed Window** strategy. When rate limits are exceeded, the API returns a `429 Too Many Requests` HTTP status code. #### Trading methods [#trading-methods] * **Default limit**: 600 requests per minute for all methods. * **Reduced limit (200 rpm)** applies to: * Get order data methods * Bulk close positions method * Price triggers methods #### History methods [#history-methods] * **All request types**: 60 requests per minute. #### Settings methods [#settings-methods] * **GET requests**: 100 requests per minute. * **POST and DELETE requests**: 60 requests per minute. Rate limits are calculated independently for each method category. For example, you can make 100 GET requests to Settings methods and 60 requests to History methods within the same minute without hitting rate limits. ## WebSocket API: Real-time data streaming [#websocket-api-real-time-data-streaming] The WebSocket API delivers real-time updates with minimal latency, essential for modern trading applications. The implementation uses unidirectional communication from server to client, ensuring efficient data delivery. ### Key characteristics [#key-characteristics-1] * **Unidirectional communication** from server to client for optimal performance. * **Real-time market data** for live trading environments. * **Position and order updates** as they occur in real-time. * **Low-latency data delivery** for time-sensitive trading operations. * **Persistent connections** maintaining continuous data flow. ### SignalR implementation [#signalr-implementation] B2TRADER utilizes **AspNetCore SignalR** for WebSocket message organization and transmission, providing a robust and scalable real-time communication framework. **Resources:** * [Official GitHub Repository](https://github.com/dotnet/aspnetcore/tree/main/src/SignalR) * [Official Documentation](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr) SignalR provides a structured approach to real-time communication through standardized message formatting and connection management. ### Connection lifecycle [#connection-lifecycle] The data transfer process consists of two essential phases: 1. **Connection establishment** — Initial handshake, authentication, and subscription setup. 2. **Data streaming** — Continuous real-time data flow with automatic reconnection handling. ### Message types [#message-types] SignalR utilizes numerical `type` indicators for different operations: ### Available stream types [#available-stream-types] * **[Trading streams](../ws-api/trading)**: Track active orders, open and closed positions. * **[Market data streams](../ws-api/market-data)**: Get real-time order book updates, market statistics and price changes. * **[Account information streams](../ws-api/account-info)**: Get live account balance and margin updates. ## FIX API: Standardized protocol connectivity [#fix-api-standardized-protocol-connectivity] The FIX API provides direct access to B2TRADER via the FIX 4.4 protocol, the industry standard for electronic trading communication. It is designed for institutional clients and algorithmic trading systems. ### Key characteristics [#key-characteristics-2] * **FIX 4.4 protocol** for standardized, vendor-neutral connectivity. * **Dedicated sessions** for Market Data and Trading with separate endpoints. * **In-band authentication** via Logon message (Username, Password, Account). * **Real-time market data** with order book snapshots and incremental updates. * **Session management** with Heartbeat, Test Request, and Sequence Reset support. ### Authentication [#authentication-1] Unlike REST and WebSocket APIs, the FIX API does not use access tokens. Authentication is performed in-band as part of the FIX Logon message using credentials provided by B2TRADER: * **Username** (`<553>`): The client username * **Password** (`<554>`): The client password * **Account** (`<1>`): The account identifier ### Available session types [#available-session-types] * **[Market Data](../fix-api/market-data)**: Subscribe to real-time order book updates, snapshots, and incremental refreshes. * **[Trading](../fix-api/trading)**: Place orders and receive execution reports in real time. ## Integration best practices [#integration-best-practices] ### API selection strategy [#api-selection-strategy] * Use **REST API** for operational tasks requiring confirmation (order placement, account management). * Use **WebSocket API** for real-time monitoring and market data visualization. * Use **FIX API** for institutional connectivity, algorithmic trading, and integration with existing FIX-based infrastructure. * Implement multiple APIs in comprehensive trading applications for optimal functionality. ### Performance optimization [#performance-optimization] * Implement proper connection pooling for REST API requests. * Use WebSocket subscriptions efficiently by subscribing only to required data streams. * Handle reconnection logic for WebSocket connections to ensure data continuity. * Implement appropriate error handling and retry mechanisms. ### Security considerations [#security-considerations] * Store authentication tokens securely and implement token refresh mechanisms. * Use secure connections (HTTPS/WSS) for all API communications. * Implement proper input validation and sanitization. * Monitor API usage and implement rate limiting on the client side. This comprehensive API architecture enables developers to build sophisticated trading applications that can handle both real-time market dynamics and operational trading requirements efficiently. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all Limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the platform, without taking into account the time settings of the devices from which the platform is accessed. ## Get full balance [#get-full-balance] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"FullBalance"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "FullBalance", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of balance objects. **`item.assetId`** `string` The asset identifier. **`item.available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`item.total`** `decimal string` The overall amount of the asset, including locked funds. **`item.locked`** `decimal string` The asset amount locked on the account for execution of all placed Limit orders. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "assetId": "eur", "available": "497838.8", "total": "497838.8", "locked": "0" } ] } ``` ## Get margin data [#get-margin-data] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"MarginData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "MarginData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.marginBalanceInRAT`** `decimal string` The total amount of funds that can be used as a collateral for trading, in RAT. This value is calculated as SUM (*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*) Where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the BP root asset. **`item.creditInRAT`** `decimal string` The promotional trading credit granted to the account by the broker, in RAT. Credit is included in the account equity but excluded from the withdrawable amount. During a rolling deployment, older payloads might omit this field. In that case, default it to `0`. **`item.unrealizedPnlInRAT`** `decimal string` The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) **`item.equityInRAT`** `decimal string` The potential balance if all open positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. **`item.usedMarginInRAT`** `decimal string` The amount of funds that is used for maintaining all open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **`item.freeMarginInRAT`** `decimal string` The amount of funds that can be used for opening new positions. **`item.marginLevel`** `decimal string` The ratio of funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "marginBalanceInRAT": "497838.8", "creditInRAT": "0", "unrealizedPnlInRAT": "-5.25", "equityInRAT": "497833.55", "usedMarginInRAT": "100.18", "freeMarginInRAT": "497733.37", "marginLevel": "4969.3905" } } ``` ## Get order book [#get-order-book] ### Connection [#connection] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Book"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eur_chf" ], "invocationId": "0", "target": "Book", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.askTotalAmount`** `string` The total ask amount. **`item.bidTotalAmount`** `string` The total bid amount. **`item.asks`** `array of objects` The array of ask price objects. **`item.asks.price`** `string` The price, in the quote asset. **`item.asks.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.asks.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.bids`** `array of objects` The array of bid price objects. **`item.bids.price`** `string` The price, in the quote asset. **`item.bids.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.bids.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.version`** `string` The order book version. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eur_chf", "askTotalAmount": "18700000", "bidTotalAmount": "19100000", "asks": [ { "price": "0.93677", "amount": "5000000", "total": "4683850" }, { "price": "0.93676", "amount": "0", "total": "0" }, { "price": "0.93676", "amount": "0", "total": "0" } ], "bids": [ { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93655", "amount": "5000000", "total": "4682750" } ], "version": "12498", "snapshot": false } } ``` ## Get trading data [#get-trading-data] ### Connection [#connection-1] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"TradingData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.bnb_btc" ] ], "invocationId": "0", "target": "TradingData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.markets.displayName`** `string` The market ticker. **`item.markets.fullName`** `string` The market full name or description (optional). **`item.markets.price`** `decimal string` The current top-of-the-book price, in the quote asset. **`item.markets.priceInRAT`** `decimal string` The current top-of-the-book price, in conversion to the root asset of the platform. **`item.markets.priceChange24hr`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.markets.priceChangeAbs24hr`** `decimal string` The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. **`item.markets.highPrice24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.markets.lowPrice24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.markets.markPrice`** `decimal string` *Applicable to Perpetual markets only.* The mid-spread price, in conversion to RAT. **`item.markets.fundingRate`** `decimal string` *Applicable to Perpetual markets only.* The current funding rate. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "cfd.eur_chf", "type": "Cfd", "displayName": "cfd.eur_chf", "fullName": "", "price": "0.93586", "priceInRAT": "1", "priceChange24hr": "-0.0006", "priceChangeAbs24hr": "-0.00049", "highPrice24hr": "0.93695", "lowPrice24hr": "0.93134", "markPrice": null, "fundingRate": null } ], "snapshot": false } } ``` ## Get top of the book [#get-top-of-the-book] ### Connection [#connection-2] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Tob"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.eth_usdt" ] ], "invocationId": "0", "target": "Tob", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.ask`** `decimal string` The top-of-the-book ask price. **`item.markets.bid`** `decimal string` The top-of-the-book bid price. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "spot.eth_usdt", "ask": "2483.82", "bid": "2483.81" } ], "snapshot": false } } ``` ## Get trading chart [#get-trading-chart] ### Connection [#connection-3] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` and `timescale` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Chart"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eth_eur@15m" ], "invocationId": "0", "target": "Chart", "type": 4 } ``` *** ### Message [#message-3] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.low`** `decimal string` The lowest base asset price within the specified time interval. **`item.high`** `decimal string` The highest base asset price within the specified time interval. **`item.open`** `decimal string` The base asset price at the beginning of the specified time interval. **`item.close`** `decimal string` The base asset price at the end of the specified time interval. **`item.start`** `dateTime` The beginning of the specified time interval, in ISO 8601 format. **`item.end`** `dateTime` The end of the specified time interval, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eth_eur", "low": "2240.88", "high": "2270.29", "open": "2265.63", "close": "2255.99", "start": "2025-05-21T15:30:00Z", "end": "2025-05-21T15:45:00Z" } } ``` ## Get market summary [#get-market-summary] ### Connection [#connection-4] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Summary"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "cfd.eur_chf" ] ], "invocationId": "0", "target": "Summary", "type": 4 } ``` *** ### Message [#message-4] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.items`** `array of objects` The array of data objects. **`item.items.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.items.last`** `decimal string` The price of the last trade. **`item.items.high24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.items.low24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.items.percentChange`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "items": [ { "marketId": "cfd.eur_chf", "last": "0.93597", "high24hr": "0.93695", "low24hr": "0.93134", "percentChange": "-0.02" } ], "snapshot": false } } ``` ## Get open orders [#get-open-orders] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenOrders", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of market objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.status`** `string` The current [order status](../get-started/order-statuses). Possible values: * `Started` * `Pending` * `Working` **`item.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`item.reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`item.remainingAmount`** `decimal string` The order amount that hasn't yet been filled, in the base asset. **`item.requestedPrice`** `decimal string` The limit price for Limit orders; `null` for Market orders. **`item.executionPrice`** `decimal string` The volume-weighted average price of the order executions. **`item.createdAt`** `dateTime` The timestamp when the order was created, in ISO 8601 format. **`item.updatedAt`** `dateTime` The timestamp of the most recent update to the order, in ISO 8601 format. **`item.cancellationDate`** `dateTime` The timestamp when the order was cancelled or expired, in ISO 8601 format; `null` if not cancelled. **`item.commissionAssetId`** `string` The currency in which the commission was held. **`item.commissionAmount`** `decimal string` The total commissions put on hold for executing the order. **`item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when placing the order. **`item.fillFactor`** `decimal string` The proportion of the order amount filled so far, where `1` represents 100% fulfillment. **`item.comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.stopLoss`** `decimal string` The Stop Loss price, if set. ```json { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "orderId": "01JVQBFSTVC40VK03A0AY7K016", "timeInForce": "Gtc", "status": "Pending", "source": "Manual", "reason": "Trader", "side": "Buy", "orderType": "Limit", "requestedAmount": "10000", "remainingAmount": "10000", "requestedPrice": "0.9", "executionPrice": "0", "createdAt": "2025-05-20T17:22:31.899Z", "updatedAt": "2025-05-20T17:22:31.9001213Z", "cancellationDate": null, "commissionAssetId": "eur", "commissionAmount": "0", "leverage": 1, "fillFactor": "0", "takeProfit": null, "stopLoss": null, "comment": null } ] } ``` ## Get open positions [#get-open-positions] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenPositions"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenPositions", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.item`** `array of objects` The array of position objects. **`item.item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.item.marketDisplayName`** `string` The market ticker. **`item.item.marketFullName`** `string` The market full name or description (optional). **`item.item.createdAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. **`item.item.updatedAt`** `dateTime` The timestamp of the most recent update to the position, in ISO 8601 format. **`item.item.side`** `string` The position side. Possible values: * `Buy` * `Sell` **`item.item.status`** `string` The current position status. Always `"Open"`. **`item.item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when opening the position. **`item.item.positionLotAmount`** `decimal string` The position volume, in lots. **`item.item.positionPriceInRAT`** `decimal string` The current position price, in conversion to RAT. **`item.item.rateToRAT`** `decimal string` The current exchange rate of a quote asset to RAT. **`item.item.usedMarginInRAT`** `decimal string` The amount of trader’s funds used for maintaining a position, in conversion to RAT. **`item.item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.item.currentMarketPrice`** `decimal string` The current market price of the base asset: bid for Long positions and ask for Short positions. **`item.item.unrealizedPnlDayInRAT`** `decimal string` The potential profit or loss earned for a current day, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. **`item.item.unrealizedPnlDayPercent`** `decimal string` The potential profit or loss earned for a current day, in percents. **`item.item.unrealizedPnlTotalInRAT`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). **`item.item.unrealizedPnlTotalPercent`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT, in percents. **`item.item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.item.stopLoss`** `decimal string` The Stop Loss price, if set. **`item.item.positionModifier`** `string` The reason for the latest position update. **`item.item.comment`** `string | nullable` The text note inherited from the opening order, up to 100 characters. **`snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "item": [ { "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-03-12T06:36:31.257Z", "updatedAt": "2025-03-12T06:36:31.257Z", "side": "Buy", "status": "Open", "leverage": 1, "positionLotAmount": "0.01", "positionPriceInRAT": "1000.46", "rateToRAT": "1.07", "usedMarginInRAT": "1000.53", "openPrice": "0.96304", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "1.86", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-29.93", "unrealizedPnlTotalPercent": "-0.0291", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null }, { "positionId": "01JVQB9ZWJ6G4QV0P98X0QWNA7", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-05-20T17:19:21.49Z", "updatedAt": "2025-05-20T17:19:21.491321Z", "side": "Buy", "status": "Open", "leverage": 100, "positionLotAmount": "0.1", "positionPriceInRAT": "10004.6", "rateToRAT": "1.07", "usedMarginInRAT": "100.06", "openPrice": "0.93666", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "18.61", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-17.02", "unrealizedPnlTotalPercent": "-0.0017", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null } ], "snapshot": false } } ``` ## Get closed positions [#get-closed-positions] ### Connection [#connection-2] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"ClosePositionsOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "ClosePositionsOrders", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of position objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.positionCloseLotAmount`** `decimal string` The closed volume, in lots, which is equivalent to the corresponding filled order volume. **`item.reason`** `string` The reason for position closing. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.realizedPnlInRAT`** `decimal string` The actual profit or loss earned, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). **`item.closedAt`** `dateTime` The timestamp when the position was closed, in ISO 8601 format. **`item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`item.positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`item.rateToRAT`** `decimal string` The conversion rate to RAT. **`item.openedAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketFullName": "", "marketDisplayName": "EUR/CHF", "marketType": "Cfd", "orderId": "01JVSQ8WFA3QZ6AQTKYPXVXDWA", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.01", "reason": "Trader", "realizedPnlInRAT": "-29.25", "closedAt": "2025-05-21T15:26:57.0027785Z", "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "openPrice": "0.96304", "closePrice": "0.93571", "positionPriceInRAT": "1001.2", "rateToRAT": "1.07", "openedAt": "2025-03-12T06:36:31.257Z" } ] } ``` ## Open positions [#open-positions] ### Get executions for an open position [#get-executions-for-an-open-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/executions/list` #### Summary [#summary] Use this method to retrieve execution details for a specific open position using its position identifier. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`positionId`** `required` The position identifier. ##### Body [#body] **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`offset`** `integer · int32 | nullable` The number of items to skip before starting to collect the result set. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PMT0VMJG5B8XBDNZ7FNM1F/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "offset": 0 } ``` #### Response [#response] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VNWB23GSRN2XQAJD6Q", "baseAmount": "0.314", "executionPrice": "4603.5", "commissionAmountInRAT": "0", "commissions": [], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VN1F2JPM14AEV6V8YJ", "baseAmount": "0.045", "executionPrice": "4603.49", "commissionAmountInRAT": "0", "commissions": [], "comment": null } ] } ``` ### Get executions for open positions [#get-executions-for-open-positions] `POST` `/frontoffice/api/v4/positions/executions/list` #### Summary [#summary-1] Use this method to retrieve execution details for multiple open positions by providing an array of position identifiers. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`positionIds`** `array · string[]` The array of position identifiers. **`limit`** `integer · int32 | nullable` The maximum number of items to return. ```http title="Request example" POST /frontoffice/api/v4/positions/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "positionIds": [ "01K2PMT0VMJG5B8XBDNZ7FNM1F", "01K2PMXY63HESK110WT1CHMAFA" ], "limit": 5 } ``` #### Response [#response-1] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMXY63HESK110WT1CHMAFA", "orderId": "01K2PMXY1894RC6E2BYFR00T87", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:38:10.627Z", "executionId": "01K2PMXY63NXM30VNWPDECSFJR", "baseAmount": "15", "executionPrice": "4333.69288", "commissionAmountInRAT": "32.27", "commissions": [ { "assetId": "eur", "amount": "32.27" } ], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.292Z", "executionId": "01K2PMT0VMPCZW0JB2C9J6B405", "baseAmount": "0.141", "executionPrice": "4602.3", "commissionAmountInRAT": "5", "commissions": [ { "assetId": "eur", "amount": "5" } ], "comment": null } ] } ``` ## Closed positions [#closed-positions] ### Get orders for closed positions [#get-orders-for-closed-positions] `POST` `/frontoffice/api/v4/orders/closed-positions` #### Summary [#summary-2] Use this method to retrieve orders associated with closed positions within specified date ranges and market filters. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`createdAtFrom`** `string · date-time | nullable` The start date of the period when the positions were opened. **`createdAtTo`** `string · date-time | nullable` The end date of the period when the positions were opened. **`closedAtFrom`** `string · date-time | nullable` The start date of the period when the positions were closed. **`closedAtTo`** `string · date-time | nullable` The end date of the period when the positions were closed. **`marketId`** `string | nullable` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`marketType`** `string | nullable` The market type. Possible values: * `Cfd` * `Perp` **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastOrderId`** `string | nullable` The identifier of the final order to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/closed-positions HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "createdAtFrom": "2025-08-01T12:00:32.886Z", "createdAtTo": "2025-08-15T12:00:32.886Z" } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier. **`marketFullName`** `string | nullable` The market full name or description (optional). **`marketDisplayName`** `string | nullable` The market ticker. **`marketType`** `string` The market type. Possible values: * `Cfd` * `Perp` **`orderId`** `string` The order identifier. **`orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`timeInForce`** `string` The [time-in-force setting](../get-started/time-in-force) of the order. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`side`** `string` The order side. Possible values: * `Buy` * `Sell` **`positionCloseLotAmount`** `decimal string` The position amount closed by the order, in lots. **`reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`closedAt`** `string · date-time | nullable` The date and time when the position was closed. **`positionId`** `string` The position identifier. **`openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`rateToRAT`** `decimal string` The conversion rate to RAT. **`openedAt`** `string · date-time` The date and time when the position was opened. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "data": [ { "marketId": "cfd.eth_eur", "marketFullName": null, "marketDisplayName": "CFD ETH/EUR", "marketType": "Cfd", "orderId": "01K2PNGX50SR1FRE6P14PJC17E", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "15", "reason": "Trader", "realizedPnlInRAT": "-144.64", "closedAt": "2025-08-15T10:48:32.393Z", "positionId": "01K2PMXY63HESK110WT1CHMAFA", "openPrice": "4333.69288", "closePrice": "3370.58389", "positionPriceInRAT": "50558.75", "rateToRAT": "1", "openedAt": "2025-08-15T10:38:10.628Z", "comment": null }, { "marketId": "perp.eth_usdt", "marketFullName": "ETH/USDT_4s8hKqiPXmXOEhsO1J6W", "marketDisplayName": "ETH/USDT_jC6Im5PxwgZLrwyccRcI", "marketType": "Perpetual", "orderId": "01K2PNG3N6NKAJVV4RV5E2V0HK", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.5", "reason": "Trader", "realizedPnlInRAT": "13.42", "closedAt": "2025-08-15T10:48:06.234Z", "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "openPrice": "4603.1607", "closePrice": "4634.3915", "positionPriceInRAT": "1992.78", "rateToRAT": "0.86", "openedAt": "2025-08-15T10:36:02.293Z", "comment": null } ], "isExceeded": true } ``` ### Get executions for a closing order [#get-executions-for-a-closing-order] `POST` `/frontoffice/api/v5/orders/``{orderId}``/executions/list` #### Summary [#summary-3] Use this method to retrieve execution details for a specific position-closing order using its identifier. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The order identifier. ##### Body [#body-3] **`positionId`** `string | nullable` The position identifier. **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastExecutionId`** `string | nullable` The identifier of the final execution to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/01K2PNG3N6NKAJVV4RV5E2V0HK/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 5 } ``` #### Response [#response-3] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed amount of the base asset. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T19:02:22.196Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true } ], "isExceeded": true } ``` ### Get executions for closing orders [#get-executions-for-closing-orders] `POST` `/frontoffice/api/v5/orders/executions/list` #### Summary [#summary-4] Use this method to retrieve execution details for multiple position-closing orders by providing an array of order identifiers. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`orderId`** `string` The order identifier. **`positionId`** `string` The order identifier. ```http title="Request example" POST /frontoffice/api/v4/orders/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "orderPositionPairs": [ { "orderId": "01K31APDKZCVGWZA3XTF5JPAMD", "positionId": "01K31APDWF2EBHRKHH15VGB1ST" } ], "limit": 0 } ``` #### Response [#response-4] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T18:53:15.657Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true, "comment": null } ], "isExceeded": true } ``` ## Accounts [#accounts] ### Get accounts [#get-accounts] `GET` `/frontoffice/api/v3/accounts` #### Summary [#summary] Use this method to retrieve a list of all trading accounts with their basic information including account type and total balance. #### Request [#request] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/accounts HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response] In case of success, an array of objects will be returned. Each object contains the following information: **`accountId`** `string` The trading account identifier. **`publicAccountId`** `integer` The public account identifier for display purposes. **`accountName`** `string` The account name. **`accountType`** `string` The account type. Possible values: * `Hedging` * `Netting` **`accountStatus`** `string` The account status, which determines the permitted operations. For a description of each value, see [Account statuses](../get-started/account-statuses). Possible values: * `Active` * `Halted` * `Frozen` **`totalBalanceInRAT`** `decimal string` The total balance, in RAT. **`isCopyTradingAccount`** `boolean` Indicates if the account is `Copy`. ```json title="Response example — 200: OK" [ { "accountId": "685a7eaa360f9e7416221a61", "publicAccountId": 1234567, "accountName": "B2TRADER Hedging account", "accountType": "Hedging", "accountStatus": "Active", "totalBalanceInRAT": "6020.12", "isCopyTradingAccount": false }, { "accountId": "6891e70db552ff9c6fbbccf5", "publicAccountId": 1234568, "accountName": "B2TRADER Netting account", "accountType": "Netting", "accountStatus": "Halted", "totalBalanceInRAT": "10987.39", "isCopyTradingAccount": false } ] ``` ## Assets [#assets] ### Get assets [#get-assets] `GET` `/frontoffice/api/v3/assets` #### Summary [#summary-1] Use this method to retrieve a list of available assets on the platform. #### Request [#request-1] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-1] In case of success, an array of objects will be returned. Each object contains the following information: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`isRootAsset`** `boolean` Indicates whether this is a root asset. ```json title="Response example — 200: OK" [ { "assetId": "usdt", "assetName": "Tether", "isRootAsset": true }, { "assetId": "xrp", "assetName": "Ripple", "isRootAsset": false } ] ``` ## Markets [#markets] ### Get markets [#get-markets] `GET` `/frontoffice/api/v6/markets` #### Summary [#summary-2] Use this method to retrieve a list of available markets with their type, subtype, and favorite status. #### Request [#request-2] ##### Query parameters [#query-parameters] **`categoryId`** The market category identifier. **`dynamicCommissionGroupId`** The dynamic commission group identifier. **`isFavorite`** `boolean` Filter by favorite status. If set to `true`, only markets marked as favorites are returned. ```http title="Request example" GET /frontoffice/api/v6/markets?isFavorite=true HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} ``` #### Response [#response-2] In case of success, an array of market objects is returned. Each market object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description. **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" [ { "marketId": "spot.btc_usdt", "displayName": "BTC/USDT", "fullName": null, "type": "Spot", "subtype": null, "isFavorite": true }, { "marketId": "cfd.eth_btc", "displayName": "ETH/BTC", "fullName": "Ethereum to Bitcoin", "type": "Cfd", "subtype": "Crypto", "isFavorite": false }, { "marketId": "perp.trx_usdt", "displayName": "TRX/USDT", "fullName": "TRX to Tether Perpetual", "type": "Perpetual", "subtype": null, "isFavorite": false } ] ``` ### Get market [#get-market] `GET` `/frontoffice/api/v6/markets/``{marketId}` #### Summary [#summary-3] Use this method to retrieve detailed information about a specific market using its market identifier. #### Request [#request-3] ##### Path parameters [#path-parameters] **`marketId`** `required` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```http title="Request example" GET /frontoffice/api/v6/markets/{marketId} HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description (optional). **`baseAssetId`** `string` The base asset identifier. **`quoteAssetId`** `string` The quote asset identifier. **`minAmount`** `decimal string | nullable` *Applicable to Spot markets only.* The minimum tradable amount of the base asset. **`maxBaseAmount`** `decimal string | nullable` The maximum tradable amount of the base asset. **`priceDeviation`** `decimal string` The allowed price deviation for Limit orders placed on the market. Supports decimal values in the range `[0, 1]`, with up to 4 decimal places, for example: * `0.1` = 10% * `0.01` = 1% * `0.001` = 0.1% * `0.0001` = 0.01% If set to `0`, no restriction is applied, the price deviation is ignored. **`priceScale`** `integer` The price precision, which is the number of digits after a decimal separator. Also determines the minimum allowed trade price. Supports only integer values in the range `[2, 8]`. For example, `2` means the following price format: `0.01`, and `8`: `0.00000001`. **`amountScale`** `integer | nullable` *Applicable to Spot markets only.* The amount precision, which is the number of digits after a decimal separator. Also determines the minimum trade amount. Supports only integer values in the range `[0, 8]`. For example: * `0` means `1` (no digits after the decimal separator) * `5` means `0.00001` (five digits after the decimal separator) * `8` means `0.00000001` (eight digits after the decimal separator) **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`swapSettings`** `object | nullable` *Applicable to CFD markets only.* The fee type charged for holding open positions overnight. The amount can be negative for rebates. Possible values: * `FixPerLot`: The fixed amount per lot. * `Percent`: The fixed amount in points which is applied to the position size, in the range `[-1, 1]`, with up to 5 decimal places. * `Points`: The fixed amount of percents which is applied to the position size, with up to 3 decimal places. Structure: * **`type`** `string` — Swap calculation type. Possible values: `FixPerLot`, `Percent`, `Points`. * **`shortPositionSettings`** `object` — Settings for Short positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` * **`longPositionSettings`** `object` — Settings for Long positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` **`lotSize`** `integer | nullable` *Not applicable to Spot markets.* The standardized quantity of the base asset per lot. Supports only integer values in the range `[1, 1000000]`. **`minLotAmount`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum order amount, in lots, that can be placed and executed. Supports values in the range `[0.00000001, 1]`. **`maxLotAmount`** `integer | nullable` *Not applicable to Spot markets.* The maximum order amount, in lots, that can be placed and executed. Supports only integer values in the range `[1, 10000]`. **`tickSize`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum price increment. **`lotStep`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum lot amount increment. Supports values in the range `[0.00000001, 1]`. By default, equals to the `minLotAmount`. **`slippageRate`** `decimal string` The expected slippage, that is, the difference between the expected execution price and the actual one. This value is used as a multiplier to calculate the funds to be put on hold for a market order execution. Supports values in the range `[1, 10]`, including decimal values with up to 4 decimal places. The default value is `1` which means that only the current bid/ask price is put on hold. For example, `1.1` means that the current bid or ask price + 10% is put on hold for each order, to cover the 10% slippage. **Mind that** the total amount funds to be held depends on the order parameters and takes into account many conditions, the slippage rate is only one of them. **`calendar`** `object` The trading calendar defining market trading hours. Structure: * **`timeZoneId`** `string` — IANA time zone identifier. * **`tradingSessions`** `array` — Weekly trading sessions: * **`dayOfWeek`** `string` — One of: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. * **`timeIntervals`** `array` — List of intervals with: * **`start`** `string` (time) — Start time in `calendar.timeZoneId`. * **`end`** `string` (time) — End time in `calendar.timeZoneId`. * **`sessionOverrides`** `array` — Optional specific-date overrides: * **`date`** `string` (date) — In `YYYY-MM-DD` format. * **`timeIntervals`** `array | nullable` — Intervals for that date. **`fundingStartTime`** `string | nullable` *Applicable to Perpetual markets only.* The time of the first funding settlement, in the following format: `HH:MM:SS`. **`fundingIntervalInHours`** `integer | nullable` *Applicable to Perpetual markets only.* The funding settlement interval, in hours. Possible values: 1, 2, 3, 4, 6, 8, 12, 24. **`leverageProfile`** `object` *Not applicable to Spot markets.* The leverage profile. Structure: * **`leverageType`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`leverage`** `object` * **`useOnlyMaxLeverage`** `boolean` * **`maxLeverage`** `integer` — For `Fixed` leverage type only. * **`tiers`** `array` — For `Dynamic` leverage type only. * **`maxLeverage`** `integer` — The maximum allowed leverage for this tier. * **`maxNotionalValueInRAT`** `string | nullable` — The maximum position notional for this tier. **`commissionSettings`** `object` The commission settings. Structure: * **`type`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`charge`** `object` * **`type`** `string` — Possible values: `Percent`, `FixPerLot`. * **`assetId`** `string | nullable` — For `Fixed` commission type only. * **`size`** `decimal string` — For `Fixed` commission type only. * **`tiers`** `array` — For `Dynamic` commission type only. * **`size`** `string` — The commission amount for this tier. * **`minTradingVolumeInRAT`** `string` — The minimum required trading volume for this tier. * **`minCommissionInRAT`** `decimal string | nullable` * **`dynamicCommissionGroupId`** **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" { "marketId": "string", "displayName": "string", "fullName": "string", "baseAssetId": "string", "quoteAssetId": "string", "minAmount": "string", "maxBaseAmount": "string", "minQuoteAmount": "string", "priceDeviation": "string", "priceScale": 0, "amountScale": 0, "type": "Spot", "subtype": "Cash", "swapSettings": { "type": "FixPerLot", "shortPositionSettings": { "size": "string", "assetId": "string" }, "longPositionSettings": { "size": "string", "assetId": "string" } }, "lotSize": 0, "minLotAmount": "string", "maxLotAmount": 0, "tickSize": "string", "lotStep": "string", "slippageRate": "string", "calendar": { "timeZoneId": "string", "tradingSessions": [ { "dayOfWeek": "Monday", "timeIntervals": [ { "start": "string", "end": "string" } ] } ], "sessionOverrides": [ { "date": "2025-12-18", "timeIntervals": [ { "start": "string", "end": "string" } ] } ] }, "fundingStartTime": "string", "fundingIntervalInHours": 0, "leverageProfile": { "leverageType": "Fixed", "leverage": { "useOnlyMaxLeverage": true, "maxLeverage": 0 } }, "commissionSettings": { "type": "Dynamic", "сharge": { "type": "Percent", "tiers": [ { "size": "string", "minTradingVolumeInRAT": "string" }, { "size": "string", "minTradingVolumeInRAT": "string" } ], "minCommissionInRAT": "string" }, "dynamicCommissionGroupId": "string" }, "isFavorite": true } ``` *** ### Add favorite market [#add-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/add` #### Summary [#summary-4] Add a market to the current user's favorites list. #### Request [#request-4] ##### Body [#body] **`marketId`** `string` `required` The market identifier to add to favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/add HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-4] In case of success (`200`), an empty object is returned. *** ### Remove favorite market [#remove-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/delete` #### Summary [#summary-5] Remove a market from the current user's favorites list. #### Request [#request-5] ##### Body [#body-1] **`marketId`** `string` `required` The market identifier to remove from favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/delete HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-5] In case of success (`200`), an empty object is returned. ## Account margin settings [#account-margin-settings] ### Get margin assets [#get-margin-assets] `GET` `/frontoffice/api/v4/account-margin-settings/assets` #### Summary [#summary-6] Use this method to retrieve a list of assets that can be used as collateral for margin trading. #### Request [#request-6] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v4/account-margin-settings/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`assets`** `array` A list of assets that can be used as a collateral for margin trading. Each array item contains: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`total`** `decimal string` The overall amount of the asset, including locked funds. **`marginRatio`** `decimal string` The percentage of the asset value used as a collateral. Supports values in the range `[0, 1]`, where `1` represents 100.00%. **`isSelected`** `boolean` Indicates whether the asset is selected to be used as collateral. Can be `true` only for assets with the `marginRatio` more than `0`. ```json title="Response example — 200: OK" { "assets": [ { "assetId": "btc", "assetName": "btc", "available": "0.031", "total": "0.031", "marginRatio": "1", "isSelected": true }, { "assetId": "eth", "assetName": "eth", "available": "0", "total": "0", "marginRatio": "1", "isSelected": false } ] } ``` ### Select margin asset [#select-margin-asset] `POST` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-7] Use this method to enable a particular asset to be used as collateral for margin trading. Only assets with the `marginRatio` more than `0` can be selected. #### Request [#request-7] ##### Path parameters [#path-parameters-1] **`assetId`** `required` The asset identifier. ```http title="Request example" POST /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json Accept: */* {} ``` #### Response [#response-7] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ### Disable margin asset [#disable-margin-asset] `DELETE` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-8] Use this method to prohibit a specific asset from being used as collateral for margin trading. #### Request [#request-8] ##### Path parameters [#path-parameters-2] **`assetId`** `required` The asset identifier. ```http title="Request example" DELETE /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-8] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ## Info [#info] ### Get server info [#get-server-info] `GET` `/frontoffice/api/v3/info` #### Summary [#summary-9] Use this method to retrieve current server time and timezone information. #### Request [#request-9] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`serverTime`** `string` The server time, in the Unix timestamp format. **`serverTimeZone`** `string` The server time zone. ```json title="Response example — 200: OK" { "serverTime": "1755190380", "serverTimeZone": "+00:00" } ``` ### Get server time zones [#get-server-time-zones] `GET` `/frontoffice/api/v3/info/time-zones` #### Summary [#summary-10] Use this method to retrieve available server time zones. #### Request [#request-10] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info/time-zones HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-10] In case of success, an array of objects will be returned. Each object contains the following information: **`id`** `string` The time zone identifier. **`offset`** `string` The UTC offset, in the following format: `HH:MM:SS`. **`offsetInMinutes`** `integer · int32` The UTC offset in minutes. **`shortLabel`** `string` The short label for the time zone. **`label`** `string` The display label for the time zone. ```json title="Response example — 200: OK" [ { "id": "Africa/Abidjan", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Abidjan", "label": "(UTC+00:00) Côte d’Ivoire Time" }, { "id": "Africa/Algiers", "offset": "01:00:00", "offsetInMinutes": 60, "shortLabel": "Africa/Algiers", "label": "(UTC+01:00) Central European Time (Algiers)" }, { "id": "Africa/Bissau", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Bissau", "label": "(UTC+00:00) Guinea-Bissau Time" }, ... ] ``` ## Webhooks [#webhooks] ### Create webhook API key [#create-webhook-api-key] `POST` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-11] Create a new webhook API key for receiving TradingView alerts. #### Request [#request-11] ##### Header parameters [#header-parameters] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Body [#body-2] **`name`** `string` `required` A descriptive name for the API key, up to 100 characters. ```http title="Request example" POST /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "name": "My TradingView Key" } ``` #### Response [#response-11] In case of success (`201`), the created API key object is returned. **`id`** `string` The unique identifier of the API key. **`apiKey`** `string` The full API key value. The key is shown only once at creation. **`name`** `string` The name assigned to the key. **`userId`** `string` The user identifier the key is bound to. **`status`** `string` The key status: `Active`. **`createdAt`** `string` The timestamp when the key was created. **`expiresAt`** `string` The timestamp when the key expires (one year from creation). ```json title="Response example" { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "apiKey": "wh_key_abc123def456...", "name": "My TradingView Key", "userId": "01JZ3CVZKN20410JPYYH1YZJSK", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ``` The API key is shown only once in the creation response. It can't be retrieved again after this call. *** ### List webhook API keys [#list-webhook-api-keys] `GET` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-12] Retrieve all webhook API keys for the authenticated user along with the webhook URL. #### Request [#request-12] ##### Header parameters [#header-parameters-1] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ```http title="Request example" GET /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-12] In case of success (`200`), the webhook URL and a list of API keys are returned. **`webhookUrl`** `string` The webhook URL to configure in TradingView alerts. **`apiKeys`** `array of objects` The list of API keys. **`apiKeys[].id`** `string` The unique identifier of the API key. **`apiKeys[].name`** `string` The name assigned to the key. **`apiKeys[].status`** `string` The key status. Possible values: * `Active` * `Revoked` * `Expired` **`apiKeys[].createdAt`** `string` The timestamp when the key was created. **`apiKeys[].expiresAt`** `string` The timestamp when the key expires. ```json title="Response example" { "webhookUrl": "https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3...", "apiKeys": [ { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "name": "My TradingView Key", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ] } ``` *** ### Revoke webhook API key [#revoke-webhook-api-key] `DELETE` `/frontoffice/api/v3/webhook/api-keys/{id}` #### Summary [#summary-13] Revoke an active webhook API key. After revocation, the key can no longer be used to authenticate webhook requests. #### Request [#request-13] ##### Header parameters [#header-parameters-2] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Path parameters [#path-parameters-3] **`id`** `string` `required` The unique identifier of the API key to revoke. ```http title="Request example" DELETE /frontoffice/api/v3/webhook/api-keys/01JZ3CVZKN20410JPYYH1YZJSK HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-13] In case of success (`200`), a confirmation object is returned. **`success`** `boolean` Indicates whether the key was revoked successfully. **`message`** `string` A description of the result. ```json title="Response example" { "success": true, "message": "API key revoked successfully" } ``` *** ### Receive TradingView alert [#receive-tradingview-alert] `POST` `/frontoffice/api/v3/webhook/alerts/{userId}` #### Summary [#summary-14] Accept a webhook alert from TradingView and place an order on the specified trading account. TradingView calls this endpoint when an alert triggers. #### Request [#request-14] ##### Path parameters [#path-parameters-4] **`userId`** `string` `required` The B2TRADER user identifier (ULID format). ##### Body [#body-3] **`apiKey`** `string` `required` The webhook API key for authentication. **`accountId`** `string` `required` The trading account identifier. **`symbol`** `string` `required` The market symbol with a type prefix (`spot.`, `cfd.`, or `perp.`) followed by the pair name. For example: `spot.btc_usdt`, `cfd.eur_usd`, `perp.btc_usdt`. **`side`** `string` `required` The order side. Possible values: * `buy` * `sell` **`quantity`** `decimal string` `required` The order quantity in the base asset. **`orderType`** `string` The order type. Default: `market`. Possible values: * `market` * `limit` * `stop` * `stop_limit` **`price`** `decimal string` The limit price. Required for `limit` and `stop_limit` orders. **`stopPrice`** `decimal string` The stop price. Required for `stop` and `stop_limit` orders. **`leverage`** `decimal string` The leverage ratio. Applicable to CFD and Perpetual Futures markets only. **`takeProfit`** `decimal string` The take profit trigger price. **`stopLoss`** `decimal string` The stop loss trigger price. **`timeInForce`** `string` The time-in-force policy. Default: `gtc`. Possible values: * `gtc` * `ioc` * `fok` * `day` **`comment`** `string` A custom comment, up to 256 characters. **`deduplicationId`** `string` A UUID for idempotency. Duplicate requests with the same ID within five minutes return a cached response. ```http title="Request example" POST /frontoffice/api/v3/webhook/alerts/01JZ3CVZKN... HTTP/1.1 Host: {host} Content-Type: application/json { "apiKey": "wh_key_abc123def456...", "accountId": "01JZ3CVZKN20410JPYYH1YZJSK", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01", "comment": "TV Strategy Signal" } ``` #### Response [#response-14] In case of success (`200`), an order confirmation is returned. **`success`** `boolean` Indicates whether the order was placed successfully. **`orderId`** `string` The unique identifier of the created order. **`orderStatus`** `string` The initial status of the order. **`message`** `string` A description of the result. **`timestamp`** `string` The timestamp of the response. ```json title="Response example" { "success": true, "orderId": "01JZ3CVZKN20410JPYYH1YZJSK", "orderStatus": "Working", "message": "Order placed successfully", "timestamp": "2026-02-02T12:34:56.789Z" } ``` #### Rate limits [#rate-limits] Webhook requests are limited to five requests per second per user. If the limit is exceeded, the response returns a `429` status code with the following headers: * `X-RateLimit-Limit`: Maximum requests per window * `X-RateLimit-Remaining`: Remaining requests in the current window * `X-RateLimit-Reset`: Unix timestamp when the window resets ## Orders [#orders] ### Place SPOT order [#place-spot-order] `POST` `/frontoffice/api/v3/orders` #### Summary [#summary] Use this method to create and submit a new order for SPOT markets. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Body [#body] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Limit", "timeInForce": "Gtc", "requestedAmount": 0.02, "requestedPrice": 115193.35, "comment": "Strategy A" } } ``` #### Response [#response] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. Right after the order is created commission is `0`. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K1ZTB4DB0S6Y2NH81S781BQX", "orderType": "Limit", "side": "Buy", "status": "Pending", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.02", "remainingAmount": "0.02", "requestedPrice": "115193.35", "executionPrice": "0", "createdAt": "2025-08-06T13:50:13.931Z", "updatedAt": "2025-08-06T13:50:13.9325008Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Place CFD order [#place-cfd-order] `POST` `/frontoffice/api/cfd/v4/orders` #### Summary [#summary-1] Use this method to create and submit a new order for CFD markets. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "timeInForce": "Gtd", "requestedLotAmount": 1, "requestedPrice": 3280, "leverage": 75, "cancellationDate": "2025-08-10T00:00:00Z", "stopLoss": { "price": 3320, "isTrailing": false }, "takeProfit": { "price": 3200 }, "comment": "Strategy A" } } ``` #### Response [#response-1] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2253Q9X3VTJ68PNWY40JC6Q", "status": "Pending" } } ``` ### Place PF order [#place-pf-order] `POST` `/frontoffice/api/perpetual/v4/orders` #### Summary [#summary-2] Use this method to create and submit a new order for Perpetual markets. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `perp.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "perp.eth_usdt", "side": "Buy", "orderType": "Market", "timeInForce": "Ioc", "requestedLotAmount": 10, "leverage": 159, "comment": "Strategy A" } } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K228VN55N7WFZRG70M24T9J1", "status": "Working" } } ``` ### Cancel order [#cancel-order] `DELETE` `/frontoffice/api/v3/orders/``{orderId}` #### Summary [#summary-3] Use this method to cancel an active order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`orderId`** `required` The order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/orders/01K2PF9XS29WN4JZRHMCTTQYJB HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` * `StopOrder` * `FixApi` * `System` **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.eth_usdt", "marketDisplayName": "SPOT ETH/USDT", "orderId": "01K2PF9XS29WN4JZRHMCTTQYJB", "orderType": "Limit", "side": "Buy", "status": "Cancelled", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.1", "remainingAmount": "0.1", "requestedPrice": "4450", "executionPrice": "0", "createdAt": "2025-08-15T08:59:51.97Z", "updatedAt": "2025-08-15T09:00:06.2791048Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Get SPOT order data [#get-spot-order-data] `POST` `/frontoffice/api/v3/order-data` #### Summary [#summary-4] Use this method to retrieve and validate order data for SPOT market orders before placing. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-3] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.requestedBaseAmount`** `decimal string | nullable` The requested amount in base asset units. **`order.requestedQuoteAmount`** `decimal string | nullable` The requested amount in quote asset units. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. ```http title="Request example" POST /frontoffice/api/v3/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=3.0 Accept: */* { "order": { "marketId": "spot.eth_usdt", "side": "Buy", "orderType": "Limit", "requestedBaseAmount": 0.2, "requestedPrice": 4600 } } ``` #### Response [#response-4] In case of success, an object will be returned. Each object contains the following information: **`baseAmount`** `decimal string` The calculated base asset amount for the order. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmount`** `decimal string` The estimated commission amount to be charged. **`total`** `decimal string` The total quote asset amount, including the estimated commission. ```json title="Response example — 200: OK" { "order": { "baseAmount": "0.2", "quoteAmount": "920", "commissionAmount": "9.2", "total": "929.2" } } ``` ### Get CFD order data [#get-cfd-order-data] `POST` `/frontoffice/api/cfd/v4/order-data` #### Summary [#summary-5] Use this method to retrieve and validate order data for CFD market orders before placing. #### Request [#request-5] ##### Header parameters [#header-parameters-5] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables the Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/cfd/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": 15000, "triggerType": "points" }, "stopLoss": { "triggerSize": "4020", "triggerType": "price", "isTrailing": false }, "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Market", "leverage": 135, "requestedLotAmount": 1 } } ``` #### Response [#response-5] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "34.4613643", "quoteAmount": "4004.345", "commissionAmountInRAT": "0", "marginLevel": "5.3015", "takeProfit": { "price": "3989.345", "rate": "0.0037", "points": 15000, "pnl": "17.42713545" }, "stopLoss": { "price": "4020", "rate": "-0.0039", "points": -15655, "pnl": "-18.18812036" } } } ``` ### Get PF order data [#get-pf-order-data] `POST` `/frontoffice/api/perpetual/v4/order-data` #### Summary [#summary-6] Use this method to retrieve and validate order data for Perpetual market orders before placing. #### Request [#request-6] ##### Header parameters [#header-parameters-6] **`accountId`** `required` The trading account identifier. ##### Body [#body-5] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/perpetual/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": "0.01", "triggerType": "rate" }, "stopLoss": { "triggerSize": "-100", "triggerType": "pnl", "isTrailing": false }, "marketId": "perp.btc_usdt", "side": "Buy", "orderType": "Limit", "leverage": 100, "requestedLotAmount": 0.5, "requestedPrice": 118450 } } ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "592.25", "quoteAmount": "59225", "commissionAmountInRAT": "0", "marginLevel": "0.3582", "takeProfit": { "price": "119634.5", "rate": "0.01", "points": 11845, "pnl": "592.25" }, "stopLoss": { "price": "118250", "rate": "-0.0016", "points": -2000, "pnl": "-100" } } } ``` ## Stop orders [#stop-orders] ### Place SPOT Stop order [#place-spot-stop-order] `POST` `/frontoffice/api/v3/stop-orders` #### Summary [#summary-7] Use this method to create and submit a new Stop order for SPOT markets. #### Request [#request-7] ##### Header parameters [#header-parameters-7] **`accountId`** `required` The trading account identifier. ##### Body [#body-6] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Market", "activationPrice": 128000, "requestedAmount": 0.01, "timeInForce": "Ioc", "comment": "Strategy A" } } ``` #### Response [#response-7] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order, same as in the request. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K2MNC3BVR5WRTBEE9YWAS91K", "orderType": "Market", "side": "Buy", "requestedPrice": "0", "activationPrice": "128000", "requestedAmount": "0.01", "timeInForce": "Ioc", "status": "WaitingForActivation", "createdAt": "2025-08-14T16:07:25.8193038Z", "updatedAt": "2025-08-14T16:07:25.8193044Z", "cancellationDate": null, "comment": null } } ``` ### Place CFD Stop order [#place-cfd-stop-order] `POST` `/frontoffice/api/cfd/v4/stop-orders` #### Summary [#summary-8] Use this method to create and submit a new Stop order for CFD markets. #### Request [#request-8] ##### Header parameters [#header-parameters-8] **`accountId`** `required` The trading account identifier. ##### Body [#body-7] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "activationPrice": 3200, "requestedLotAmount": 0.5, "timeInForce": "Gtd", "leverage": 76, "requestedPrice": 3500, "cancellationDate": "2025-08-18T00:00:00Z", "stopLoss": { "price": "3900", "isTrailing": false }, "takeProfit": { "price": "3100" }, "comment": "Strategy A" } } ``` #### Response [#response-8] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNRWP2J1S8T9TKTCXWYY87", "status": "WaitingForActivation" } } ``` ### Place PF Stop order [#place-pf-stop-order] `POST` `/frontoffice/api/perpetual/v4/stop-orders` #### Summary [#summary-9] Use this method to create and submit a new Stop order for Perpetual markets. #### Request [#request-9] ##### Header parameters [#header-parameters-9] **`accountId`** `required` The trading account identifier. ##### Body [#body-8] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "perp.btc_usdt", "side": "Sell", "orderType": "Market", "activationPrice": 115000, "requestedLotAmount": 1, "timeInForce": "Fok", "leverage": 22, "stopLoss": { "price": "118020", "isTrailing": true }, "takeProfit": { "price": "113873" }, "comment": "Strategy A" } } ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNM0S8B2R9DS7BWJ8PGYPR", "status": "WaitingForActivation" } } ``` ### Cancel Stop order [#cancel-stop-order] `DELETE` `/frontoffice/api/v3/stop-orders/``{orderId}` #### Summary [#summary-10] Use this method to cancel an active Stop order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-10] ##### Header parameters [#header-parameters-10] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The Stop order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/stop-orders/01K2MNGAWPMQJ7WGATFSCAS1G4 HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-10] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. ```json title="Response example — 200: OK" { "order": { "marketId": "perp.btc_usdt", "marketDisplayName": "Perpetual BTC/USDT", "orderId": "01K2MNGAWPMQJ7WGATFSCAS1G4", "orderType": "Limit", "side": "Sell", "requestedPrice": "115100", "activationPrice": "115000", "requestedAmount": "1", "timeInForce": "Gtc", "status": "Rejected", "createdAt": "2025-08-14T16:09:44.5986099Z", "updatedAt": "2025-08-14T16:09:44.5986103Z", "cancellationDate": null } } ``` ## Positions [#positions] ### Close position [#close-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/close` #### Summary [#summary-11] Use this method to close a specific position entirely or partially. #### Request [#request-11] ##### Header parameters [#header-parameters-11] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-2] **`positionId`** `required` The position identifier to close. ##### Body [#body-9] **`closePositionLotAmount`** `decimal string | nullable` The portion of the position to close, in lots. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PFXDP1FWCJSGTX4GJ6JHM0/close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-11] In case of success, an object will be returned. Each object contains the following information: **`positionId`** `string` The position identifier. ```json title="Response example — 200: OK" { "positionId": "01K2PFXDP1FWCJSGTX4GJ6JHM0" } ``` ### Bulk close positions [#bulk-close-positions] `POST` `/frontoffice/api/v4/positions/bulk-close` #### Summary [#summary-12] Use this method to close multiple positions simultaneously based on different criteria such as all positions, positive PnL only, or negative PnL only. #### Request [#request-12] ##### Header parameters [#header-parameters-12] **`accountId`** `required` The trading account identifier. ##### Body [#body-10] **`mode`** `string` `required` The bulk close mode. Possible values: * `AllPositions` — close all positions. * `PositivePnl` — close only positions with positive PnL. * `NegativePnl` — close only positions with negative PnL. ```http title="Request example" POST /frontoffice/api/v4/positions/bulk-close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "mode": "AllPositions" } ``` #### Response [#response-12] In case of success, an object will be returned containing identifiers of closed positions. ```json title="Response example — 200: OK" { "status": "accepted", "positionIds": [ "01K228VNC2Q7E7K9W8GABWBZ5Z", "01K22BZ2DCETJZKW6MK81N1T8Y", "01K2CXF06A3A5SK2YFJT67CMZ5", "01K2CXF2ZJ6MJYMEK663TBBY8K", "01K2PFXDP1FWCJSGTX4GJ6JHM0" ] } ``` ### Get trigger data [#get-trigger-data] `POST` `/frontoffice/api/v4/positions/``{positionId}``/trigger-data` #### Summary [#summary-13] Use this method to retrieve Stop loss and Take profit settings for an open position. #### Request [#request-13] ##### Header parameters [#header-parameters-13] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-3] **`positionId`** `required` The position identifier. ##### Body [#body-11] **`stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`stopLoss.isTrailing`** `boolean | nullable` Indicates if Stop loss is Trailing. **`takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/trigger-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "triggerSize": "-0.01", "triggerType": "rate", "isTrailing": true }, "takeProfit": { "triggerSize": 2500, "triggerType": "points" } } ``` #### Response [#response-13] In case of success, an object will be returned. Each object contains the following information: **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "takeProfit": { "price": "248.27", "rate": "0.1119", "points": 2500, "pnl": "21.5" }, "stopLoss": { "price": "221.04", "rate": "-0.01", "points": -223, "pnl": "-1.91" } } ``` ### Submit triggers [#submit-triggers] `PUT` `/frontoffice/api/v4/positions/``{positionId}``/triggers` #### Summary [#summary-14] Use this method to modify Stop loss and Take profit settings for an open position. #### Request [#request-14] ##### Header parameters [#header-parameters-14] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-4] **`positionId`** `required` The position identifier. ##### Body [#body-12] **`stopLoss.price`** `decimal string` The Stop loss trigger price. **`stopLoss.isTrailing`** `boolean` If `true`, enables the Trailing behavior for Stop loss. **`takeProfit.price`** `decimal string` The Take profit trigger price. ```http title="Request example" PUT /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/triggers HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "price": "165.13", "isTrailing": true }, "takeProfit": { "price": 250 } } ``` #### Response [#response-14] In case of success, an object will be returned containing the identifier of the updated position. ```json title="Response example — 200: OK" { "positionId": "01K2HYXA7N2G9NHTFEWYVM9SEQ" } ``` ## Commissions [#commissions] ### Get account trading volume [#get-account-trading-volume] `GET` `/frontoffice/api/v3/commission/``{dynamicCommissionGroupId}``/account-trading-volume` #### Summary [#summary-15] Use this method to obtain a cumulative account trading volume used for calculating the commission tier. #### Request [#request-15] ##### Header parameters [#header-parameters-15] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-5] **`dynamicCommissionGroupId`** `required` The dynamic commission group identifier. Use [Get market](settings#get-market) to obtain. ```http title="Request example" GET /frontoffice/api/v3/commission/{dynamicCommissionGroupId}/account-trading-volume HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-15] In case of success, an object will be returned containing current trading volume, in RAT, for the account. ```json title="Response example — 200: OK" { "currentTradingVolumeInRAT": "string" } ``` You can connect B2Trader to **ChatGPT** as a **connector**. It uses the same B2Trader MCP URL and OAuth sign-in as every other agent. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in ChatGPT's connector directory. Connector availability depends on your ChatGPT plan. ## Connect the B2Trader connector [#connect-the-b2trader-connector] 1. In ChatGPT, open **Settings** → **Connectors**. 2. Choose to add a connector by **URL** (custom connector). 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Confirm. ChatGPT reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — no API key is pasted into ChatGPT. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. ChatGPT lists the connector as connected, and the B2Trader tools become available to it. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — ChatGPT receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and ChatGPT stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector appears as connected in ChatGPT's settings. * B2Trader tools are available to ChatGPT in your chats. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In ChatGPT, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). You can connect B2Trader to **Claude** in two places: * **claude.ai** (web and desktop app) — add B2Trader as a **custom connector**. * **Claude Desktop** — add B2Trader as an MCP server; the OAuth sign-in completes through Claude's hosted redirect (`https://claude.ai/api/mcp/auth_callback`). Both use the same B2Trader MCP URL and the same OAuth sign-in. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in Claude's connector directory. ## Connect on claude.ai [#connect-on-claudeai] 1. Open **Settings** → **Connectors** in claude.ai. 2. Click **Add custom connector**. 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Click **Add**. Claude reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — you are **not** pasting an API key into Claude. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. Claude shows the connector as **Connected**, and the B2Trader tools appear in the tool list for your conversations. ## Connect in Claude Desktop [#connect-in-claude-desktop] 1. Open **Claude Desktop** → **Settings** → **Connectors**. 2. Add a new MCP server pointing at the B2Trader MCP URL for your surface. 3. Claude Desktop opens your browser for OAuth sign-in and completes the flow through Claude's **hosted** redirect (`https://claude.ai/api/mcp/auth_callback`), a pre-registered redirect URI. 4. Sign in and — for full access — approve the consent screen. 5. The B2Trader tools appear in Claude Desktop once the connector reports **Connected**. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — Claude receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and Claude stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector is listed as **Connected** in Claude's settings. * B2Trader tools (for example `trader_get_accounts`, plus platform market-data and portfolio tools) are available to Claude in your conversations. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In Claude, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). If you are building your own agent (for example with an Agent SDK) or using an MCP client that is not Claude or ChatGPT, you connect to the same two B2Trader endpoints and the same OAuth flow. This page covers the OAuth details a custom client needs. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` `` is the domain you open your B2Trader terminal on, not a separate API address. ## OAuth discovery [#oauth-discovery] Your client needs no B2Trader-specific configuration beyond the MCP URL. B2Trader is an OAuth 2.1 protected resource and advertises everything a compliant client needs: 1. Your client calls the MCP endpoint without a token and receives `401 Unauthorized` with a `WWW-Authenticate: Bearer resource_metadata="…"` header. 2. That header points at the protected-resource metadata (RFC 9728) for the surface you called — each surface has its own document: `https:///.well-known/oauth-protected-resource/mcp-read-only` and `https:///.well-known/oauth-protected-resource/mcp-full-access`. Fetching it returns the resource identifier, the authorization server (your broker's Keycloak realm), and `scopes_supported` — one scope only, matching the surface: `[mcp:read]` for `/mcp-read-only`, `[mcp:trade]` for `/mcp-full-access`. 3. Your client runs the standard OAuth 2.1 **authorization-code flow with PKCE** against that authorization server, requesting the scope for the surface you want. 4. B2Trader validates the token's audience (`bbp-mcp`) and the required scope (`mcp:read` for read-only, `mcp:trade` for full access) before serving any tool. Use a compliant MCP client library — it performs discovery, PKCE, and token refresh for you. You only supply the MCP URL. ## Pre-registered OAuth clients [#pre-registered-oauth-clients] B2Trader ships two pre-registered public OAuth clients. Use the one matching your surface: | Surface | `client_id` | Scope | Consent | | ----------- | ----------------- | ----------- | ---------------------------- | | Read-only | `mcp-read-only` | `mcp:read` | None | | Full access | `mcp-full-access` | `mcp:trade` | Explicit trade-scope consent | Both are **public** clients (no client secret) and require **PKCE (S256)**. A custom client authenticates as one of these `client_id`s and completes the browser sign-in as any other agent does. Depending on how your broker set up your platform, the page that opens is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account — your client behaves the same either way. ## Command-line agents (Codex CLI, Claude Code) [#command-line-agents-codex-cli-claude-code] Command-line MCP clients default to **Dynamic Client Registration (DCR)** — on first connect they try to register a brand-new OAuth client with the authorization server instead of using a fixed `client_id`. The B2Trader Keycloak realm does not permit anonymous DCR, so these tools must be told to use one of the pre-registered `client_id`s above: * **Codex CLI:** ```bash codex mcp add --url --oauth-client-id mcp-full-access codex mcp login ``` Use `mcp-read-only` in place of `mcp-full-access` for the read-only surface. * **Claude Code:** ```bash claude mcp add --transport http --client-id mcp-full-access --callback-port 8080 ``` Without an explicit `client_id`, both tools fall back to anonymous DCR, which the authorization server rejects — the connection fails before you reach the sign-in page. ## Redirect URIs [#redirect-uris] The pre-registered clients accept these redirect URIs: | Redirect URI | Use | | ------------------------------------------------------- | ----------------------------------------------------- | | `https://claude.ai/api/mcp/auth_callback` | Claude (claude.ai) | | `https://chatgpt.com/connector_platform_oauth_redirect` | ChatGPT | | `http://localhost:8080/*` | Claude Code — fixed callback port | | `http://127.0.0.1/*` | Codex CLI and other loopback clients — ephemeral port | If your custom agent runs locally, use one of the loopback redirects above. Most Agent SDKs and MCP client libraries (including Codex CLI) default to an ephemeral-port loopback callback on `127.0.0.1`, matching `http://127.0.0.1/*`, so no configuration change is needed. Claude Code is the exception: it needs a **fixed** callback port to match a registered redirect, so pass `--callback-port 8080` (matching `http://localhost:8080/*`) as shown above. ## Adding a custom redirect URI (broker step) [#adding-a-custom-redirect-uri-broker-step] If your agent runs on a hosted callback URL that is **not** one of the above (for example a server-side agent with its own public redirect), your broker must add that redirect URI to the pre-registered client in Keycloak before sign-in will succeed. A redirect URI that is not registered on the client fails at the sign-in step with an "Invalid redirect URI" error from Keycloak. Send your broker the exact callback URL your agent uses and which surface it needs (read-only or full access). Adding a redirect URI is a broker-side change to the MCP client registration. It requires no product change and is the documented path for onboarding custom, non-marketplace agents. ## Full access [#full-access] If your custom agent uses the full-access surface, the same [full-access safety](full-access-safety) rules apply: no per-action confirmation, irreversible actions, and the prompt-injection risk of an autonomous agent. Read that page before granting `mcp:trade`. The full-access surface (`/mcp-full-access`) lets a connected AI agent trade on your account **directly**. This page explains exactly what that means and how to stay in control. Read it before you approve the full-access consent screen. Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. ## No per-action confirmation [#no-per-action-confirmation] The in-terminal **AI Assistant chat** asks you to confirm each trade before it executes. The full-access MCP surface does **not**. Once connected, the agent can place, cancel, and close orders and set price triggers on its own, as fast as it decides to — there is no confirmation dialog and no "are you sure?" step. ## Actions are irreversible [#actions-are-irreversible] Trades execute against the live market. A filled order, a closed position, or a cancelled order **cannot be undone**. If your agent makes a mistake — or is manipulated into one — the market result stands. ## Prompt-injection risk [#prompt-injection-risk] An autonomous agent acts on the text it reads. If your agent processes untrusted content — a web page, an email, a chat message, a document — that content can contain hidden instructions telling the agent to trade against your interest. This is called **prompt injection**. Because the full-access surface has no confirmation gate, a successful injection can move real money before you notice. To reduce the risk: * Prefer the **read-only** surface unless you specifically need the agent to trade. * Only grant full access to agents and workflows you trust and control. * Be cautious about letting a full-access agent read untrusted external content in the same session it can trade. ## How to stop your agent [#how-to-stop-your-agent] You have two independent controls. Use either — or both. 1. **Stop it in the agent (fastest).** Disconnect or remove the B2Trader connector in your agent (Claude, ChatGPT, or your custom client). The agent immediately stops making new calls. 2. **Revoke the grant in B2Trader.** Open your **account console** (your broker's Keycloak account page) → **Applications**, find the connected MCP application, and **revoke** its access. This removes your consent so the agent cannot obtain a new token. There is no broker-side "kill switch" that instantly voids a token already in the agent's hands. A token the agent already holds stays valid until it expires (see [Access tokens are short-lived](#access-tokens-are-short-lived)). Revoking in the account console stops **new** tokens; disconnecting in the agent stops it using the one it has. Do both to be certain. ## You still get execution notifications [#you-still-get-execution-notifications] Every order the agent places, cancels, or closes fires the **same account notifications** you already receive for terminal activity. Your normal notification channels keep working, so a full-access agent cannot act silently — watch them to see what your agent is doing. ## Access tokens are short-lived [#access-tokens-are-short-lived] The agent's access token has a **short lifetime**. If you revoke consent in the account console, the agent can finish using its current token but cannot get a new one once it expires — so a revoked grant fully lapses within the token's short window, without any forced server-side revocation. ## Choosing read-only instead [#choosing-read-only-instead] If you do not need the agent to trade, connect the **read-only** surface (`/mcp-read-only`) instead. Its tools cannot place or change anything — the trading tools are not part of that surface at all. See [Overview](overview) for the comparison. B2Trader can expose your trading account to external AI agents through the **Model Context Protocol (MCP)** — an open standard that lets AI applications such as Claude and ChatGPT call a defined set of tools on your behalf. Once you connect an agent, it can read your market data and portfolio, and — on the full-access surface — place and manage orders directly. This is different from the **in-terminal AI Assistant chat**, which runs inside the B2Trader terminal and confirms each trade with you before it executes. An external MCP agent runs in *its own* application (Claude, ChatGPT, or your own client) and connects to B2Trader over the internet using your account sign-in. Connecting an AI agent is optional — it's your choice whether to use it. The MCP surfaces are available by default, though your broker can restrict or disable them for your platform. The MCP endpoints live on the same domain you use to open your B2Trader terminal, so wherever these pages show `https:///…`, that means your terminal address — not a separate API address. If a connection URL below doesn't work, contact your broker. ## Two surfaces [#two-surfaces] B2Trader publishes **two** separate MCP endpoints. You choose one when you connect your agent. | | Read-only | Full access | | ------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Endpoint path** | `/mcp-read-only` | `/mcp-full-access` | | **What the agent can do** | View market data, your portfolio, order and position history, and analytics | Everything in read-only **plus** place, cancel, and close orders and set price triggers | | **Tools exposed** | 23 | 39 | | **Trading** | None — mutating tools are not present at all | Full trading, with **no per-action confirmation** | | **OAuth scope** | `mcp:read` | `mcp:trade` | | **Consent screen** | No extra consent | Explicit trade-scope consent (see [Full-access safety](full-access-safety)) | | **Marketplace-listed** | Yes | No — connect by URL | The **read-only** surface is the one listed in AI marketplaces (for example the Claude and ChatGPT connector directories). It is safe to connect broadly: the trading tools are **structurally absent** — the agent cannot see or call them. The **full-access** surface is connected by pasting its URL directly. It grants your agent the ability to trade with no confirmation gate. Read [Full-access safety](full-access-safety) before you connect it. ## Tool categories [#tool-categories] Both surfaces expose the same read tools; the full-access surface adds the mutating ones. | Category | Read-only | Full access | | ------------------------------------------------------------------------------ | --------- | ----------- | | Market data — B2Trader platform prices (tickers, order book, market summaries) | Yes | Yes | | Portfolio & account (balances, margin, open positions) | Yes | Yes | | Order & position history | Yes | Yes | | Analytics & reference data | Yes | Yes | | Place / cancel / close orders (single) | No | Yes | | Bulk order / position actions | No | Yes | | Set & edit price triggers, other account mutations | No | Yes | | **Total tools** | **23** | **39** | The 16 tools that the full-access surface adds are the mutating actions: single trading actions, bulk trading actions, and non-trading account mutations. ## Which surface to choose [#which-surface-to-choose] * **Choose read-only** if you want an agent to analyze markets, summarize your portfolio, or answer questions about your trading history. This is the recommended default and the safest option. * **Choose full access** only if you deliberately want your agent to trade for you without confirming each action, and you understand the risks in [Full-access safety](full-access-safety). ## Prerequisites [#prerequisites] Before connecting any agent you need: * A **B2Trader account** on a platform that offers the MCP surfaces. They are available by default; a broker can restrict or disable them. * Your account must be **active** (`bbp.spot.status = Active`) — the same status required to trade in the terminal. A non-active account can sign in, but its tool calls are rejected by the platform. * An AI application that supports MCP with OAuth — for example [Claude](connect-claude), [ChatGPT](connect-chatgpt), or a [custom agent](connect-custom-agent). ## How connecting works [#how-connecting-works] You never paste an API key or password into your agent. Connection uses **OAuth 2.1 with PKCE**: 1. You add the B2Trader MCP URL to your agent. 2. The agent discovers B2Trader's authorization server automatically — it reads the endpoint's protected-resource metadata at `/.well-known/oauth-protected-resource/mcp-read-only` or `/.well-known/oauth-protected-resource/mcp-full-access`, depending on the surface. 3. Your browser opens the sign-in page for your platform, where you sign in with the credentials you normally use. 4. For the full-access surface, you approve an explicit consent screen describing what the agent may do. 5. The agent receives a short-lived access token and is connected. No long-lived secret is stored in the agent. The sign-in page you see depends on how your broker set up your platform: either the B2Trader sign-in form, or the sign-in page of the portal you normally use to access your account, which opens automatically. If you are already signed in there in the same browser, no sign-in prompt appears. The per-client steps are covered in the connection guides: * [Connect Claude](connect-claude) * [Connect ChatGPT](connect-chatgpt) * [Connect a custom agent](connect-custom-agent) * [Full-access safety](full-access-safety) ## Global interface controls [#global-interface-controls] ### Account selection [#account-selection] The **Account select** is located in the topbar and enables you to switch between your trading accounts. Each account shows its type: `H` (Hedging) or `N` (Netting). Once you switch the account, all the widgets automatically adjust to show relevant information for the selected account. Account select #### Account status [#account-status] An account can have a status that limits what you can do with it. When a status applies, a status indicator is shown on the account, and a banner explains the restriction. Account status is managed by your administrator. The following statuses are visible to you: * **Halted**: A banner reads *Account is locked for trading. Contact your administrator.* The trading controls are disabled, but you can still deposit and withdraw funds, and your balances, positions, and history stay visible. * **Frozen**: A banner reads *Account is frozen. Contact your administrator.* The account is view-only. All controls are disabled, while your balances, positions, and history stay visible. To restore trading on an account that is Halted or Frozen, contact your administrator. Archived accounts don't appear in the account list. ### Instrument selection [#instrument-selection] The **Instrument select** is located in the topbar and enables you to switch between various markets and trading pairs. Once you change the market, all the widgets automatically adjust to show relevant information for the selected instrument. Instrument select #### Favorite markets [#favorite-markets] Mark instruments as favorites for quick access. To add or remove a market from favorites, click the **star icon** next to the market name in the instrument selection list. Favorite markets can be accessed in two ways: * **Favorites tab** in the instrument selection panel — filters the list to show only your favorite markets. * **Favorites dropdown** in the topbar — provides quick access to favorite markets from anywhere in the terminal. ### Settings [#settings] Use this control to access interface and system settings. Refer to [Settings](settings) for details. Settings ### Other controls [#other-controls] * **Introduction tour**: Access the interactive platform walkthrough. Introduction tour * **Alerts**: View new system notifications. Unread alerts * **Analytics**: Open the **Account Analytics** view with the **Equity Curve** chart — your account balance and equity dynamics over time (Margin Balance, Equity, Total Equity, Unrealized PnL, Deposits / Withdrawals) for a selected period and granularity. The data updates hourly. Click **Back to Trading** to return to the terminal. Analytics * **Log out**: Log out of the system to securely terminate the session. After that you’re navigated to the Login page. Log out ## Working with widgets [#working-with-widgets] > For more information about available widgets, refer to the **Widgets** section of this guide. ### Add widgets to your workspace [#add-widgets-to-your-workspace] **To add a new widget**: 1. Click the **Add Widget** button. 2. Browse the available widgets. 3. Click any widget to add it to your workspace. Add Widget **To add widgets to existing panels**: 1. Look for the **+** button next to the tabs in a panel's header. 2. Click it to open the widget catalog. 3. Select a widget to add it as a new tab to that panel. Add widget tabs ### Move and position widgets [#move-and-position-widgets] **To move a widget**: 1. Click and hold the **move handle** in the top-right corner of the panel header. 2. Drag it to desired location on the page. 3. Drop it. Move widgets **To rearrange widget tabs within a panel**: 1. Click and hold any widget tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ### Resize widgets [#resize-widgets] **To resize a widget panel**: * **Single edge**: Hover over any edge until you see the resize cursor, then drag. * **Corner resize**: Drag a corner to adjust both width and height simultaneously. * **Precision**: Use edge dragging for fine-tuned sizing. Resize widgets ### Remove widgets and tabs [#remove-widgets-and-tabs] **To remove a tab**: 1. Click the **×** button in the top-right corner of the widget tab. 2. The tab will be removed immediately. 3. When you remove the last tab from a panel, the entire panel disappears. Remove tabs and widget panels ### Link panels to a group [#link-panels-to-a-group] Each panel header has a **Link to group** button — the circle icon **next to the move handle** in the top-right corner. Linking panels to the same colored group keeps them in sync: when you select an instrument in one linked panel, the other panels in the same group switch to it automatically. **To link a panel to a group**: 1. Click the **Link to group** button (next to the move handle) in the panel's top-right corner. 2. Select one of the color groups (Group 1–5). 3. Repeat for other panels, choosing the same group to keep them synchronized. Link to group ### Customize widget content [#customize-widget-content] Certain widgets let you customize which columns to display and their order: Look for the **column settings** button in the widget header. **To customize columns**: 1. Click the **column settings** button. 2. **Show/hide columns**: Check or uncheck boxes (grayed-out columns are required). 3. **Reorder columns**: Drag and drop items in the list. 4. **Reset**: Click *Reset to default* to restore original settings. Configure columns ## Managing workspaces [#managing-workspaces] ### Create new workspaces [#create-new-workspaces] **To create a workspace**: 1. Click the **+** tab next to your existing workspaces. 2. Choose a template: * **Pre-built templates**: Start with common widget combinations. * **Empty**: Build completely from scratch. 3. Enter a name for your workspace. 4. Start customizing. Add a new workspace ### Workspace management [#workspace-management] **To rename or delete a workspace**: 1. Click the menu icon on the workspace tab. 2. Select **Rename** or **Remove**. Workspace menu **To reorder workspaces**: 1. Click and hold any workspace tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ## Market info panel [#market-info-panel] Click the **info icon** next to a market symbol in widgets to view: * Detailed market information. * Trading session schedules. * Leverage details (for CFD and PF markets). * Fee details. * Funding details (for PF markets). Market info ## Pro tips [#pro-tips] ### Efficient layout building [#efficient-layout-building] * Start with a template that is close to your needs, then customize. * Group related widgets in tabs to save screen space. * Use larger panels for charts, smaller ones for order books. ### Layout best practices [#layout-best-practices] * **Save multiple workspaces** for different trading strategies. * **Test your layout** during low-activity periods. * **Keep essential widgets visible** (account info, positions, alerts). Access settings by clicking the **gear icon** in the topbar of the Trading terminal. Settings Settings are organized into tabs: * [Interface](#interface): Configure language, time display, and visual theme. * [Widgets](#widgets): Customize widget display options. * [Action Confirmation](#action-confirmation): Choose which actions require additional confirmation. * [Account margin](#account-margin): Manage collateral assets for margin trading. * [Trading report](#trading-report): Generate comprehensive trading and account reports. * [API token management](#api-token-management): Generate and manage tokens for accessing the Trading API. * [TradingView Webhooks](#tradingview-webhooks): Configure TradingView webhook alerts for automated order execution. ## Interface [#interface] Configure global interface preferences: **Language** Select the interface language from the dropdown menu. **24 hour mode** * Enable: Display time in 24-hour format. * Disable: Display time in 12-hour format with AM/PM. **Dark theme** * Enable: Apply dark color scheme. * Disable: Apply light color scheme. ## Widgets [#widgets] Configure display options for the following widgets. ### Price chart [#price-chart] **Display positions** When enabled, open positions are shown on the chart along with: * Position size and current PnL. * Quick access to edit price triggers and close positions. * Color coding: Long positions (green), Short positions (red). **Display orders and triggers** When enabled, the following orders and triggers are displayed on the chart: * Active Limit and Stop orders with order type, price, and amount. * Stop loss, Take profit, and Trailing stop triggers. * Quick access to edit triggers and cancel orders. * Color coding: Buy orders (green), Sell orders (red). **Display executed orders** When enabled, executed orders are shown on the chart with order type indicators: * Green `B` tag for Buy orders. * Red `S` tag for Sell orders. Clicking `B` or `S` will open details of one or more orders that were executed during the candle interval. **Market quick trade panel** When enabled, a panel is displayed on the chart for placing Market orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. **Limit quick trade panel** When enabled, a panel is displayed on the chart for placing Limit orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. ## Action Confirmation [#action-confirmation] Choose which trading actions require an additional confirmation dialog before execution. **Cancel orders** * Enable: A confirmation dialog is displayed before canceling orders. * Disable: Orders are canceled immediately without confirmation. This setting applies to single and bulk order cancellations from the **Open Orders** widget and the **Price chart**. The confirmation dialog includes a **"Don't ask again"** checkbox. To skip the confirmation for future order cancellations, check this box. **Full Close Positions** * Enable: A confirmation dialog is displayed before closing positions. * Disable: Positions are closed immediately without confirmation. This setting applies to single and bulk position closures from the **Open Positions** widget. **Limit order cross-TOB warning** * Enable: A confirmation dialog is displayed before a Limit order is submitted if its price crosses the current top-of-book — that is, when a Buy price is at or above the best ask, or a Sell price is at or below the best bid. The dialog shows the entered price and the current best bid/ask, and includes a **Do not show this warning again** checkbox. * Disable: Crossing Limit orders are submitted immediately without the warning. The warning is enabled by default. The dialog checkbox and this toggle share the same global setting and stay in sync. The warning is informational only — it does not block the order. If you confirm, the order is submitted with the original price. The warning applies only to standard Limit orders; Stop-limit, Take-profit-limit, IOC, FOK, and other order types are not affected. If best bid or best ask data is unavailable (empty book or disconnected feed), the order is submitted without the warning. ## Account margin [#account-margin] Control which assets can be used as collateral for margin trading. ### Asset list [#asset-list] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance available for trading, calculated as *Total – Halted*, where *Halted* represents funds locked for pending Limit orders. *** **Total** The complete asset balance including locked funds. *** **Margin ratio** The percentage of asset value that can be used as collateral for margin trading. *** **Use as margin** Enable this toggle to use the asset as collateral for margin trading. Configure which assets can be used as collateral for margin trading by toggling the **Use as margin** setting for each asset. Only assets with **Margin ratio** greater than 0 (zero) can be enabled. The platform root asset is enabled by default and can't be disabled. ### Filtering options [#filtering-options] Click the **funnel icon** to configure the asset list display: * **Show/Hide zero balances**: Control visibility of assets with zero balance. By default, hidden. * **Show/Hide assets unused as margin**: Control visibility of assets with disabled margin usage. * **Show/Hide assets with zero margin ratio**: Control visibility of assets that can't be used as collateral. By default, hidden. ## Trading report [#trading-report] Generate comprehensive reports containing: * **Trade history** * Closed positions * Executed orders * Individual trades * **Transfers history** * All account transfers * **Account statistics** * Total balance * Realized PnL * Position swaps * Position funding * Commissions To generate a report: 1. Select a custom period of time (UTC time), or generate a report for your entire account history using the **All data** range. The following timeframe presets have been implemented for your convenience: * **Today** * **Current**: week, month, quarter * **Previous**: week, month, quarter * **All data**. 2. Click **Download**. Once generated, the report will be automatically downloaded to your computer as a zipped CSV file. ## API token management [#api-token-management] Generate tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/): * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time To generate a token: 1. Click **+ Create new**. 2. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 3. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ## TradingView Webhooks [#tradingview-webhooks] Use TradingView Webhooks to automatically execute orders on your trading account based on alerts from TradingView. When a TradingView alert triggers, it sends a webhook request to B2TRADER, which places an order according to the parameters specified in the alert message. This feature supports all market types: Spot, CFD, and Perpetual Futures. ### Set up the webhook [#set-up-the-webhook] #### Step 1: Create a webhook API key [#step-1-create-a-webhook-api-key] To create a webhook API key in the Trading terminal: 1. Click the **gear icon** in the topbar to open Settings. 2. Navigate to the **TradingView Webhooks** tab. 3. Click **+ Create new**. 4. In the popup, fill in a **Name** for the key. 5. Click **Create**. The popup displays the generated API key and the webhook URL. Copy both values and store them securely. The API key is shown only once at creation. It can't be retrieved after closing the popup. The following limits apply: * Maximum 10 active keys per user * Each key is valid for 1 year from creation * Keys can be revoked at any time #### Step 2: Configure the alert in TradingView [#step-2-configure-the-alert-in-tradingview] 1. In TradingView, create a new alert or edit an existing one. 2. In the **Notifications** section, enable **Webhook URL**. 3. Paste the webhook URL copied from the terminal. 4. In the **Message** field, enter the alert body in JSON format (see [Alert message format](#alert-message-format)). 5. Save the alert. When the alert triggers, TradingView sends the message to B2TRADER, and the order is placed automatically. ### Alert message format [#alert-message-format] The alert message is a JSON object with the following fields: | Field | Required | Description | | ----------------- | ----------- | -------------------------------------------------------------------------- | | `apiKey` | Yes | Webhook API key generated in the terminal | | `accountId` | Yes | Trading account ID | | `symbol` | Yes | Market symbol with type prefix (see [Symbol format](#symbol-format)) | | `side` | Yes | Order side: `buy` or `sell` | | `quantity` | Yes | Order quantity in base asset | | `orderType` | No | `market` (default), `limit`, `stop`, or `stop_limit` | | `price` | Conditional | Limit price. Required for `limit` and `stop_limit` orders | | `stopPrice` | Conditional | Stop price. Required for `stop` and `stop_limit` orders | | `leverage` | No | Leverage ratio. Applicable to CFD and Perpetual Futures markets only | | `takeProfit` | No | Take profit trigger price | | `stopLoss` | No | Stop loss trigger price | | `timeInForce` | No | `gtc` (default), `ioc`, `fok`, or `day` | | `comment` | No | Custom comment, up to 256 characters | | `deduplicationId` | No | UUID for idempotency. Duplicates within 5 minutes return a cached response | #### Symbol format [#symbol-format] The symbol must include a market type prefix: | Market type | Prefix | Example | | ----------------- | ------- | --------------- | | Spot | `spot.` | `spot.btc_usdt` | | CFD | `cfd.` | `cfd.eur_usd` | | Perpetual Futures | `perp.` | `perp.btc_usdt` | #### Examples [#examples] **Market buy order (Spot):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01" } ``` **Limit sell order with TP/SL (CFD):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "cfd.eur_usd", "side": "sell", "orderType": "limit", "price": "1.0900", "quantity": "1000", "leverage": "10", "takeProfit": "1.0800", "stopLoss": "1.0950", "timeInForce": "gtc" } ``` ### Manage webhook API keys [#manage-webhook-api-keys] To view or manage your webhook API keys, navigate to **Settings** > **TradingView Webhooks**. The following information is provided about each key: | Column | Description | | ----------- | ----------------------------------------------- | | **Name** | The name assigned to the key at creation | | **Status** | Current key status: Active, Revoked, or Expired | | **Created** | The date and time the key was generated | | **Expires** | The date and time the key expires | To revoke a key, click the **Revoke** button next to the key entry. ### Rate limits [#rate-limits] Webhook requests are limited to 5 requests per second per user. If this limit is exceeded, the request returns a `429` error code and the order isn't placed. ### Troubleshooting [#troubleshooting] The following table describes common error scenarios and their solutions: | Issue | Cause | Solution | | -------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | | `Invalid API key` | The API key is incorrect or wasn't copied in full | Generate a new key and update the TradingView alert | | `API key expired` | The key has passed its 1-year validity period | Generate a new key | | `API key revoked` | The key was manually revoked | Generate a new key | | `Invalid symbol format` | The symbol is missing a market type prefix | Add the prefix: `spot.`, `cfd.`, or `perp.` | | `Price required for limit order` | A `limit` or `stop_limit` order is missing the `price` field | Add the `price` field to the alert message | | `Rate limit exceeded` | More than 5 requests were sent within 1 second | Reduce the alert frequency in TradingView | | `Account not found` | The `accountId` doesn't exist or isn't accessible | Verify the account ID in the terminal | A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to limit and stop limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to limit and stop limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the BP, without taking into account the time settings of the devices from which the BP is accessed. ## iOS v1.35 [#ios-v135] This version includes: * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. Select a time period and granularity level to filter performance data, and switch between accounts using the built-in account selector. * **AI Assistant** A new **AI Assistant** widget provides AI-powered market analysis for each instrument, including trade recommendations, market sentiment, signal drivers, suggested actions, and key metrics. * **Quick order from the chart** You can now place orders directly from the **Price chart** by tapping a price pin. The **Quick Order** panel opens pre-filled at the selected price level for faster order placement. * **Customizable workspace** You can now reorder and show or hide bottom tabs in **Settings**, allowing you to tailor the terminal layout to your trading preferences. * **Adaptive interface by market type** Tabs, **Margin Level**, and perpetual funding indicators are now automatically hidden for accounts that do not have access to the corresponding market types, providing a cleaner and more focused interface. * **Landscape mode for the chart** Tapping the **Expand** button on the **Price chart** now automatically rotates the chart to landscape mode for a wider view. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.34 [#ios-v134] This version includes: * **Drag Take Profit and Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be adjusted by dragging their lines directly on the **Price chart**. Changes are applied to the order immediately, with automatic rollback if an error occurs. * **Demo accounts** Demo trading accounts are now supported, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets appear as chips in the market list and are indicated with an icon in the terminal. * **Credit in margin details** A dedicated **Credit** row has been added to the margin details section, providing visibility into credit amounts allocated to your trading account. * **Comments for orders, positions, and trades** You can now add a comment when placing an order or managing a position. The comment is visible throughout the trading lifecycle — on open orders, open positions, and in trade history. * **Margin Level display** When **Margin Level** data is unavailable, the field now displays "–" instead of 0% for clearer data visibility. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.33 [#ios-v133] This version includes: * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Hide zero balances settings relocated** The **Hide zero balances** toggle has been moved to the **Assets** tab for more intuitive access. * **Improved backend error messages** Backend error messages are now mapped to user-friendly descriptions, providing clearer feedback when issues occur. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.32 [#ios-v132] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Quick cancel button for open orders** The **Open orders** widget now features a quick **Cancel** button on each order card, enabling faster order cancellation directly from the list view. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Redesigned account selection header** The account selection section in the terminal header has been redesigned for improved navigation and a cleaner appearance. * **Updated closed positions design** The **Closed positions** widget has been updated with a refreshed layout for better readability and consistency with other trading widgets. * **Confirmation bottom sheet** Order and position actions now display a confirmation bottom sheet, helping to prevent accidental trades and providing a clearer review step before execution. * **Settings button relocated** The **Settings** button has been moved from the **Price chart** widget to the terminal header for easier access across all views. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.31 [#ios-v131] This version includes: Experience an advanced trading workflow with the introduction of our new **tiered leverage system**, offering dynamic leverage based on position size and enhanced margin visibility. This update also brings improved commission transparency with a dedicated Fees tab, enhanced market info, a new deposit shortcut, and updated screens for tiered commissions. We've also refined formatters to respect your selected app language for a more consistent experience. *** ## iOS v1.30 [#ios-v130] This version includes: * **Notifications widget** A new **Notifications** widget has been implemented providing quick access to system notifications related to price changes, Margin calls, Stop outs, Take profit and Stop loss triggers. * **Closing open positions from the Price chart** Open positions can now be closed directly on the **Price chart** screen ensuring quick reaction to volatile market conditions and efficient trade management. This feature is available if the **Display positions** setting is activated for the Price chart. * **Closing all open positions** The **Open positions** tab now features the **Close all** button that liquidates all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Canceling all active orders** The **Open orders** tab now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * **Trading session status** The **Trading session status** in the **Position details** is now accompanied by an info icon and an explanatory tooltip. * **Automatic horizontal scrolling for tabs** The horizontal auto scroll has been added to tabs. Active tabs are now automatically centered for optimal visibility and better accessibility to all available tabs. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.29 [#ios-v129] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding**/**Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Updated account creation process** When creating a trading account in the app, the **account type** can now be selected: **Hedging** or **Netting**, enabling traders to plan and adjust their trading strategies to maximize profit or reduce risk. Depending on the platform settings, the option may be prefilled or require manual selection. The account type can’t be changed after the account is created. * **Support for Take Profit, Stop Loss, and Trailing Stop** The **Take Profit**, **Stop Loss**, and **Trailing Stop** triggers are now supported in the app for CFD and PF trading. They can be applied to Market, Limit, and Stop orders, as well as to currently open positions. * **Support for price alerts** Price alerts are now fully supported in the app: * Multiple alerts can be added to monitor different price levels for any instrument. * Configure alerts based on a fixed price or a percentage change. * View a list of all configured alerts for each instrument. * Adjust or delete existing alerts as needed. * Triggered alerts are automatically removed to keep the list up to date. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order history widget. * **Admin-managed orders and positions** On the **Open positions**, **Closed positions**, and **Order history** widgets, if BP Admins have managed positions or orders, this is now indicated in the **Reason** field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, mitigate risks, or resolve outstanding positions before account termination. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.28 [#ios-v128] This version includes: * **Performance upgrade** Streamlined top-of-the-book ask and bid prices in the Place Order widget are now received through a dedicated socket for faster obtaining and display. * **Mobile and Web Consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** Placeholders are now displayed for empty fields and widgets for improved UX clarity. * **Internal improvements** Enhanced system logs for better diagnostics. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## Android v2.12.0 [#android-v2120] This version includes: * **AI Assistant** A new **AI Assistant** provides AI-powered market analysis for each market, including trade recommendations, a 12-month price forecast, market sentiment, signal drivers, suggested actions, and key metrics. * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. * **Account status indicators** Account statuses such as **Halted** and **Frozen** are now shown with badges and a warning banner, and the related trading actions are restricted accordingly. * **Quick order from the chart** You can now place orders directly from the **Price chart**, enabling faster reaction to market movements. * **Take Profit / Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be set by dragging their lines directly on the **Price chart**, with support for trailing Stop Loss. * **Cross-price limit order warning** A warning is now displayed before you place a **Limit** order whose price crosses the top of the **Order book**. This warning can be enabled or disabled in **Settings**. * **Customizable trading terminal** You can now customize the trading terminal layout and tab order from the new **Workspace** settings. * **Adaptive interface by market type** Margin- and perpetual-related tabs and indicators are now hidden for accounts with access to **Spot** markets only, providing a cleaner interface tailored to the account type. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.11.0 [#android-v2110] This version includes: * **Comment field in Place Order** An optional **Comment** field has been added to the **Place order** form in **Advanced Mode**. The field supports up to 100 characters and is available for all order types across Spot, CFD, and Perpetual markets. * **Full-screen chart mode** The **Price chart** widget now supports full-screen mode. Tap the **Expand** button to switch to a landscape view for a more detailed chart analysis. * **Credit information in margin details** A **Credit** row has been added to the margin section, providing visibility into credit amounts allocated to trading accounts. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.10.0 [#android-v2100] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Demo accounts** Demo trading accounts are now supported in the app, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets are synchronized between the web and mobile terminals. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Improved market status display** The **Market Closed** label is now automatically removed once live data starts updating, providing a more accurate representation of market availability. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.9.0 [#android-v290] This version includes: This update introduces the new **tiered leverage system**, enhanced fee transparency and fully redesigned Fees tab, quick Deposit/Trade shortcuts on account cards for faster navigation and various UI improvements across the app. *** ## Android v2.8.0 [#android-v280] This version includes: * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.7.0 [#android-v270] This version includes: * **Key position parameters on the TP/SL editing** Key position parameters, such as **Name**, **Side**, **Amount**, **Open price**, **Current price**, and **Leverage** are displayed at the top of the Take Profit/Stop Loss configuration screen to give you immediate, accurate context and reduce input errors. Values are updated in real time. * **Closing positions on the Price chart** You can now close positions directly on the **Price chart** widget, by tapping a position indicator. * **Canceling all active orders** The **Open orders** widget now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Closing all open positions** The **Open positions** widget now features the **Close all** button allowing to liquidate all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Closed position details** The **Order type** and **Time in force** values are now displayed for every closed position to improve trade execution transparency. * **Price chart settings saved** The **Price chart** widget now remembers your preferred timeframe and chart type settings. Each time you open the terminal, it displays the chart with your last selected settings. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.6.0 [#android-v260] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding/Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order History widget. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * Expanded capabilities for account administration and risk management for Brokers have been added. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.5.0 [#android-v250] This version includes: * **Stop Loss and Take Profit on the Price chart widget** * Introduction of Stop-Loss (SL) and Take-Profit (TP) lines on the Price chart for enhanced trading insights. * TP and SL are displayed as color-coded lines with only abbreviations visible. * Tap to view prices on the Y-axis and access deletion options. * **Full support for price alerts in the app** * Alerts can be set for specific price levels. * Alerts can be configured based on either a set price or a percentage change. * A list of configured alerts is available for each instrument. * Options to delete or adjust alerts are provided. * Triggered alerts are automatically removed from the list. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.4.0 [#android-v240] This version includes: * **New mobile features** * Introduction of Take Profit, Stop Loss, and Trailing Stop functionalities in the Mobile app. * Support for Netting accounts in the Mobile app. * **Mobile and Web consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** For order lists, the All/Spot/CFD filter is only displayed when there are both Spot and CFD orders, for improved UX clarity. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## June 10, 2026 [#june-10-2026] ### New features [#new-features] #### Guest mode [#guest-mode] A new **Guest mode** lets you explore the Trading terminal without signing in. As a guest you can browse markets and market categories, follow live price streams and interactive charts, and open the **AI Assistant** widget for market analysis. A dedicated guest workspace is provided, and the [Place order](../widgets/place-order) panel opens in the advanced view by default. A **Sign in** action is always available so you can switch to a full trading session at any time. ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Full account history in Trading reports [#full-account-history-in-trading-reports] You can now generate [Trading reports](../get-started/settings) for your entire account history. The previous **92-day** limit has been removed, and a new **All data** range has been added to the report period selector alongside the existing presets. #### Stop orders during closed market sessions [#stop-orders-during-closed-market-sessions] You can now place **Stop** orders while a market is closed according to its trading schedule. The order is accepted and activates automatically once the market reopens, instead of being rejected at placement. #### More accurate unrealized PnL [#more-accurate-unrealized-pnl] Unrealized PnL is now calculated using the correct order book side for each position direction, improving the accuracy of the PnL shown across your widgets. #### Limit price crossing warning [#limit-price-crossing-warning] When you place a limit order at a price that crosses the current top of book, the terminal now shows a warning, helping you avoid an unintended immediate execution. ## April 9, 2026 [#april-9-2026] ### New features [#new-features-1] #### Trading credit [#trading-credit] Your broker can now grant you **trading credit** — a promotional bonus balance you can use for trading. Credit appears as a separate **Credit Balance** alongside your own funds and becomes available for placing trades immediately upon issuance. You are notified when credit is granted or revoked. Trading credit is a trading-only bonus and cannot be withdrawn as cash, so it is excluded from your withdrawable balance. *** ### Improvements [#improvements-1] #### Fee-aware 100% allocation [#fee-aware-100-allocation] The **100%** button in the [Place order](../widgets/place-order) widget now accounts for commissions and margin requirements when allocating funds, so the calculated amount reflects what is actually available for the trade. #### Faster price updates [#faster-price-updates] The price update frequency in terminal widgets has been increased, providing more responsive market data across your workspace. ## March 18, 2026 [#march-18-2026] ### New features [#new-features-2] #### Webhook API for TradingView alerts [#webhook-api-for-tradingview-alerts] A new **Webhook API** has been added, enabling you to connect **TradingView** alerts to your trading workflow. You can generate and copy authentication tokens directly from the Trading terminal to configure webhook-based alerts in **TradingView**. *** ### Resolved issues [#resolved-issues] There have been no customer-facing issues reported in this release. ## March 3, 2026 [#march-3-2026] ### New features [#new-features-3] #### Long-term trading data history [#long-term-trading-data-history] The three-month limit on trading data history has been removed. You can now access the full history of your orders, positions, and trades without time restrictions, enabling deeper analysis of past trading activity. #### AI Assistant widget [#ai-assistant-widget] A new **AI Assistant** widget is now available in the Trading terminal. The widget provides AI-powered market analysis for the selected instrument, including: * A recommendation gauge displaying a score from **Strong Sell** to **Strong Buy** * A 12-month price forecast with target price and percentage change * A market sentiment bar showing the bullish/bearish ratio * Signal drivers section with technical, on-chain, and sentiment factors * Suggested trading actions and key market metrics The widget can be added to any workspace like other terminal widgets. *** ### Improvements [#improvements-2] #### Updated order cancellation confirmation [#updated-order-cancellation-confirmation] The order cancellation confirmation dialog now includes a **Don't ask again** checkbox when canceling triggers from the **TradingView** chart. This allows you to skip the confirmation step for future trigger cancellations, streamlining the trading workflow. *** ### Resolved issues [#resolved-issues-1] There have been no customer-facing issues reported in this release. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-4] #### Redesigned Market Depth widget [#redesigned-market-depth-widget] The [Market Depth](../widgets/market-depth) widget has been completely redesigned with an updated visual layout. Bid and ask labels are now displayed when hovering over a price level, providing better visibility into the order book at a glance. #### Redesigned widget adding experience [#redesigned-widget-adding-experience] The process of adding widgets to workspaces has been redesigned with a more intuitive and streamlined flow. The new interface makes it easier to customize your trading workspace layout by providing a clearer visual selection of available widgets. #### Order and position comments [#order-and-position-comments] A new **Comment** field has been added to orders, positions, and trades throughout the Trading terminal. You can now attach notes directly to your trading activities, making it easier to annotate trading decisions and keep records of your reasoning. #### Favorites [#favorites] You can now mark instruments as favorites for quick access across the Trading terminal. The [Favorite markets](../get-started/customizing-your-terminal#favorite-markets) feature integrates with the instrument selection panel, making it faster to locate and trade your preferred instruments. #### Multi-language support [#multi-language-support] The Trading terminal now supports additional languages: **Chinese (Simplified)**, **Spanish**, **Portuguese**, **French**, **Turkish**, and **Farsi**. Existing translations have also been updated to reflect the latest interface changes. *** ### Improvements [#improvements-3] #### Updated order calculations [#updated-order-calculations] The **Value** and **Amount** calculation logic has been improved for more accurate order handling: * For **Stop Market** orders, the estimated values are now calculated using updated formulas that align with the actual execution logic. * For **Spot** market orders, the **Slippage Rate** is now correctly applied only to buy orders and has been removed from sell order calculations. * The **Slippage Rate** attribute has been removed from **CFD** and **PF** market forms and information displays, as it is not applicable to these market types. #### Improved TP/SL trigger management [#improved-tpsl-trigger-management] Removing Take Profit and Stop Loss triggers is now easier in the TradingView charting widget. Instead of opening a dialog and unchecking the trigger, you can now click the close button directly on the trigger to remove it immediately. #### Updated default columns [#updated-default-columns] The default columns displayed in the [Open positions](../widgets/open-positions) and [Open orders](../widgets/open-orders) widgets have been updated to show the most relevant information by default, reducing the need for manual customization. #### Account margin value formatting [#account-margin-value-formatting] Account margin values such as **Balance**, **Equity**, **Margin**, and **Free margin** in the [Margin](../widgets/margin) widget are now formatted according to the **Root Asset Scale**. This ensures that numerical precision matches the asset's defined scale, eliminating misleading decimal places. #### Updated Settings experience [#updated-settings-experience] The [Settings](../get-started/settings) experience has been improved: * The **Action Confirmation** section text has been rewritten for clarity. The description now reads: "Choose which actions will require additional confirmation," making the toggle behavior immediately clear. * The **One-click trading** configuration has been updated with improved toggle controls and clearer options for enabling or disabling confirmation dialogs on trading actions. #### Improved order validation [#improved-order-validation] Order validation logic has been updated across the Trading terminal, providing clearer feedback on invalid inputs and reducing errors during order placement and management. #### Workspace tab styling [#workspace-tab-styling] Visual improvements have been applied to workspace tabs: gaps have been added between tabs for better visual separation, tab padding has been corrected, and hovered tabs now display a proper card-style fill matching the updated design system. ## December 19, 2025 [#december-19-2025] ### New features [#new-features-5] #### Volume-based tiered commissions [#volume-based-tiered-commissions] You can now benefit from **volume-based commission tiers** that automatically reduce your trading fees as your monthly volume grows. **Key points**: * **Trade more, pay less**: For markets with tiered fees, your 30‑day trading volume (in the root asset, for example USD) is tracked across all markets included in the same group. As you move into higher tiers, your commission percentage decreases. * **Clear fee overview**: Open [Market info](../get-started/customizing-your-terminal#market-info-panel) and switch to the **Fees** tab to see your **Current volume** for the month, the configured **Min. fee**, and the full **Commission tiers** table with volume ranges and fee %. A check mark highlights the tier you are currently in. * **Grouped volume**: Your traded volume is aggregated across markets to which the dynamic commission is applied. * **No surprises**: Orders on markets without tiered fees continue to use the existing flat commission model. Tiered markets simply adjust your fee according to the tier that matches your current trading volume. #### New settings [#new-settings] The [Settings](../get-started/settings) menu has been enriched with the following configuration options: * **Widgets**: This updated section now provides access to multiple widgets’ display settings. Along with existing [Price chart](../widgets/price-chart), you can now configure: * One-click trading for [Open positions](../widgets/open-positions): When enabled, single and bulk position closing are executed immediately, without going through additional confirmation dialogs. * One-click trading for [Open orders](../widgets/open-orders): When enabled, single and bulk order cancellations are executed immediately, without going through additional confirmation dialogs. * **API token management**: This new section allows you to generate and manage tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/). Up to 10 tokens can be generated per account. The validity period for each token is one year. The tokens can be revoked or deleted anytime. *** ### Improvements [#improvements-4] #### Responsive widget layout [#responsive-widget-layout] Widget content now adapts dynamically to the available space, ensuring that key information such as primary values, titles, and critical actions remains visible even when widgets are resized or minimized. Layouts have been refined to avoid unnecessary empty areas while preventing clipping of important elements, delivering a more readable and informative experience across all widget sizes. #### Clearer margin level display [#clearer-margin-level-display] The [Margin](../widgets/margin) widget has been updated to provide a clearer signal. Now, whenever no margin is used (for example, when you have no open positions), the **used margin** value displays **–** instead of 0%. This aligns with common brokerage practices and helps you better understand the current risk state at a glance. #### Smarter default filters for Assets and Account margin [#smarter-default-filters-for-assets-and-account-margin] Certain default filters are now applied automatically when the Trading terminal is opened for the first time. In the [Assets](../widgets/assets) widget, **Hide zero balances** is enabled by default, so assets with zero balance are not shown. In the [Account margin](../get-started/settings#account-margin) settings, **Hide zero balances** and **Hide assets with zero margin ratio** are enabled by default, hiding assets that carry no margin or balance. If you change any of these filters, the platform remembers their states. #### Improved quick trade panels [#improved-quick-trade-panels] The **Market quick trade panel** has been moved not to cover the important controls of the [Price chart](../widgets/price-chart). Additionally, it now displays the **cross icon** to quickly close the panel if needed. *** ### Resolved issues [#resolved-issues-2] There have been no customer-facing issues reported in this release. ## November 7, 2025 [#november-7-2025] ### New features [#new-features-6] #### Tiered leverage system [#tiered-leverage-system] With this release, we're excited to introduce the **tiered leverage system** that provides more sophisticated leverage options based on your position sizes, offering better risk management. **Key points:** * **Dynamic leverage tiers**: Markets can now offer tiered leverage where your maximum available leverage decreases as your position size increases. This allows you to access higher leverage on smaller positions while maintaining appropriate risk controls on larger trades. * **Enhanced market information**: Markets with tiered leverage now display comprehensive leverage information in the **Market info** panel. A new **Leverage** tab shows all available tiers, including the notional value ranges and maximum leverage for each tier. * **Improved position tracking**: Your open positions now display both the leverage you selected when opening the position (**Requested leverage**) and the actual leverage being applied (**Leverage**). Detailed tooltips explain how these values are calculated, giving you better visibility into your margin usage. * **Smart leverage selection**: When placing orders on markets with tiered leverage, the system automatically calculates your margin requirements across all applicable tiers. You can see the exact margin required before placing your order. **How it works** For markets with dynamic leverage, your position is allocated across different tiers based on its notional value. Each tier has its own maximum leverage limit, typically starting with higher leverage for smaller positions and decreasing as position size grows. This allows you to maintain appropriate risk management. **Order placement** When trading on tiered markets, you can still select your preferred leverage (up to the maximum allowed for the first tier), and the system will automatically apply the appropriate leverage limits. The margin calculator shows you the exact requirements before you place your order. All existing positions continue to operate normally with no changes to your current trading experience. Markets without tiered leverage continue to work exactly as before. *** ### Improvements [#improvements-5] #### Improved documentation experience [#improved-documentation-experience] The documentation window is now fully resizable, allowing traders to adjust both vertical and horizontal dimensions independently. All screenshots can now be zoomed, making detailed interface elements clearly visible. #### Streamlined market selection [#streamlined-market-selection] The market selection control is now displayed as the **chevron icon** directly next to the market name in widgets. The magnifying glass icon has been removed. Both the market name and chevron are now clickable and open the market selector. #### Reorganized market information access [#reorganized-market-information-access] The market info popover has been relocated under the **info icon** in the widget header to maintain accessibility while keeping the market name area focused solely on selection functionality, creating a cleaner and more consistent user interface. #### Enhanced workspace tab design [#enhanced-workspace-tab-design] A clear distinction between active and inactive workspace tabs has been achieved due to intuitive styling. Workspace option buttons are now hidden by default to reduce visual clutter and only appear when tabs are active or being hovered over. This applies to both default and custom workspace tabs, creating a cleaner interface while maintaining full functionality when needed. *** ### Resolved issues [#resolved-issues-3] There have been no customer-facing issues reported in this release. ## October 9, 2025 [#october-9-2025] ### New features [#new-features-7] #### Placing orders from the Price chart [#placing-orders-from-the-price-chart] The [Price chart](../widgets/price-chart) widget now supports direct order placement with two new quick trading panels. The **Market quick trade panel** provides a persistent interface for instant buy/sell orders, while the **Limit quick trade panel** allows hover-based order placement at specific price levels. When enabled through **Price chart settings**, both panels offer configurable amount presets and leverage ratio selection for margin trading (when applicable), creating a seamless trading experience without leaving the chart view. #### Bulk order canceling [#bulk-order-canceling] The [Open orders](../widgets/open-orders) widget introduces a **Cancel all** button that closes all active orders simultaneously. This feature provides better risk management capabilities during volatile market conditions. #### In-platform documentation [#in-platform-documentation] User documentation is now integrated directly within the Trading terminal interface. This eliminates the need to switch between applications when accessing help materials or reference guides, keeping essential information readily available during trading sessions. #### New market subtype [#new-market-subtype] The new **Commodities** subtype has been added for CFD markets, enhancing the market categorization system. *** ### Improvements [#improvements-6] #### Enhanced position tracking [#enhanced-position-tracking] A new **Direction** column has been added to **Trades** info in the [Open positions](../widgets/open-positions) and [Closed positions](../widgets/closed-positions) widgets. It indicates whether a position size increased (In) or decreased (Out) as a result of each trade. This enhancement provides clearer visibility into position movement patterns. #### Cross rates calculation precision [#cross-rates-calculation-precision] Accuracy for cross-rate calculations has been improved by introducing a new cross-rate scale parameter. It has a default value of 8 and can be adjusted in configuration files. This addresses the previous limitation where cross rates were rounded to the root asset type scale (typically 2 decimal places), causing incorrect zero values in certain scenarios. The improvement ensures accurate cross-rate calculations across all currency and cryptocurrency pairs, regardless of their relative values. #### Redesigned Settings interface [#redesigned-settings-interface] The **Settings** menu has been restructured with a new tabbed popup interface. Related configuration options are now logically grouped, making settings easier to navigate and manage. #### Pre-filled Limit order price [#pre-filled-limit-order-price] Limit order placement now includes automatic price pre-population using the best bid or ask price from the order book. This static pre-fill reduces manual entry requirements and helps prevent pricing errors during order submission. #### Updated sorting of open positions [#updated-sorting-of-open-positions] [Open positions](../widgets/open-positions) are now sorted chronologically with the newest positions displayed at the top, improving visibility of recent trading activity. #### Improved messages [#improved-messages] User communications have been updated throughout the platform, including improved Introduction tour messaging for better onboarding and clearer system notifications. #### UI enhancements [#ui-enhancements] UI improvements for this release include: * **Support for dynamic resizing of the trading interface layout**: The trading interface now features a responsive layout system that dynamically adjusts to browser window resizing. Widgets automatically scale and reposition to maintain optimal viewing regardless of screen size changes. * **Loader**: [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now display loading indicators when fetching additional data. * **Improved PnL representation**: When displayed on charts, the PnL values are now accompanied by "+" or "–" signs for immediate profit/loss recognition. * **Improved scrollbars**: Scrollbar positioning has been refined to prevent overlay of table content, ensuring all data remains visible and accessible. *** ### Resolved issues [#resolved-issues-4] There have been no customer-facing issues reported in this release. ## July 2, 2025 [#july-2-2025] ### New features [#new-features-8] #### Trading reports [#trading-reports] We've implemented a new feature enabling you to generate trading reports for a specific period of time and download them as zipped CSV files to your computer. The report includes a detailed information on: * **Trade history** * Closed positions * Executed orders * Trades * **Transfers history** * **Account statistics** * Total balance * Realized PnL * Swaps * Funding * Commissions The data is available for any period within the last **92 days** (UTC time). The following timeframe presets have been implemented for your convenience: * Today * Current: week, month, quarter * Previous: week, month, quarter Access the new **Trading report** menu under the **Settings** icon on the topbar of the Trading terminal. *** ### Improvements [#improvements-7] #### Admin-managed orders and positions [#admin-managed-orders-and-positions] In the [Open positions](../widgets/open-positions), [Closed positions](../widgets/closed-positions), and [Order history](../widgets/order-history) widgets, if BP Admins have managed positions or orders, this is now indicated in the Reason field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, and mitigate risks. *** ### Resolved issues [#resolved-issues-5] There have been no customer-facing issues reported in this release. ## May 30, 2025 [#may-30-2025] ### New features [#new-features-9] #### PF trading [#pf-trading] We are excited to introduce **Perpetual Futures (PF) trading** on our platform. These contracts feature a funding fee mechanism based on the Mark price and Funding rate. A positive rate means Long positions pay Shorts, and a negative rate means the reverse. You can see the countdown to the next funding fee settlement in the [Market summary](../widgets/market-summary) widget. This update also includes a new market type — Perpetual — enhancing your trading opportunities. *** ### Improvements [#improvements-8] #### Price chart setting [#price-chart-setting] The [Price chart](../widgets/price-chart) widget now supports displaying of open positions, as well as open and executed orders. Click the **gear icon** in the topbar to access Price chart settings and enable desired options. #### Close all positions [#close-all-positions] The [Open positions](../widgets/open-positions) widget now features a new **Close all** option, offering enhanced management capabilities. This update provides a more efficient way to handle multiple positions by allowing you to simultaneously close: * All open positions * All open positions with positive PnL * All open positions with negative PnL #### Enhanced price control [#enhanced-price-control] The following enhancements have been implemented for the [Price control](../widgets/price-control) widget: * **Editable price alerts**: You can now adjust existing price alerts by clicking a price. * **Enhanced market additions**: Price and percentage fields now automatically open for editing when a new market is added to the widget. * **Visual indicators**: Arrows near price triggers aren’t shown if the price feed is unavailable, reducing clutter and potential confusion. #### Historical data limits [#historical-data-limits] The [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now provide historical data with a limit of **92 days**. *** ### Resolved issues [#resolved-issues-6] There have been no customer-facing issues reported in this release. ## April 17, 2025 [#april-17-2025] ### New features [#new-features-10] #### Netting account type [#netting-account-type] With this release, a new **Netting** account type has been enabled. It intelligently consolidates all orders placed on the same market into a single position. Previously, the system supported only Hedging, where each order opens a separate position. **Key points of netting** * **Reduced margin requirements**: Instead of calculating margin requirements separately for each position, netting combines them, lowering overall capital needs. * **Lower trading costs**: By holding opposing positions, traders often incur double position swaps. Netting treats these positions as one, reducing unnecessary costs. * **Streamlined position management**: Managing multiple positions manually can become complicated, especially when balancing between different trade sizes, directions, leverages and margin requirements. Netting helps with it by combining positions into a single one. **Netting VS Hedging** Netting may sometimes lack the flexibility required for complex hedging strategies. In contrast, hedging excels by allowing traders to hold both long and short positions simultaneously without offsetting them. This enhances the ability to track and adjust individual trades easily while permitting precise margin management for separate positions. The Hedging type is perfectly suited for traders seeking detailed control over their positions. On the other hand, the Netting type ensures simplicity and reduced margin requirements, making it the perfect choice for straightforward trading strategies. **Workflow changes** When opening a new trading account, you must now choose its type: either Hedging or Netting. This choice is permanent and influences all future trades in the account. In the account selection interface, each account displays its type: `H` for Hedging or `N` for Netting. All existing accounts are automatically assigned to the Hedging type. *** ### Improvements [#improvements-9] #### Improved widget control [#improved-widget-control] With this release, you now have enhanced control over the viewing experience: * **Configuring widget columns**: Certain widgets allow you to configure widget columns in a way that best suits your needs, offering you the flexibility to select which columns you wish to display or hide. Additionally, you can arrange the order of these columns for your convenience, ensuring that the information you prioritize is always at your fingertips. * **Rearranging widget tabs**: All widgets now feature drag-and-drop functionality for rearranging tabs effortlessly. This user-friendly feature offers a more customized and organized interface, making it easier than ever to personalize your widget experience. #### Enhanced Order book [#enhanced-order-book] The Order book widget has been upgraded with new customizable settings. This update introduces intuitive controls, empowering you to adjust the widget view according to your preference: * **Full view**: Shows both buy and sell orders along with the market spread. * **Buy only view**: Displays only buy orders and the market spread. * **Sell only view**: Displays only sell orders and the market spread. *** ### Resolved issues [#resolved-issues-7] There have been no customer-facing issues reported in this release. ## January 15, 2025 [#january-15-2025] ### New features [#new-features-11] #### Take profit, Stop loss, Trailing stop [#take-profit-stop-loss-trailing-stop] With this release, the following new triggers for open positions have been implemented on the platform: * **Take profit**: A take-profit trigger is used to close a position automatically once the market hits a predefined price, ensuring the trader locks in profits. * **Stop loss**: A stop-loss order is a trigger to limit potential losses. It automatically closes a position when its price changes to a predetermined level. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified value. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. These settings can be used when trading on CFD markets and can be applied to Market, Limit, and Stop orders, as well as for currently open positions. The new settings can be enabled when placing an order via the [Place order](../widgets/place-order) widget (Advanced mode). Until a position is fully closed, they can also be adjusted or canceled via the [Open positions](../widgets/open-positions) widget. The information about applied settings is also available in the corresponding widgets: [Closed positions](../widgets/closed-positions), [Open orders](../widgets/open-orders), and [Order history](../widgets/order-history). *** ### Resolved issues [#resolved-issues-8] There have been no customer-facing issues reported in this release. *** ## Past releases [#past-releases] ### December, 2024 [#december-2024] #### New features [#new-features-12] ##### CFD trading [#cfd-trading] With this release, we're excited to announce the support for CFD (Contract for Difference) trading on our brokerage platform. This empowers you to trade with dynamic leverage, using your funds as collateral to secure positions confidently. Enjoy the flexibility to go both long and short, capitalizing on both bullish and bearish markets. Our CFD trading support boasts an intuitive interface, robust risk management tools, and real-time data. ##### Innovative market approach and instrument picker [#innovative-market-approach-and-instrument-picker] * **Market type**: Markets are now classified into Spot and CFD, reflecting their differing parameters. A panel indicating CFD or Spot is now included in all widgets. * **Market parameters and trading schedule**: Click a market name to access its key parameters and scheduled trading sessions. * **Market categories**: Now accessible via the top bar, offering a hierarchical view for easier selection and switching between markets. ##### Account margin settings [#account-margin-settings] Access the new [Account margin settings](../get-started/settings) to monitor your balances and configure assets to be used as collateral for CFD trading. ##### Reworked Place order widget [#reworked-place-order-widget] Place any order with a [single widget](../widgets/place-order) now. Choose Quick IOC Market or Stop with adjusted leverage — all conveniently in one place, along with an order summary. ##### Positions [#positions] Discover two new widgets for position monitoring: * [Open positions](../widgets/open-positions): Offers real-time monitoring of currently open positions with price changes, PnL, used margin, and other parameters. * [Closed positions](../widgets/closed-positions): Provides historical data on position details, prices, and realized PnL. ##### Risk management [#risk-management] You now have three essential widgets to maintain control: * [Margin](../widgets/margin): Monitor your margin account parameters in real time and respond swiftly to changes. * [Price control](../widgets/price-control): Set price alerts tailored to your specific needs and parameters. * [Messages](../widgets/messages): Receive system notifications and price alerts directly. ##### Market data [#market-data] Two new widgets have been introduced to enhance market monitoring: * [Market summary](../widgets/market-summary): Provides detailed information and updates on price changes for a specific market. * [All markets](../widgets/all-markets): Displays price change statistics across all markets simultaneously. #### Improvements [#improvements-10] * Performance has increased significantly, allowing each trader to hold up to 1,000 CFD positions open. * Limits have been increased to 3,000 requests per second. #### Resolved issues [#resolved-issues-9] There have been no customer-facing issues reported in this release. *** ### June 20, 2024 [#june-20-2024] #### Improvements [#improvements-11] * Account selection is now available from the topbar of the Trading terminal. Once you change your account, all the widgets will automatically adjust to show relevant information for the selected account. * Tabs are now available in the Trading terminal. You can place up to 10 tabs to open multiple workspaces simultaneously for better information organization. You can utilize pre-configured layouts for your workspaces or create custom ones. *** ### June 13, 2024 [#june-13-2024] #### New features [#new-features-13] ##### iOS mobile application [#ios-mobile-application] With this release, our team is thrilled to announce the launch of the brand-new iOS mobile app. The mobile app is closely integrated with B2CORE mobile. Along with single sign-on implemented, it allows you to seamlessly navigate between the apps, without re-entering credentials. In the mobile app, just like in the web version of the Trading terminal, you can access all of your BP accounts, place orders, monitor market data, and so on. For your convenience, it all can be done in a very similar way as in the web version. A consistent and user-friendly interface makes using the app easy and intuitive. Among the key features and services that the new BP mobile offers: * The account list with detailed balances, to always keep your funds under control. Creation and renaming of accounts, to keep your funds well organized. * Asset balances screen, with the amounts of free and frozen funds specified and with the possibility to hide assets with zero balances. * The Order book and price chart, to monitor and analyze trading data and make buy or sell decisions, with a quick and easy jump to the order placing screen. * Candles and line charts, with easy switching and the possibility to scroll the data for historical values. * Limit & Market order placing, with all time in force options supported in the Web version (Market: IOC, FOK; Limit: IOC, FOK, GTC, GTD, Day). * Open and history orders lists, with easy access to order parameters and details, quick canceling or repeating an order. * Light and dark themes and many more. ### October 18, 2023 [#october-18-2023] #### New features [#new-features-14] With this initial release, our team is happy to announce the launch of our new Trading terminal. ##### Placing orders [#placing-orders] The platform currently supports placing Market, Limit, Stop Market, and Stop Limit orders (refer to [Order types](../knowledge-base/order-types)). You can also choose from various [Time in force](../knowledge-base/time-in-force) options such as FOK, IOC, GTC, GTD, and DAY. ##### Widgets [#widgets] The platform provides you with enhanced widgets that are specifically designed for convenient trading. These widgets allow you to easily place orders, access the Order book, monitor open orders and order history, and much more. Refer to [Place order](../widgets/place-order) and the other pages of the Widgets section for more information. ##### Dashboard [#dashboard] The customizable dashboard allows you to personalize the layout to suit your needs and keep you focused on what's important. Refer to [Interface overview](../get-started/customizing-your-terminal) to learn more about workspace customization. ## Summary [#summary] This widget provides AI-powered market analysis and trading recommendations for the selected market. AI Assistant The widget is organized into the following sections: * [AI Recommendation](#ai-recommendation): Overall recommendation score. * [Forecast](#forecast): Price target and market sentiment. * [Signal Drivers](#signal-drivers): Technical, on-chain, and sentiment signals. * [Suggested Actions](#suggested-actions): AI-generated trading suggestions. * [Key Metrics](#key-metrics): Market data overview. ## AI Recommendation [#ai-recommendation] Displays a numeric score from 0 to 100 representing the overall AI assessment of the market, along with a label such as **Strong Buy**, **Buy**, **Neutral**, **Sell**, or **Strong Sell**. A higher score indicates a more favorable outlook. ## Forecast [#forecast] **1Y Price Target** The forecasted price in one year and the expected percentage change from the current price. *** **Market Sentiment** A visual bar showing the ratio between bullish and bearish sentiment among market participants. ## Signal Drivers [#signal-drivers] Signals that influence the AI recommendation, categorized into three types: * **Technical**: Signals based on technical analysis indicators such as RSI and Moving Averages. * **On-Chain**: Signals based on blockchain data such as ETF inflows, active addresses, and total value locked (TVL). * **Sentiment**: Signals based on community and analyst opinions. Each signal includes a description and an impact assessment: **Bullish**, **Bearish**, or **Neutral**. ## Suggested Actions [#suggested-actions] A list of AI-generated trading suggestions based on the current market conditions. These are informational recommendations, not automated trading signals. ## Key Metrics [#key-metrics] The following market data is displayed: **All-Time High** The highest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **All-Time Low** The lowest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **24h Volume** The total trading volume over the last 24 hours in USD. *** **Market Cap** The total market capitalization of the asset in USD. AI-generated insights are for informational purposes only. The AI Assistant widget can be enabled or disabled by the platform administrator. If the widget isn't available in the **Add Widget** menu, contact your broker. ## Summary [#summary] Use this widget to monitor price data on all markets available on the platform. The widget is dynamic and is continuously updated in real time. All markets ## Fields [#fields] The following information is provided about each market: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current market price, in the quote asset and in the platform root asset. This value is green if the price is rising and red if it's falling. *** **24h change** The price change over the last 24 hours, in absolute and percentage values. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. ## Summary [#summary] This widget displays the list of all asset balances on your account. Assets ## Settings [#settings] ### Hide zero balances [#hide-zero-balances] Use this option to hide all assets with zero balances from the list. It's enabled by default. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance at your disposal, meaning the difference between your total assets and a sum of all limit orders placed by this time. This value is calculated as *Total – Halted*, where *Halted* is the asset amount frozen on the account for execution of placed Limit orders. *** **Available, \{RAT}** The available balance, in conversion to the platform root asset. *** **Total** The overall amount of the asset available in your wallet, including locked funds. *** **Total, \{RAT}** The total balance, in conversion to the platform root asset. ## Summary [#summary] This widget displays a list of your closed positions on the selected account. The entire history of your closed positions is available. Closed positions The widget lists only closed positions. For a list of currently open positions, use the [Open positions](open-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists closed positions for the last three months. To display positions closed during a specific time period, use the **Select date range** field. The most recently closed positions appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related orders [#view-related-orders] Click the **chevron icon** in a position row to expand a list of position-closing orders. As positions can be partially closed, there may be more than one line. For each executed position-closing order, a separate line is added. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Pos. closed size** The closed volume, in lots, which is equivalent to the corresponding filled order volume. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Close price** The volume-weighted average price (VWAP) of trades related to a position-closing order. *** **Close order ID** The identifier of an order closing the position. *** **Realized PnL, \{RAT}** The actual profit or loss earned, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). *** **\{RAT} notional** The equivalent of the closed volume in the platform root asset. *** **History rate to \{RAT}** The rate to the platform root asset at the moment of position closing. *** **Reason** The reason for closing a position. Possible values: * **Trader**: The position was closed by you. * **Admin**: The position was closed by an Admin. * **Stop-out**: The position was automatically closed by the system, as a result of Stop out. * **Stop loss**: The position was closed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The position was closed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The position was closed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. *** **Open date, time** The date and time when a position was opened. *** **Closed date, time** The date and time when a position-closing order was last updated (fully executed). ## Summary [#summary] This widget helps you monitor margin parameters and statistics. Margin ## Fields [#fields] All values are in displayed in conversion to the platform root asset: **Your margin level** The ratio of your funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. Possible values: * **Empty**: No open positions. * **Low risk**: Everything is ok. * **Margin call**: Your margin level fell below the set Margin call value. You received a notification urging you to increase the margin level to avoid a Stop out. Remember that if you ignore this warning, the margin level may continue to decrease. During the Margin call, you can only close existing positions; opening new positions isn’t possible. * **Stop out level**: Your margin level fell below the set Stop out value; the platform started a process of liquidating your positions. This process continues until the margin level exceeds this required value. **ANY** currently open position can be closed regardless of its side and volume. *** **Margin balance** The total amount of your funds that can be used as a collateral for CFD trading. It’s calculated as Σ(*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*), where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the platform root asset. The Margin balance is continually recalculated based on price fluctuations. An increase in the prices of assets boosts available Balance & Free margin. Conversely, a decrease in asset prices may reduce the available Balance and Free margin. Additionally, a decline in the prices of assets with open positions may trigger Margin calls and Stop outs. *** **Credit** A promotional bonus granted by your broker for margin (CFD and Perpetual) trading, shown in the platform root asset (RAT). When you have no credit, this row shows 0. Credit increases your Equity and Free margin and can be used as collateral to open positions. It becomes available immediately when granted and never expires. However, credit cannot be withdrawn as cash, so it is excluded from your withdrawable balance. Your broker can revoke credit at any time, and the row updates in real time when this happens. The row includes an info tooltip that reads: *Promotional credit for margin trading only. Cannot be withdrawn.* *** **Equity** The potential balance of your account if all your positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. *** **Used margin** The amount of funds that is used for maintaining all your open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **Example** **Step 1: Initial balance** * Margin balance: $10,000 * Opened positions: 0 * Free margin: $10,000 * Used margin: $0 **Step 2: Open a long position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 100 = $1,001 * After opening: * Free margin: $8,999 * Used margin: $1,001 **Step 3: Open a long position (Leverage 1:20)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 20 = $5,005 * After opening: * Free margin: $3,994 * Used margin: $6,006 **Step 4: Open a short position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 9 lots (900,000 units) * Current price: $1 * Required margin: $(900,000 × 1.001) / 100 = $9,009. The system verifies that upon opening this position, the MarketUsedMargin remains valid by satisfying the condition: **MarketUsedMargin** = MAX(*MarketPositionLong*, *MarketPositionShort*) = MAX(6,006, 9,009) = 9,009. Since the condition is met, the position opens. * After opening: * Free margin: $991 * Used margin: $9,009 As a result, you can open multiple opposite positions without significantly increasing the Used margin. Furthermore, closing positions never increases the Used margin. *** **Free margin** The amount of funds that can be used for opening new positions. *** **Unrealized PnL** The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) ## Summary [#summary] Use this widget to assess the current market depth indicating the actual liquidity of an asset, which is evaluated based on the number of currently open orders to buy and sell it as well asset prices and volumes at various price levels. Market depth The widget is dynamic and is continuously updated in real time. The widget displays a chart indicating the overall volume of buy (green) and sell (red) orders at various price levels awaiting execution at the moment. You can hover the mouse pointer over the chart to learn the exact price and volume of an asset traded at a specific price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ## Summary [#summary] Use this widget to monitor statistics on a specific instrument. The widget is dynamic and is continuously updated in real time. Market summary To monitor multiple instruments at a time, use the [Watch list](watch-list) widget. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the first column. To change the market, click the market symbol and select a different one from the list. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current top-of-the-book price, in the quote asset. *** **Current price, \{RAT}** The current top-of-the-book price, in conversion to the platform root asset. *** **24h change** The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h high** The highest trade price over the last 24 hours. This value is always green. *** **24h low** The lowest trade price over the last 24 hours. This value is always red. *** **Info icon** Click this icon to view market details and trading sessions schedule. ## Summary [#summary] This widget displays a list of received notifications, both system and configured via the [Price control](price-control) widget. Messages ## Settings [#settings] ### Mark as read [#mark-as-read] Unread alerts are marked with a red dot in the list: * Click the dot to mark the notification as read. * Click **Mark all as read** to mark all new notifications as read at once. * Click the **three dots** icon in the upper right corner of the widget to access the **Hide read notifications option**. The counter of unread alerts is also displayed on the **bell icon** in the topbar. ## Summary [#summary] This widget displays a list of Limit orders that have been placed from this specific account and are currently open and assigned one of the following [statuses](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. Open orders The widget lists only open orders, that are currently not filled or partially filled. For a list of orders in the final statuses, use the [Order history](order-history) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders for all the time. To display orders for a specific time period, use the **Select date range** field. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled so far. *** **Fee** The total commission paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that hasn’t yet been filled. *** **Limit price** For Limit orders, the Limit price set when placing the order. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set. *** **Used leverage** For margin trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Valid until** The date and time when an order expires. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Admin**: The order was placed by an Admin. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Cancel orders [#cancel-orders] To cancel an order, click the **×** in the corresponding row. To cancel all active orders at once, click the **Cancel all** button in the widget header. ## Summary [#summary] This widget displays a list of your positions currently open on the selected account. Open positions The widget lists only open positions. For a list of closed positions, use the [Closed positions](closed-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists open positions for all the time. To display positions opened during a specific time period, use the **Select date range** field. The most recent position appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related trades [#view-related-trades] Click the **chevron icon** in a position row to expand a list of related trades. ### Close positions [#close-positions] To close a position, hover over it and click the **CLOSE** button that appears. To close all/multiple positions at once, click **Close all** and select the desired option: close all positions or close positions with positive/negative PnL. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Position size** The current position volume, in lots. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Current price** The current market price of the base asset: bid for Long positions and ask for Short positions. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Unrealized PnL, DAY, \{RAT}** The potential profit or loss earned for a current day, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. *** **Unrealized PnL, DAY, %** The potential profit or loss earned for a current day, in percents. *** **Unrealized PnL, Total, \{RAT}** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). *** **Unrealized PnL, Total, %** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset, in percents. *** **Used margin, \{RAT}** The amount of your funds used for maintaining a position, in conversion to the platform root asset. *** **Leverage** The actual leverage ratio used for opening a position. *** **Req. leverage** The leverage ratio you requested when opening a position. *** **\{RAT} notional** The current position size equivalent in the platform root asset. *** **Rate to \{RAT}** The current exchange rate of a quote asset to the platform root asset. *** **Open date, time** The date and time when a position was opened. *** **Updated date, time** The date and time of the latest position-related trade. *** **Reason** The reason for opening a position: * **Trader**: The position was opened by you. * **Admin**: The position was opened by an Admin. * **Webhook alert**: The position was opened via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. ## Summary [#summary] This widget displays a list of currently open buy and sell limit orders for a selected asset along with the current bid-ask spread. Order book The widget is dynamic and is continuously updated in real time. It provides three different sections displaying the following information: * Open sell orders are highlighted in red and listed in the top section. The best ask, which is the sell order with the lowest price, is displayed at the bottom of this list. * Open buy orders are highlighted in green and listed in the bottom section. The best bid, which is the buy order with the highest price, is displayed at the top of this list. * The middle section displays the current bid-ask spread indicating the gap between the best ask and bid prices declared for an asset. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Display only asks/bids [#display-only-asksbids] In the upper part of the widget, you can choose how to display the Order book: * Full view. * Buy orders only + spread. * Sell orders only + spread. ## Fields [#fields] Each row of the Order book provides the following information about a selected market: **Price, \{QUOTE}** The price, in the quote asset. *** **Amount, \{BASE}** The total amount of the base asset available at a corresponding price level. *** **Total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. In addition, you can use the [Market depth](market-depth) widget to evaluate the liquidity of a specific asset based on the overall volume of orders traded at various price levels. For Spot markets, hover over Order book rows to view additional information and buy or sell assets in click: **Average price** The average price, in the quote asset. *** **Total volume** The total amount of the base asset available at a corresponding price level. *** **Grand total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. *** **Buy** / **Sell** Click the button to instantly place a Market order to buy or sell the asset at the selected price level. ## Summary [#summary] This widget provides up-to-date information about the orders executed on a selected market partially or in full, as well as the orders that were canceled, rejected, and expired. The entire order history of your account is available. Order history The widget lists only the orders to which final statuses are assigned. For a list of orders that are still being executed, use the [Open orders](open-orders) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders with the *Completed* status for the last three months. To display orders for a specific time period, use the **Select date range** field. To display orders with specific statuses, select one or more from the dropdown above the list. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled. *** **Fee** The total commissions paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that wasn't filled. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Completed*, *Cancelled*, *Rejected*, or *Expired*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Stop loss**: The order was placed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The order was placed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Summary [#summary] Use this widget to place new orders. Place order The widget has two states: ### The PRO toggle is disabled [#the-pro-toggle-is-disabled] In this state, you can quickly place **IOC Market** and **GTC Limit** orders by selecting the order side (Buy/Sell) and type (Market/Limit), and specifying the order size (in lots) and price (for Limit orders). You can also place orders on CFD markets with the maximum leverage automatically applied. ### The PRO toggle is enabled [#the-pro-toggle-is-enabled] In this state, you get access to more precise order settings, such as: * **Stop orders** * **Time in force** * **Leverage** * **Take profit, Stop loss, Trailing stop** * **Comment** * **Complete order information** The **Comment** field allows you to attach a text note to the order (up to 100 characters). The comment is inherited by the resulting position and can't be edited after the order is placed. ## Settings [#settings] ### Select a market [#select-a-market] The market on which the order will be placed is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Place an order [#place-an-order] To place an order, fill in the parameters, review order details and preliminary calculated values, and then confirm the order by clicking the **Place** button. For a Limit order whose price crosses the current top-of-book — Buy at or above the best ask, or Sell at or below the best bid — the platform shows a confirmation dialog before submission. The dialog shows the entered price and the current best bid/ask, and lets you confirm or cancel the order. This warning is enabled by default; you can disable it from the dialog (**Do not show this warning again**) or from the **Limit order cross-TOB warning** toggle in [Settings](../get-started/settings#action-confirmation). ### Set price triggers [#set-price-triggers] If using **Take profit, Stop loss, Trailing stop**, set the prices in consideration of the current highest market bid/ask or a specified Limit price: These values can be adjusted any time until the position is fully closed via the [Open positions](open-positions) widget. You can't place orders during non-trading hours, according to the trading calendar schedule. The order controls are disabled when the selected account is Halted or Frozen. For more information, see [Account status](../get-started/customizing-your-terminal#account-status). You will not be able to place an order if the execution of the order causes your margin level to fall below the *Margin call* level. The same conditions apply to withdrawal operations. ## Summary [#summary] This widget displays a price chart showing fluctuation of prices for a selected market over a certain time period. Price chart The horizontal axis (X-axis) represents the time scale, and the vertical axis (Y-axis) indicates the price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Customization [#customization] Multiple customization options are provided, allowing you to configure the chart according to your preferences. You can switch between bar, candle, Heikin Ashi, line, area and baseline views, as well as specify the time period for which data should be displayed. The chart supports numerous financial indicators, such as moving averages and regressions, and can feature a variety of custom shapes, including arrows and lines, pitchforks, and various ranges, allowing you to perform an in-depth market analysis. ### Display options [#display-options] The widget supports displaying of open positions, price triggers, open and executed orders. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart) to enable desired options. ## Placing orders [#placing-orders] ### Enable placing orders [#enable-placing-orders] To enable placing orders directly from the Price chart, you need to activate the corresponding settings: 1. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart). 2. Activate the **Market quick trade panel** or **Limit quick trade panel** toggle, or both. 3. If needed, adjust the amount presets. These amounts will be available for quick selection when placing an order. ### Market quick trade panel [#market-quick-trade-panel] If the corresponding setting is activated, the draggable **Market quick trade panel** is constantly displayed on the Price chart. ### Limit quick trade panel [#limit-quick-trade-panel] If the corresponding setting is activated, the **+** will appear when hovering over price levels on the chart. Clicking it will open the **Limit quick trade panel**: * in the upper half of the chart — to sell; * in the lower half of the chart — to buy. ### Place a new order [#place-a-new-order] To place a new Market or Limit order from the Price chart, when a corresponding panel is displayed: 1. Select the **amount** from configured presets. 2. Select a **leverage** ratio, if trading on CFD or PF markets. 3. Click **Buy** or **Sell**. The order will be placed according to the selected type. ## Summary [#summary] Use this widget to configure alerts that will be delivered to the [Messages](messages) widget when an instrument price reaches the specified level. Price control ## Settings [#settings] ### Configure a new alert [#configure-a-new-alert] To configure a new alert: 1. Click the **Add market** button to select a required market from the list. 2. Click the **+** icon below the instrument name to add a new alert trigger. 3. In the displayed fields, specify the exact price or the price change in percents (positive or negative). The other value will be calculated automatically. 4. Click the **check mark icon** to add the trigger. Now you will receive a notification in the [Messages](messages) widget, once the instrument price hits the specified level. You can configure multiple triggers for each instrument. ### Edit alerts [#edit-alerts] Click the price to edit the existing alert. ### Remove alerts [#remove-alerts] Click the **×** button on the trigger panel to remove it and stop receiving corresponding notifications. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ## Summary [#summary] This widget displays a list of untriggered Stop orders created on the selected account. Once a market price reaches your predetermined Stop price, the Stop order is activated and submitted as either a Market or Limit order. It's then removed from this widget. You can now find it in either the [Open orders](open-orders) or [Order history](order-history) widget, depending on its current status. Stop orders ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the Stop Market and Stop Limit orders for all the time. The most recent order appears at the top of the list. To display orders for a specific time period, use the **Select date range** field. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types): Stop Market or Stop Limit. *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Stop price** The stop price specified when creating an order. When the market reaches this price, the Stop order will be placed (as a Market or Limit order. *** **Limit price** The price of a Limit order that will be placed when the Stop price is triggered. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Order ID** The system identifier of an order. ## Summary [#summary] Use this widget to monitor statistics on multiple instruments at a time. The widget is dynamic and is continuously updated in real time. Watch list ## Settings [#settings] ### Add/remove instruments [#addremove-instruments] Click the **Add market** button to select a required market from the list. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Last price** The price of the last trade. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h low** The lowest trade price over the last 24 hours. *** **24h high** The highest trade price over the last 24 hours. Understand the basics and learn everything you need to start using the B2TRADER API Understand the basics and learn everything you need to start using the B2TRADER API Consult an in-depth reference describing REST API requests and responses Consult an in-depth reference describing REST API requests and responses Explore the supported WebSocket API methods and streams Explore the supported WebSocket API methods and streams Connect to the FIX 4.4 API for market data streaming and order execution Connect to the FIX 4.4 API for market data streaming and order execution ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Trading API: Stop orders for closed markets [#trading-api-stop-orders-for-closed-markets] The **Trading API** now accepts **Stop** orders for markets that are closed according to their trading calendar. The order is stored and activates automatically when the market reopens, instead of being rejected at submission. #### Reports API: full account history [#reports-api-full-account-history] Trading reports can now be generated for the entire account history. The previous **92-day** limit has been removed, and an **All data** range is now available for report generation. #### Trading API: market asset identifiers [#trading-api-market-asset-identifiers] The `baseAssetId` and `quoteAssetId` fields have been added to the v6 `/markets` responses, allowing clients to resolve the base and quote assets of each market without additional lookups. #### Accurate unrealized PnL [#accurate-unrealized-pnl] Unrealized PnL returned by the API is now calculated using the correct order book side for each position direction, improving the accuracy of PnL values in position and margin responses. *** ### Resolved issues [#resolved-issues] * Resolved an issue where `WebhookAlert` order reason and position modifier values were returned as numeric codes instead of API enum strings in History API `/v2/orders` responses. ## April 9, 2026 [#april-9-2026] ### New features [#new-features] #### Trading credit in API responses [#trading-credit-in-api-responses] Broker-issued **trading credit** is now exposed through the API. The account margin data response and the real-time margin stream include the current credit amount in the Reference Asset (`creditInRAT`). Credit is included in the account equity and excluded from the withdrawable amount. *** ### Improvements [#improvements-1] #### Webhook Trading API: webhook URL in key listing [#webhook-trading-api-webhook-url-in-key-listing] The list webhook API keys response now includes the `webhookUrl` field, so the configured webhook endpoint can be retrieved for each key. ## March 16, 2026 [#march-16-2026] ### New features [#new-features-1] #### Webhook Trading API [#webhook-trading-api] A new **Webhook Trading API** has been added, enabling automated order creation via webhook alerts with API key authentication. **Key points:** * Create and manage webhook API keys for secure authentication * Receive trading alerts and create orders automatically * Idempotency supported via deduplication ID * Market type routing by symbol prefix (spot, CFD, perpetual) #### Public Account ID [#public-account-id] A new `publicAccountId` field has been added across all API endpoints, providing a human-readable account identifier as an alternative to internal UUIDs. **Affected APIs:** * Trading API — account-related responses and filters * Settings API — account configuration endpoints * History API — all REST endpoints and WebSocket streams * Reports API — report responses and filters #### Long-term trading data history [#long-term-trading-data-history] Date range restrictions have been removed from **Order History** and **Closed Positions** endpoints, allowing access to full trading history without time-based limitations. *** ### Improvements [#improvements-2] #### Transfer subtype field [#transfer-subtype-field] A new `subtype` field has been added to transfer responses in the History API to distinguish **Negative Balance Protection** transfers from manual ones. #### Rounded position prices [#rounded-position-prices] The `positionPriceInRAT` values are now properly rounded in closed position API responses according to the Reference Asset (RAT) scale. *** ### Resolved issues [#resolved-issues-1] * Resolved an issue where `/total-swaps` requests returned HTTP 504 timeout errors. ## March 11, 2026 [#march-11-2026] ### Added FIX API documentation [#added-fix-api-documentation] Added new FIX API section covering Market Data and Trading sessions via the FIX 4.4 protocol. ## March 11, 2026 [#march-11-2026-1] ### Initial version [#initial-version] ## March 2, 2026 [#march-2-2026] ### New features [#new-features-2] #### Trading Terminal AI assistant [#trading-terminal-ai-assistant] A new **AI assistant** has been added to the Trading Terminal, providing traders with an intelligent widget for market analysis and trading support. *** ### Improvements [#improvements-3] #### Public Account ID (preview) [#public-account-id-preview] The `publicAccountId` field has been added to account-related API responses as a preview, ahead of the full rollout across all endpoints. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-3] #### Funding Rates API [#funding-rates-api] New API endpoints have been added for retrieving funding rate data synchronized from **B2CONNECT**, including funding rates, mark price, and funding interval for Perpetual Futures markets. **Key points:** * Funding rate values streamed in real time * Mark price used for position valuation when available from LP * Funding interval synchronized per market configuration * FIX API contract extended with funding data fields #### OHLC Candlestick API [#ohlc-candlestick-api] A new API endpoint has been added for retrieving OHLC (candlestick) data, supporting both **Spot** and **Perpetual Futures** markets. Minute-level candle data is now stored for up to 5 years. OHLC candle data streaming is also available via the WebSocket API using gRPC transport, providing real-time candlestick updates. #### Favorite markets [#favorite-markets] A new **Favorite markets** feature has been added, allowing traders to manage personalized market lists via the Trading API. #### Comment field for orders and positions [#comment-field-for-orders-and-positions] A new `comment` field has been added to order and position responses across REST, WebSocket, and History APIs. The comment can be set when placing an order and is propagated to the associated position and execution records. #### B2COPY Integration API [#b2copy-integration-api] New API endpoints have been added for **B2COPY** and IB (Introducing Broker) integrations, including special account types for copy trading. The `isCopyTradingAccount` field has been added to the `/api/v1/total-fundings` endpoint. *** ### Improvements [#improvements-4] #### FIX API: enhanced request throughput [#fix-api-enhanced-request-throughput] The FIX API trading request processing has been optimized to support up to 100 requests per second per connection. All `TimeInForce` types are now supported, including **GTD** (Good Till Date). #### Multilingual support [#multilingual-support] Trading API, Settings API, and Reports API endpoints now support multilingual content with full Unicode character support, enabling localized responses for configurable fields, report names, and templates. #### Stop Market order calculation [#stop-market-order-calculation] The **Value** and **Amount** calculation for **Stop Market** orders has been corrected for **Spot** markets. **Slippage Rate** has been removed from **CFD** and **Perpetual Futures** order calculations. #### Trading API: empty categories hidden [#trading-api-empty-categories-hidden] Empty market categories are now automatically excluded from Trading API responses, reducing unnecessary data in category listings. #### Balance API: zero balance for all assets [#balance-api-zero-balance-for-all-assets] Assets without prior balance operations now return a zero balance in API responses instead of being omitted. #### Cross-rate market configuration [#cross-rate-market-configuration] Markets used exclusively for cross-rate calculations can now be disabled for trading while remaining active for rate conversion. #### History API: extended contracts [#history-api-extended-contracts] Positions and Events API responses have been extended with additional fields. The `updatedAt` field is now available as a sorting and filtering parameter in History Server API endpoints. #### Settings API: market update endpoint [#settings-api-market-update-endpoint] The market update endpoint has been changed from `PATCH` to `PUT` semantics, requiring the full market object in the request body. #### Settings API: legacy endpoints removed [#settings-api-legacy-endpoints-removed] Legacy commission and routing rule endpoints have been removed following the tier commission update. Use the current endpoints as documented in the API reference. *** ### Resolved issues [#resolved-issues-2] * Resolved an issue where `takeProfitPrice` and `stopLossPrice` values were missing from the History Server `/v2/orders` endpoint responses. * Resolved an issue where bulk order cancellation returned a successful result for non-existing orders. * Resolved an issue where bulk order cancellation returned a successful result for orders that could not be cancelled. * Resolved incorrect error codes returned when `closePositionLotAmount` was set to `0`, a negative value, or an empty string. * Resolved an issue where the WebSocket Book stream continued sending prices with an outdated tick size after market parameter changes. * Resolved an issue where negative spreads in the **Market Data API** were not handled correctly. * Resolved an issue where orders could not be created when using the default 24/7 calendar. * Resolved an issue where the `/external-orders` API returned `null` for `rejectReason` although the Trading Server received a reason from the LP. Customize your Trading Terminal and configure settings Customize your Trading Terminal and configure settings Explore and manage all available trading widgets Explore and manage all available trading widgets Learn basic terms and values used across the platform Learn basic terms and values used across the platform The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](trading) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `V` — Market Data Request (Client → B2TRADER) * `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER) * `X` — Market Data — Incremental Refresh (Client ← B2TRADER) * `Y` — Market Data Request Reject (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Market Data session, use the following parameters provided by B2TRADER: * **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint) * **SenderCompID**: Your client identifier for the Market Data session * **TargetCompID**: The server identifier for the Market Data session * **Protocol**: FIX 4.4 The Market Data connection does not require SSL. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request. ```text title="Example" 8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Optional. ```text title="Example" 8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^ ``` *** ## Market Data Request (V) [#market-data-request-v] This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol. After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update. To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout. **`262 MDReqID`** `String` The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard. **`263 SubscriptionRequestType`** `int` The type of response expected from the server. Required. Possible values: * `1` — Subscribe: receive updates as the market status changes * `2` — Unsubscribe: stop streaming market data for the specified symbol **`264 MarketDepth`** `int` The market depth for an order book snapshot. Required. Possible values: * `0` — Full order book * `1` — Top-of-the-book prices **`265 MDUpdateType`** `int` The update type. Required. Must be `1` (incremental updates for changed price levels only). **`267 NoMDEntryTypes`** `int` The number of `<269>` MDEntryType entries requested. Required. > Repeating group: **`269 MDEntryType`** `int` The side of the quote. Required. Possible values: * `0` — Bid * `1` — Ask **`146 NoRelatedSym`** `int` The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each. > Repeating group: **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```text title="Example (Client → B2TRADER)" 8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^ ``` ## Market Data — Snapshot/Full Refresh (W) [#market-data--snapshotfull-refresh-w] This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^ ``` ## Market Data — Incremental Refresh (X) [#market-data--incremental-refresh-x] This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. * Must be unique among active entries when `<279>` MDUpdateAction is `0` (New) * Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete) **`279 MDUpdateAction`** `int` The update type. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — New * `1` — Change * `2` — Delete **`58 Text`** `String` Additional context. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^ ``` ## Market Data Request Reject (Y) [#market-data-request-reject-y] This message is sent by the server to reject a Market Data Request due to business or technical reasons. **`262 MDReqID`** `String` The identifier of the rejected Market Data Request. Required. **`281 MDReqRejReason`** `int` The reason why the request is rejected. Optional. Possible values: * `0` — Unknown symbol * `1` — Duplicate MDReqID * `2` — Insufficient bandwidth * `3` — Insufficient permissions * `4` — Unsupported SubscriptionRequestType * `5` — Unsupported MarketDepth * `6` — Unsupported MDUpdateType * `8` — Unsupported MDEntryType **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^ ``` The Trading session enables order placement and execution management via the FIX 4.4 protocol. Use this session to submit orders and receive real-time execution reports for your trading activity. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Trading** session only. For real-time order book streaming, use the [Market Data](market-data) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `D` — New Order Single (Client → B2TRADER) * `8` — Execution Report (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Trading session, use the following parameters provided by B2TRADER: * **Host and port**: The Trading endpoint (provided separately from the Market Data endpoint) * **SenderCompID**: Your client identifier for the Trading session * **TargetCompID**: The server identifier for the Trading session * **Protocol**: FIX 4.4 The Trading connection requires SSL with a self-signed certificate. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=117^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=117^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=93^35=A^1=68a4446ac84827ff5cd35c74^34=225^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=054^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Conditional — required when sent in response to a Test Request. ```text title="Example" 8=FIX.4.4^9=79^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=156^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Required. ```text title="Example" 8=FIX.4.4^9=87^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=250^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=90^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=176^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=105^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=Session terminated by client^10=183^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=81^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=009^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Execution Report with rejected status and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=128^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=11^372=D^373=1^58=Required tag missing: ClOrdID^10=126^ ``` *** ## New Order Single (D) [#new-order-single-d] This message is sent by the client to place a new order. The server responds with an Execution Report confirming the order status. For details on supported order types, see [Order types](../get-started/order-types). For details on time-in-force options, see [Time in force](../get-started/time-in-force). **`11 ClOrdID`** `String` The unique client-assigned order identifier. Required. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`38 OrderQty`** `Qty` The order quantity. Required. Must be greater than zero. The decimal precision must not exceed the market's amount scale, and the value must be at least the market's minimum amount. **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`59 TimeInForce`** `char` The order's time-in-force policy. Required. Possible values: * `0` — Day * `1` — Good Till Cancel (GTC) * `3` — Immediate or Cancel (IOC) * `4` — Fill or Kill (FOK) * `6` — Good Till Date (GTD) **`44 Price`** `Price` The order price. Conditional — required when `<40>` OrdType is `2` (Limit), must not be present when `<40>` OrdType is `1` (Market). Must be greater than zero. The decimal precision must not exceed the market's price scale. **`126 ExpireTime`** `UTCTimestamp` The order expiration time. Conditional — required when `<59>` TimeInForce is `6` (GTD), must not be present otherwise. **`60 TransactTime`** `UTCTimestamp` The time of order creation. Required. ```text title="Limit order example (Client → B2TRADER)" 8=FIX.4.4^9=168^35=D^34=3^52=20231220-09:15:30.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order001^55=spot.btc_usdt^54=1^38=0.5^40=2^44=42500.00^59=1^60=20231220-09:15:30.000^10=123^ ``` ```text title="Market order example (Client → B2TRADER)" 8=FIX.4.4^9=155^35=D^34=4^52=20231220-09:16:00.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order002^55=spot.btc_usdt^54=2^38=0.1^40=1^59=3^60=20231220-09:16:00.000^10=045^ ``` ## Execution Report (8) [#execution-report-8] This message is sent by the server to confirm order status changes, including acknowledgment of new orders, fills, partial fills, cancellations, and rejections. For details on order statuses, see [Order statuses](../get-started/order-statuses). **`37 OrderID`** `String` The server-assigned unique order identifier. Required. **`11 ClOrdID`** `String` The client-assigned order identifier from the original New Order Single. Required. **`17 ExecID`** `String` The unique execution identifier. Present for trade executions. **`150 ExecType`** `char` The type of execution being reported. Required. Possible values: * `0` — New: order has been accepted * `4` — Canceled: order has been canceled by the server (e.g., IOC order partially filled, GTD order expired, or market settings changed) * `8` — Rejected: order has been rejected * `F` — Trade: order has been partially or fully filled **`39 OrdStatus`** `char` The current order status. Required. Possible values: * `0` — New * `1` — Partially filled * `2` — Filled * `4` — Canceled * `8` — Rejected **`1 Account`** `String` The account identifier. Required. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`44 Price`** `Price` The order price. Present for Limit orders. **`6 AvgPx`** `Price` The average price of all fills on this order. Required. **`14 CumQty`** `Qty` The total filled quantity. Required. **`151 LeavesQty`** `Qty` The remaining quantity to be filled. Required. Set to `0` for Canceled or Rejected orders. **`31 LastPx`** `Price` The price of the last fill. Present when `<150>` ExecType is `F` (Trade). **`32 LastQty`** `Qty` The quantity of the last fill. Present when `<150>` ExecType is `F` (Trade). **`15 Currency`** `String` The quote asset identifier. Optional. **`60 TransactTime`** `UTCTimestamp` The transaction time. Required. **`64 SettlDate`** `String` The settlement date in `YYYYMMDD` format. Required. **`58 Text`** `String` Additional information, such as the rejection reason. Optional. ```text title="New order accepted (B2TRADER → Client)" 8=FIX.4.4^9=220^35=8^34=5^52=20231220-09:15:30.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^150=0^39=0^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=0^14=0^151=0.5^60=20231220-09:15:30.100^64=20231220^10=087^ ``` ```text title="Trade execution (B2TRADER → Client)" 8=FIX.4.4^9=245^35=8^34=6^52=20231220-09:15:30.200^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^17=01HBXK5V3R8NQ7YR^150=F^39=2^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=42500.00^14=0.5^151=0^31=42500.00^32=0.5^15=usdt^60=20231220-09:15:30.200^64=20231220^10=154^ ``` ```text title="Order rejected (B2TRADER → Client)" 8=FIX.4.4^9=214^35=8^34=7^52=20231220-09:16:00.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YS^11=order002^150=8^39=8^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=2^40=1^6=0^14=0^151=0^58=Insufficient balance^60=20231220-09:16:00.100^64=20231220^10=201^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard session-level Reject or Execution Report rejection. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=100^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=006^ ``` Each trading account has an `accountStatus` field that determines which operations are permitted on the account. The field is returned on account objects by the API, such as in [Get accounts](../rest-api/settings). An account can be assigned one of the following statuses: * **Active**: All operations are permitted, including placing, modifying, and canceling orders, opening and closing positions, deposits, and withdrawals. * **Halted**: Trader-initiated trading is blocked. Requests to place, modify, or cancel orders and to open or close positions are rejected. Deposits and withdrawals remain allowed. Managed trading through the Management API (MAM, B2COPY) continues to work. * **Frozen**: All operations are blocked. Trading, deposits, and withdrawals are unavailable, and the account is view-only. Stop-out liquidation still executes as a safety mechanism. * **Archived**: The account is decommissioned and hidden from all user-facing surfaces. Real-time profit and loss, equity, margin level, and funding settlement continue for all statuses. Archived accounts are never returned in the trading API account list. They are excluded server-side, so an account that changes to *Archived* stops appearing in [Get accounts](../rest-api/settings) responses. A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. ## Introduction [#introduction] B2TRADER provides developers with three distinct methods for data delivery, each optimized for specific use cases and performance requirements: REST, WebSocket, and FIX APIs. The **REST API** provides read access to market data as well as both read and write access to trading operations. It serves as the foundation for synchronous data operations where immediate confirmation and guaranteed delivery are essential. The **WebSocket API** provides access to public market data streaming as well as private account updates. It delivers real-time updates with low latency, making it ideal for live trading environments. The **FIX API** provides direct access to market data and trading via the FIX 4.4 protocol. It is designed for institutional clients and algorithmic trading systems that require standardized, low-latency connectivity using the industry-standard Financial Information eXchange protocol. This approach provides developers with flexible options for building robust, scalable trading applications that can handle both operational requirements and real-time market dynamics. ### When to use REST API [#when-to-use-rest-api] * **Account configuration and settings**: Managing user preferences and system configurations. * **Order placement and modification**: Creating, updating, and canceling trading orders. * **Historical data retrieval**: Accessing past trading records and market data. * **One-time data requests**: Retrieving specific information that doesn't require continuous updates. * **Administrative operations**: Account management and system administration tasks. ### When to use WebSocket API [#when-to-use-websocket-api] * **Real-time price monitoring**: Live market price feeds and ticker updates. * **Live position tracking**: Continuous monitoring of open and closed positions. * **Order book visualization**: Real-time depth of market data. * **Market data feeds**: Streaming market statistics and trading activity. * **Account balance monitoring**: Live updates of account equity and margin status. ### When to use FIX API [#when-to-use-fix-api] * **Institutional connectivity**: Standardized FIX 4.4 protocol for professional trading infrastructure. * **Algorithmic trading**: Low-latency order execution and market data for automated strategies. * **Market data streaming**: Real-time order book snapshots and incremental updates via FIX protocol. * **Multi-venue integration**: Unified FIX connectivity for systems already integrated with other FIX-based venues. ## General considerations [#general-considerations] The following applies to all interface descriptions provided in this documentation: * **Endpoints**: All endpoints are relative and resolved based on a specified hostname (indicated as `{host}`). * **Authentication**: REST and WebSocket APIs require an access token (see [Authentication](#authentication)). The FIX API uses in-band authentication via the Logon message with Username, Password, and Account fields provided by B2TRADER. * **Data format**: REST and WebSocket APIs return results in JSON format. The FIX API uses the standard FIX 4.4 message format. * **Security**: All communications use secure protocols (HTTPS for REST, WSS for WebSocket, encrypted TCP for FIX). ### Authentication [#authentication] API access requires an access token for both REST and WebSocket connections. Authentication follows a two-step process: 1. Generate an offline token in the Trading terminal. 2. Exchange the offline token for an access token via API call. #### Token types [#token-types] **Offline token** * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time * **Purpose**: Generate access tokens **Access token** * **Type**: Bearer token * **Validity**: 60 minutes * **Purpose**: Authorize API requests ### Generate offline token [#generate-offline-token] To generate an offline token: 1. In the Trading terminal, open **Settings** and select **API token management**. 2. Click **+ Create new**. 3. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 4. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ### Obtain access token [#obtain-access-token] Request an access token using your offline token. **Endpoint**: `POST` `/frontoffice/api/v4/access-token` **Request body**: ```json { "token": "{YOUR_OFFLINE_TOKEN}" } ``` **Response** (Success): ```json { "accessToken": "{YOUR_ACCESS_TOKEN}", "expiresIn": 3600, "tokenType": "Bearer" } ``` **`accessToken`** `string` The access token for API authorization. **`expiresIn`** `integer` The token lifetime, in seconds. **`tokenType`** `string` The authentication type, always `"Bearer"`. ### Using access tokens [#using-access-tokens] Include the access token in API requests: ```http title="REST" Authorization: Bearer {YOUR_ACCESS_TOKEN} ``` ```http title="WebSocket" {URL}?access_token={YOUR_ACCESS_TOKEN} ``` Access tokens must be refreshed before expiration by repeating the Step 2 with your offline token. ## REST API: Synchronous data operations [#rest-api-synchronous-data-operations] The REST API serves as the foundation for synchronous data operations within the B2TRADER platform. This approach follows standard HTTP protocols and is ideal for operations requiring immediate confirmation and guaranteed delivery. ### Key characteristics [#key-characteristics] * **Request-response operations** where immediate confirmation is required. * **Account management** including settings and configuration. * **Order placement and modification** with guaranteed delivery. * **Historical data retrieval** for analysis and reporting. * **Stateless operations** that don't require persistent connections. ### HTTP response codes [#http-response-codes] B2TRADER API uses conventional HTTP response codes to indicate the success or failure of requests. **Success codes:** * `200 OK` — Request successful **Error codes:** * `400 Bad Request` — Invalid request parameters * `401 Unauthorized` — Authentication required * `403 Forbidden` — Insufficient permissions * `404 Not Found` — Resource not found * `429 Too Many Requests` — [Rate limit](#rate-limits) exceeded * `500 Internal Server Error` — Server error In case of an error, an object will be returned with the following structure: ```json { "code": "text", "message": "text", "details": { "source": "text", "message": "text", "stackTrace": "text" } } ``` ### Available endpoints [#available-endpoints] * **[Trading operations](../rest-api/trading)**: Create, modify, and cancel orders; open, close, and modify positions; control price trigger settings. * **[Trading history](../rest-api/history)**: Retrieve detailed execution records for positions and orders. * **[Settings and configurations](../rest-api/settings)**: Access account information, market specifications, trading sessions, and asset details. ### Rate limits [#rate-limits] Rate limits are applied per minute for each unique **AccountId** to ensure fair resource usage and maintain optimal API performance. All limits use the **Fixed Window** strategy. When rate limits are exceeded, the API returns a `429 Too Many Requests` HTTP status code. #### Trading methods [#trading-methods] * **Default limit**: 600 requests per minute for all methods. * **Reduced limit (200 rpm)** applies to: * Get order data methods * Bulk close positions method * Price triggers methods #### History methods [#history-methods] * **All request types**: 60 requests per minute. #### Settings methods [#settings-methods] * **GET requests**: 100 requests per minute. * **POST and DELETE requests**: 60 requests per minute. Rate limits are calculated independently for each method category. For example, you can make 100 GET requests to Settings methods and 60 requests to History methods within the same minute without hitting rate limits. ## WebSocket API: Real-time data streaming [#websocket-api-real-time-data-streaming] The WebSocket API delivers real-time updates with minimal latency, essential for modern trading applications. The implementation uses unidirectional communication from server to client, ensuring efficient data delivery. ### Key characteristics [#key-characteristics-1] * **Unidirectional communication** from server to client for optimal performance. * **Real-time market data** for live trading environments. * **Position and order updates** as they occur in real-time. * **Low-latency data delivery** for time-sensitive trading operations. * **Persistent connections** maintaining continuous data flow. ### SignalR implementation [#signalr-implementation] B2TRADER utilizes **AspNetCore SignalR** for WebSocket message organization and transmission, providing a robust and scalable real-time communication framework. **Resources:** * [Official GitHub Repository](https://github.com/dotnet/aspnetcore/tree/main/src/SignalR) * [Official Documentation](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr) SignalR provides a structured approach to real-time communication through standardized message formatting and connection management. ### Connection lifecycle [#connection-lifecycle] The data transfer process consists of two essential phases: 1. **Connection establishment** — Initial handshake, authentication, and subscription setup. 2. **Data streaming** — Continuous real-time data flow with automatic reconnection handling. ### Message types [#message-types] SignalR utilizes numerical `type` indicators for different operations: ### Available stream types [#available-stream-types] * **[Trading streams](../ws-api/trading)**: Track active orders, open and closed positions. * **[Market data streams](../ws-api/market-data)**: Get real-time order book updates, market statistics and price changes. * **[Account information streams](../ws-api/account-info)**: Get live account balance and margin updates. ## FIX API: Standardized protocol connectivity [#fix-api-standardized-protocol-connectivity] The FIX API provides direct access to B2TRADER via the FIX 4.4 protocol, the industry standard for electronic trading communication. It is designed for institutional clients and algorithmic trading systems. ### Key characteristics [#key-characteristics-2] * **FIX 4.4 protocol** for standardized, vendor-neutral connectivity. * **Dedicated sessions** for Market Data and Trading with separate endpoints. * **In-band authentication** via Logon message (Username, Password, Account). * **Real-time market data** with order book snapshots and incremental updates. * **Session management** with Heartbeat, Test Request, and Sequence Reset support. ### Authentication [#authentication-1] Unlike REST and WebSocket APIs, the FIX API does not use access tokens. Authentication is performed in-band as part of the FIX Logon message using credentials provided by B2TRADER: * **Username** (`<553>`): The client username * **Password** (`<554>`): The client password * **Account** (`<1>`): The account identifier ### Available session types [#available-session-types] * **[Market Data](../fix-api/market-data)**: Subscribe to real-time order book updates, snapshots, and incremental refreshes. * **[Trading](../fix-api/trading)**: Place orders and receive execution reports in real time. ## Integration best practices [#integration-best-practices] ### API selection strategy [#api-selection-strategy] * Use **REST API** for operational tasks requiring confirmation (order placement, account management). * Use **WebSocket API** for real-time monitoring and market data visualization. * Use **FIX API** for institutional connectivity, algorithmic trading, and integration with existing FIX-based infrastructure. * Implement multiple APIs in comprehensive trading applications for optimal functionality. ### Performance optimization [#performance-optimization] * Implement proper connection pooling for REST API requests. * Use WebSocket subscriptions efficiently by subscribing only to required data streams. * Handle reconnection logic for WebSocket connections to ensure data continuity. * Implement appropriate error handling and retry mechanisms. ### Security considerations [#security-considerations] * Store authentication tokens securely and implement token refresh mechanisms. * Use secure connections (HTTPS/WSS) for all API communications. * Implement proper input validation and sanitization. * Monitor API usage and implement rate limiting on the client side. This comprehensive API architecture enables developers to build sophisticated trading applications that can handle both real-time market dynamics and operational trading requirements efficiently. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all Limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the platform, without taking into account the time settings of the devices from which the platform is accessed. ## Get full balance [#get-full-balance] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"FullBalance"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "FullBalance", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of balance objects. **`item.assetId`** `string` The asset identifier. **`item.available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`item.total`** `decimal string` The overall amount of the asset, including locked funds. **`item.locked`** `decimal string` The asset amount locked on the account for execution of all placed Limit orders. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "assetId": "eur", "available": "497838.8", "total": "497838.8", "locked": "0" } ] } ``` ## Get margin data [#get-margin-data] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"MarginData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "MarginData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.marginBalanceInRAT`** `decimal string` The total amount of funds that can be used as a collateral for trading, in RAT. This value is calculated as SUM (*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*) Where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the BP root asset. **`item.creditInRAT`** `decimal string` The promotional trading credit granted to the account by the broker, in RAT. Credit is included in the account equity but excluded from the withdrawable amount. During a rolling deployment, older payloads might omit this field. In that case, default it to `0`. **`item.unrealizedPnlInRAT`** `decimal string` The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) **`item.equityInRAT`** `decimal string` The potential balance if all open positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. **`item.usedMarginInRAT`** `decimal string` The amount of funds that is used for maintaining all open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **`item.freeMarginInRAT`** `decimal string` The amount of funds that can be used for opening new positions. **`item.marginLevel`** `decimal string` The ratio of funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "marginBalanceInRAT": "497838.8", "creditInRAT": "0", "unrealizedPnlInRAT": "-5.25", "equityInRAT": "497833.55", "usedMarginInRAT": "100.18", "freeMarginInRAT": "497733.37", "marginLevel": "4969.3905" } } ``` ## Get order book [#get-order-book] ### Connection [#connection] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Book"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eur_chf" ], "invocationId": "0", "target": "Book", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.askTotalAmount`** `string` The total ask amount. **`item.bidTotalAmount`** `string` The total bid amount. **`item.asks`** `array of objects` The array of ask price objects. **`item.asks.price`** `string` The price, in the quote asset. **`item.asks.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.asks.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.bids`** `array of objects` The array of bid price objects. **`item.bids.price`** `string` The price, in the quote asset. **`item.bids.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.bids.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.version`** `string` The order book version. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eur_chf", "askTotalAmount": "18700000", "bidTotalAmount": "19100000", "asks": [ { "price": "0.93677", "amount": "5000000", "total": "4683850" }, { "price": "0.93676", "amount": "0", "total": "0" }, { "price": "0.93676", "amount": "0", "total": "0" } ], "bids": [ { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93655", "amount": "5000000", "total": "4682750" } ], "version": "12498", "snapshot": false } } ``` ## Get trading data [#get-trading-data] ### Connection [#connection-1] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"TradingData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.bnb_btc" ] ], "invocationId": "0", "target": "TradingData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.markets.displayName`** `string` The market ticker. **`item.markets.fullName`** `string` The market full name or description (optional). **`item.markets.price`** `decimal string` The current top-of-the-book price, in the quote asset. **`item.markets.priceInRAT`** `decimal string` The current top-of-the-book price, in conversion to the root asset of the platform. **`item.markets.priceChange24hr`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.markets.priceChangeAbs24hr`** `decimal string` The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. **`item.markets.highPrice24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.markets.lowPrice24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.markets.markPrice`** `decimal string` *Applicable to Perpetual markets only.* The mid-spread price, in conversion to RAT. **`item.markets.fundingRate`** `decimal string` *Applicable to Perpetual markets only.* The current funding rate. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "cfd.eur_chf", "type": "Cfd", "displayName": "cfd.eur_chf", "fullName": "", "price": "0.93586", "priceInRAT": "1", "priceChange24hr": "-0.0006", "priceChangeAbs24hr": "-0.00049", "highPrice24hr": "0.93695", "lowPrice24hr": "0.93134", "markPrice": null, "fundingRate": null } ], "snapshot": false } } ``` ## Get top of the book [#get-top-of-the-book] ### Connection [#connection-2] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Tob"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.eth_usdt" ] ], "invocationId": "0", "target": "Tob", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.ask`** `decimal string` The top-of-the-book ask price. **`item.markets.bid`** `decimal string` The top-of-the-book bid price. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "spot.eth_usdt", "ask": "2483.82", "bid": "2483.81" } ], "snapshot": false } } ``` ## Get trading chart [#get-trading-chart] ### Connection [#connection-3] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` and `timescale` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Chart"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eth_eur@15m" ], "invocationId": "0", "target": "Chart", "type": 4 } ``` *** ### Message [#message-3] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.low`** `decimal string` The lowest base asset price within the specified time interval. **`item.high`** `decimal string` The highest base asset price within the specified time interval. **`item.open`** `decimal string` The base asset price at the beginning of the specified time interval. **`item.close`** `decimal string` The base asset price at the end of the specified time interval. **`item.start`** `dateTime` The beginning of the specified time interval, in ISO 8601 format. **`item.end`** `dateTime` The end of the specified time interval, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eth_eur", "low": "2240.88", "high": "2270.29", "open": "2265.63", "close": "2255.99", "start": "2025-05-21T15:30:00Z", "end": "2025-05-21T15:45:00Z" } } ``` ## Get market summary [#get-market-summary] ### Connection [#connection-4] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Summary"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "cfd.eur_chf" ] ], "invocationId": "0", "target": "Summary", "type": 4 } ``` *** ### Message [#message-4] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.items`** `array of objects` The array of data objects. **`item.items.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.items.last`** `decimal string` The price of the last trade. **`item.items.high24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.items.low24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.items.percentChange`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "items": [ { "marketId": "cfd.eur_chf", "last": "0.93597", "high24hr": "0.93695", "low24hr": "0.93134", "percentChange": "-0.02" } ], "snapshot": false } } ``` ## Get open orders [#get-open-orders] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenOrders", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of market objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.status`** `string` The current [order status](../get-started/order-statuses). Possible values: * `Started` * `Pending` * `Working` **`item.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`item.reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`item.remainingAmount`** `decimal string` The order amount that hasn't yet been filled, in the base asset. **`item.requestedPrice`** `decimal string` The limit price for Limit orders; `null` for Market orders. **`item.executionPrice`** `decimal string` The volume-weighted average price of the order executions. **`item.createdAt`** `dateTime` The timestamp when the order was created, in ISO 8601 format. **`item.updatedAt`** `dateTime` The timestamp of the most recent update to the order, in ISO 8601 format. **`item.cancellationDate`** `dateTime` The timestamp when the order was cancelled or expired, in ISO 8601 format; `null` if not cancelled. **`item.commissionAssetId`** `string` The currency in which the commission was held. **`item.commissionAmount`** `decimal string` The total commissions put on hold for executing the order. **`item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when placing the order. **`item.fillFactor`** `decimal string` The proportion of the order amount filled so far, where `1` represents 100% fulfillment. **`item.comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.stopLoss`** `decimal string` The Stop Loss price, if set. ```json { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "orderId": "01JVQBFSTVC40VK03A0AY7K016", "timeInForce": "Gtc", "status": "Pending", "source": "Manual", "reason": "Trader", "side": "Buy", "orderType": "Limit", "requestedAmount": "10000", "remainingAmount": "10000", "requestedPrice": "0.9", "executionPrice": "0", "createdAt": "2025-05-20T17:22:31.899Z", "updatedAt": "2025-05-20T17:22:31.9001213Z", "cancellationDate": null, "commissionAssetId": "eur", "commissionAmount": "0", "leverage": 1, "fillFactor": "0", "takeProfit": null, "stopLoss": null, "comment": null } ] } ``` ## Get open positions [#get-open-positions] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenPositions"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenPositions", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.item`** `array of objects` The array of position objects. **`item.item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.item.marketDisplayName`** `string` The market ticker. **`item.item.marketFullName`** `string` The market full name or description (optional). **`item.item.createdAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. **`item.item.updatedAt`** `dateTime` The timestamp of the most recent update to the position, in ISO 8601 format. **`item.item.side`** `string` The position side. Possible values: * `Buy` * `Sell` **`item.item.status`** `string` The current position status. Always `"Open"`. **`item.item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when opening the position. **`item.item.positionLotAmount`** `decimal string` The position volume, in lots. **`item.item.positionPriceInRAT`** `decimal string` The current position price, in conversion to RAT. **`item.item.rateToRAT`** `decimal string` The current exchange rate of a quote asset to RAT. **`item.item.usedMarginInRAT`** `decimal string` The amount of trader’s funds used for maintaining a position, in conversion to RAT. **`item.item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.item.currentMarketPrice`** `decimal string` The current market price of the base asset: bid for Long positions and ask for Short positions. **`item.item.unrealizedPnlDayInRAT`** `decimal string` The potential profit or loss earned for a current day, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. **`item.item.unrealizedPnlDayPercent`** `decimal string` The potential profit or loss earned for a current day, in percents. **`item.item.unrealizedPnlTotalInRAT`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). **`item.item.unrealizedPnlTotalPercent`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT, in percents. **`item.item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.item.stopLoss`** `decimal string` The Stop Loss price, if set. **`item.item.positionModifier`** `string` The reason for the latest position update. **`item.item.comment`** `string | nullable` The text note inherited from the opening order, up to 100 characters. **`snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "item": [ { "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-03-12T06:36:31.257Z", "updatedAt": "2025-03-12T06:36:31.257Z", "side": "Buy", "status": "Open", "leverage": 1, "positionLotAmount": "0.01", "positionPriceInRAT": "1000.46", "rateToRAT": "1.07", "usedMarginInRAT": "1000.53", "openPrice": "0.96304", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "1.86", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-29.93", "unrealizedPnlTotalPercent": "-0.0291", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null }, { "positionId": "01JVQB9ZWJ6G4QV0P98X0QWNA7", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-05-20T17:19:21.49Z", "updatedAt": "2025-05-20T17:19:21.491321Z", "side": "Buy", "status": "Open", "leverage": 100, "positionLotAmount": "0.1", "positionPriceInRAT": "10004.6", "rateToRAT": "1.07", "usedMarginInRAT": "100.06", "openPrice": "0.93666", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "18.61", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-17.02", "unrealizedPnlTotalPercent": "-0.0017", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null } ], "snapshot": false } } ``` ## Get closed positions [#get-closed-positions] ### Connection [#connection-2] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"ClosePositionsOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "ClosePositionsOrders", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of position objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.positionCloseLotAmount`** `decimal string` The closed volume, in lots, which is equivalent to the corresponding filled order volume. **`item.reason`** `string` The reason for position closing. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.realizedPnlInRAT`** `decimal string` The actual profit or loss earned, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). **`item.closedAt`** `dateTime` The timestamp when the position was closed, in ISO 8601 format. **`item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`item.positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`item.rateToRAT`** `decimal string` The conversion rate to RAT. **`item.openedAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketFullName": "", "marketDisplayName": "EUR/CHF", "marketType": "Cfd", "orderId": "01JVSQ8WFA3QZ6AQTKYPXVXDWA", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.01", "reason": "Trader", "realizedPnlInRAT": "-29.25", "closedAt": "2025-05-21T15:26:57.0027785Z", "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "openPrice": "0.96304", "closePrice": "0.93571", "positionPriceInRAT": "1001.2", "rateToRAT": "1.07", "openedAt": "2025-03-12T06:36:31.257Z" } ] } ``` ## Open positions [#open-positions] ### Get executions for an open position [#get-executions-for-an-open-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/executions/list` #### Summary [#summary] Use this method to retrieve execution details for a specific open position using its position identifier. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`positionId`** `required` The position identifier. ##### Body [#body] **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`offset`** `integer · int32 | nullable` The number of items to skip before starting to collect the result set. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PMT0VMJG5B8XBDNZ7FNM1F/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "offset": 0 } ``` #### Response [#response] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VNWB23GSRN2XQAJD6Q", "baseAmount": "0.314", "executionPrice": "4603.5", "commissionAmountInRAT": "0", "commissions": [], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VN1F2JPM14AEV6V8YJ", "baseAmount": "0.045", "executionPrice": "4603.49", "commissionAmountInRAT": "0", "commissions": [], "comment": null } ] } ``` ### Get executions for open positions [#get-executions-for-open-positions] `POST` `/frontoffice/api/v4/positions/executions/list` #### Summary [#summary-1] Use this method to retrieve execution details for multiple open positions by providing an array of position identifiers. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`positionIds`** `array · string[]` The array of position identifiers. **`limit`** `integer · int32 | nullable` The maximum number of items to return. ```http title="Request example" POST /frontoffice/api/v4/positions/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "positionIds": [ "01K2PMT0VMJG5B8XBDNZ7FNM1F", "01K2PMXY63HESK110WT1CHMAFA" ], "limit": 5 } ``` #### Response [#response-1] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMXY63HESK110WT1CHMAFA", "orderId": "01K2PMXY1894RC6E2BYFR00T87", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:38:10.627Z", "executionId": "01K2PMXY63NXM30VNWPDECSFJR", "baseAmount": "15", "executionPrice": "4333.69288", "commissionAmountInRAT": "32.27", "commissions": [ { "assetId": "eur", "amount": "32.27" } ], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.292Z", "executionId": "01K2PMT0VMPCZW0JB2C9J6B405", "baseAmount": "0.141", "executionPrice": "4602.3", "commissionAmountInRAT": "5", "commissions": [ { "assetId": "eur", "amount": "5" } ], "comment": null } ] } ``` ## Closed positions [#closed-positions] ### Get orders for closed positions [#get-orders-for-closed-positions] `POST` `/frontoffice/api/v4/orders/closed-positions` #### Summary [#summary-2] Use this method to retrieve orders associated with closed positions within specified date ranges and market filters. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`createdAtFrom`** `string · date-time | nullable` The start date of the period when the positions were opened. **`createdAtTo`** `string · date-time | nullable` The end date of the period when the positions were opened. **`closedAtFrom`** `string · date-time | nullable` The start date of the period when the positions were closed. **`closedAtTo`** `string · date-time | nullable` The end date of the period when the positions were closed. **`marketId`** `string | nullable` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`marketType`** `string | nullable` The market type. Possible values: * `Cfd` * `Perp` **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastOrderId`** `string | nullable` The identifier of the final order to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/closed-positions HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "createdAtFrom": "2025-08-01T12:00:32.886Z", "createdAtTo": "2025-08-15T12:00:32.886Z" } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier. **`marketFullName`** `string | nullable` The market full name or description (optional). **`marketDisplayName`** `string | nullable` The market ticker. **`marketType`** `string` The market type. Possible values: * `Cfd` * `Perp` **`orderId`** `string` The order identifier. **`orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`timeInForce`** `string` The [time-in-force setting](../get-started/time-in-force) of the order. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`side`** `string` The order side. Possible values: * `Buy` * `Sell` **`positionCloseLotAmount`** `decimal string` The position amount closed by the order, in lots. **`reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`closedAt`** `string · date-time | nullable` The date and time when the position was closed. **`positionId`** `string` The position identifier. **`openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`rateToRAT`** `decimal string` The conversion rate to RAT. **`openedAt`** `string · date-time` The date and time when the position was opened. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "data": [ { "marketId": "cfd.eth_eur", "marketFullName": null, "marketDisplayName": "CFD ETH/EUR", "marketType": "Cfd", "orderId": "01K2PNGX50SR1FRE6P14PJC17E", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "15", "reason": "Trader", "realizedPnlInRAT": "-144.64", "closedAt": "2025-08-15T10:48:32.393Z", "positionId": "01K2PMXY63HESK110WT1CHMAFA", "openPrice": "4333.69288", "closePrice": "3370.58389", "positionPriceInRAT": "50558.75", "rateToRAT": "1", "openedAt": "2025-08-15T10:38:10.628Z", "comment": null }, { "marketId": "perp.eth_usdt", "marketFullName": "ETH/USDT_4s8hKqiPXmXOEhsO1J6W", "marketDisplayName": "ETH/USDT_jC6Im5PxwgZLrwyccRcI", "marketType": "Perpetual", "orderId": "01K2PNG3N6NKAJVV4RV5E2V0HK", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.5", "reason": "Trader", "realizedPnlInRAT": "13.42", "closedAt": "2025-08-15T10:48:06.234Z", "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "openPrice": "4603.1607", "closePrice": "4634.3915", "positionPriceInRAT": "1992.78", "rateToRAT": "0.86", "openedAt": "2025-08-15T10:36:02.293Z", "comment": null } ], "isExceeded": true } ``` ### Get executions for a closing order [#get-executions-for-a-closing-order] `POST` `/frontoffice/api/v5/orders/``{orderId}``/executions/list` #### Summary [#summary-3] Use this method to retrieve execution details for a specific position-closing order using its identifier. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The order identifier. ##### Body [#body-3] **`positionId`** `string | nullable` The position identifier. **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastExecutionId`** `string | nullable` The identifier of the final execution to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/01K2PNG3N6NKAJVV4RV5E2V0HK/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 5 } ``` #### Response [#response-3] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed amount of the base asset. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T19:02:22.196Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true } ], "isExceeded": true } ``` ### Get executions for closing orders [#get-executions-for-closing-orders] `POST` `/frontoffice/api/v5/orders/executions/list` #### Summary [#summary-4] Use this method to retrieve execution details for multiple position-closing orders by providing an array of order identifiers. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`orderId`** `string` The order identifier. **`positionId`** `string` The order identifier. ```http title="Request example" POST /frontoffice/api/v4/orders/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "orderPositionPairs": [ { "orderId": "01K31APDKZCVGWZA3XTF5JPAMD", "positionId": "01K31APDWF2EBHRKHH15VGB1ST" } ], "limit": 0 } ``` #### Response [#response-4] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T18:53:15.657Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true, "comment": null } ], "isExceeded": true } ``` ## Accounts [#accounts] ### Get accounts [#get-accounts] `GET` `/frontoffice/api/v3/accounts` #### Summary [#summary] Use this method to retrieve a list of all trading accounts with their basic information including account type and total balance. #### Request [#request] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/accounts HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response] In case of success, an array of objects will be returned. Each object contains the following information: **`accountId`** `string` The trading account identifier. **`publicAccountId`** `integer` The public account identifier for display purposes. **`accountName`** `string` The account name. **`accountType`** `string` The account type. Possible values: * `Hedging` * `Netting` **`accountStatus`** `string` The account status, which determines the permitted operations. For a description of each value, see [Account statuses](../get-started/account-statuses). Possible values: * `Active` * `Halted` * `Frozen` **`totalBalanceInRAT`** `decimal string` The total balance, in RAT. **`isCopyTradingAccount`** `boolean` Indicates if the account is `Copy`. ```json title="Response example — 200: OK" [ { "accountId": "685a7eaa360f9e7416221a61", "publicAccountId": 1234567, "accountName": "B2TRADER Hedging account", "accountType": "Hedging", "accountStatus": "Active", "totalBalanceInRAT": "6020.12", "isCopyTradingAccount": false }, { "accountId": "6891e70db552ff9c6fbbccf5", "publicAccountId": 1234568, "accountName": "B2TRADER Netting account", "accountType": "Netting", "accountStatus": "Halted", "totalBalanceInRAT": "10987.39", "isCopyTradingAccount": false } ] ``` ## Assets [#assets] ### Get assets [#get-assets] `GET` `/frontoffice/api/v3/assets` #### Summary [#summary-1] Use this method to retrieve a list of available assets on the platform. #### Request [#request-1] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-1] In case of success, an array of objects will be returned. Each object contains the following information: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`isRootAsset`** `boolean` Indicates whether this is a root asset. ```json title="Response example — 200: OK" [ { "assetId": "usdt", "assetName": "Tether", "isRootAsset": true }, { "assetId": "xrp", "assetName": "Ripple", "isRootAsset": false } ] ``` ## Markets [#markets] ### Get markets [#get-markets] `GET` `/frontoffice/api/v6/markets` #### Summary [#summary-2] Use this method to retrieve a list of available markets with their type, subtype, and favorite status. #### Request [#request-2] ##### Query parameters [#query-parameters] **`categoryId`** The market category identifier. **`dynamicCommissionGroupId`** The dynamic commission group identifier. **`isFavorite`** `boolean` Filter by favorite status. If set to `true`, only markets marked as favorites are returned. ```http title="Request example" GET /frontoffice/api/v6/markets?isFavorite=true HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} ``` #### Response [#response-2] In case of success, an array of market objects is returned. Each market object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description. **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" [ { "marketId": "spot.btc_usdt", "displayName": "BTC/USDT", "fullName": null, "type": "Spot", "subtype": null, "isFavorite": true }, { "marketId": "cfd.eth_btc", "displayName": "ETH/BTC", "fullName": "Ethereum to Bitcoin", "type": "Cfd", "subtype": "Crypto", "isFavorite": false }, { "marketId": "perp.trx_usdt", "displayName": "TRX/USDT", "fullName": "TRX to Tether Perpetual", "type": "Perpetual", "subtype": null, "isFavorite": false } ] ``` ### Get market [#get-market] `GET` `/frontoffice/api/v6/markets/``{marketId}` #### Summary [#summary-3] Use this method to retrieve detailed information about a specific market using its market identifier. #### Request [#request-3] ##### Path parameters [#path-parameters] **`marketId`** `required` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```http title="Request example" GET /frontoffice/api/v6/markets/{marketId} HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description (optional). **`baseAssetId`** `string` The base asset identifier. **`quoteAssetId`** `string` The quote asset identifier. **`minAmount`** `decimal string | nullable` *Applicable to Spot markets only.* The minimum tradable amount of the base asset. **`maxBaseAmount`** `decimal string | nullable` The maximum tradable amount of the base asset. **`priceDeviation`** `decimal string` The allowed price deviation for Limit orders placed on the market. Supports decimal values in the range `[0, 1]`, with up to 4 decimal places, for example: * `0.1` = 10% * `0.01` = 1% * `0.001` = 0.1% * `0.0001` = 0.01% If set to `0`, no restriction is applied, the price deviation is ignored. **`priceScale`** `integer` The price precision, which is the number of digits after a decimal separator. Also determines the minimum allowed trade price. Supports only integer values in the range `[2, 8]`. For example, `2` means the following price format: `0.01`, and `8`: `0.00000001`. **`amountScale`** `integer | nullable` *Applicable to Spot markets only.* The amount precision, which is the number of digits after a decimal separator. Also determines the minimum trade amount. Supports only integer values in the range `[0, 8]`. For example: * `0` means `1` (no digits after the decimal separator) * `5` means `0.00001` (five digits after the decimal separator) * `8` means `0.00000001` (eight digits after the decimal separator) **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`swapSettings`** `object | nullable` *Applicable to CFD markets only.* The fee type charged for holding open positions overnight. The amount can be negative for rebates. Possible values: * `FixPerLot`: The fixed amount per lot. * `Percent`: The fixed amount in points which is applied to the position size, in the range `[-1, 1]`, with up to 5 decimal places. * `Points`: The fixed amount of percents which is applied to the position size, with up to 3 decimal places. Structure: * **`type`** `string` — Swap calculation type. Possible values: `FixPerLot`, `Percent`, `Points`. * **`shortPositionSettings`** `object` — Settings for Short positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` * **`longPositionSettings`** `object` — Settings for Long positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` **`lotSize`** `integer | nullable` *Not applicable to Spot markets.* The standardized quantity of the base asset per lot. Supports only integer values in the range `[1, 1000000]`. **`minLotAmount`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum order amount, in lots, that can be placed and executed. Supports values in the range `[0.00000001, 1]`. **`maxLotAmount`** `integer | nullable` *Not applicable to Spot markets.* The maximum order amount, in lots, that can be placed and executed. Supports only integer values in the range `[1, 10000]`. **`tickSize`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum price increment. **`lotStep`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum lot amount increment. Supports values in the range `[0.00000001, 1]`. By default, equals to the `minLotAmount`. **`slippageRate`** `decimal string` The expected slippage, that is, the difference between the expected execution price and the actual one. This value is used as a multiplier to calculate the funds to be put on hold for a market order execution. Supports values in the range `[1, 10]`, including decimal values with up to 4 decimal places. The default value is `1` which means that only the current bid/ask price is put on hold. For example, `1.1` means that the current bid or ask price + 10% is put on hold for each order, to cover the 10% slippage. **Mind that** the total amount funds to be held depends on the order parameters and takes into account many conditions, the slippage rate is only one of them. **`calendar`** `object` The trading calendar defining market trading hours. Structure: * **`timeZoneId`** `string` — IANA time zone identifier. * **`tradingSessions`** `array` — Weekly trading sessions: * **`dayOfWeek`** `string` — One of: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. * **`timeIntervals`** `array` — List of intervals with: * **`start`** `string` (time) — Start time in `calendar.timeZoneId`. * **`end`** `string` (time) — End time in `calendar.timeZoneId`. * **`sessionOverrides`** `array` — Optional specific-date overrides: * **`date`** `string` (date) — In `YYYY-MM-DD` format. * **`timeIntervals`** `array | nullable` — Intervals for that date. **`fundingStartTime`** `string | nullable` *Applicable to Perpetual markets only.* The time of the first funding settlement, in the following format: `HH:MM:SS`. **`fundingIntervalInHours`** `integer | nullable` *Applicable to Perpetual markets only.* The funding settlement interval, in hours. Possible values: 1, 2, 3, 4, 6, 8, 12, 24. **`leverageProfile`** `object` *Not applicable to Spot markets.* The leverage profile. Structure: * **`leverageType`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`leverage`** `object` * **`useOnlyMaxLeverage`** `boolean` * **`maxLeverage`** `integer` — For `Fixed` leverage type only. * **`tiers`** `array` — For `Dynamic` leverage type only. * **`maxLeverage`** `integer` — The maximum allowed leverage for this tier. * **`maxNotionalValueInRAT`** `string | nullable` — The maximum position notional for this tier. **`commissionSettings`** `object` The commission settings. Structure: * **`type`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`charge`** `object` * **`type`** `string` — Possible values: `Percent`, `FixPerLot`. * **`assetId`** `string | nullable` — For `Fixed` commission type only. * **`size`** `decimal string` — For `Fixed` commission type only. * **`tiers`** `array` — For `Dynamic` commission type only. * **`size`** `string` — The commission amount for this tier. * **`minTradingVolumeInRAT`** `string` — The minimum required trading volume for this tier. * **`minCommissionInRAT`** `decimal string | nullable` * **`dynamicCommissionGroupId`** **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" { "marketId": "string", "displayName": "string", "fullName": "string", "baseAssetId": "string", "quoteAssetId": "string", "minAmount": "string", "maxBaseAmount": "string", "minQuoteAmount": "string", "priceDeviation": "string", "priceScale": 0, "amountScale": 0, "type": "Spot", "subtype": "Cash", "swapSettings": { "type": "FixPerLot", "shortPositionSettings": { "size": "string", "assetId": "string" }, "longPositionSettings": { "size": "string", "assetId": "string" } }, "lotSize": 0, "minLotAmount": "string", "maxLotAmount": 0, "tickSize": "string", "lotStep": "string", "slippageRate": "string", "calendar": { "timeZoneId": "string", "tradingSessions": [ { "dayOfWeek": "Monday", "timeIntervals": [ { "start": "string", "end": "string" } ] } ], "sessionOverrides": [ { "date": "2025-12-18", "timeIntervals": [ { "start": "string", "end": "string" } ] } ] }, "fundingStartTime": "string", "fundingIntervalInHours": 0, "leverageProfile": { "leverageType": "Fixed", "leverage": { "useOnlyMaxLeverage": true, "maxLeverage": 0 } }, "commissionSettings": { "type": "Dynamic", "сharge": { "type": "Percent", "tiers": [ { "size": "string", "minTradingVolumeInRAT": "string" }, { "size": "string", "minTradingVolumeInRAT": "string" } ], "minCommissionInRAT": "string" }, "dynamicCommissionGroupId": "string" }, "isFavorite": true } ``` *** ### Add favorite market [#add-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/add` #### Summary [#summary-4] Add a market to the current user's favorites list. #### Request [#request-4] ##### Body [#body] **`marketId`** `string` `required` The market identifier to add to favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/add HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-4] In case of success (`200`), an empty object is returned. *** ### Remove favorite market [#remove-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/delete` #### Summary [#summary-5] Remove a market from the current user's favorites list. #### Request [#request-5] ##### Body [#body-1] **`marketId`** `string` `required` The market identifier to remove from favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/delete HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-5] In case of success (`200`), an empty object is returned. ## Account margin settings [#account-margin-settings] ### Get margin assets [#get-margin-assets] `GET` `/frontoffice/api/v4/account-margin-settings/assets` #### Summary [#summary-6] Use this method to retrieve a list of assets that can be used as collateral for margin trading. #### Request [#request-6] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v4/account-margin-settings/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`assets`** `array` A list of assets that can be used as a collateral for margin trading. Each array item contains: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`total`** `decimal string` The overall amount of the asset, including locked funds. **`marginRatio`** `decimal string` The percentage of the asset value used as a collateral. Supports values in the range `[0, 1]`, where `1` represents 100.00%. **`isSelected`** `boolean` Indicates whether the asset is selected to be used as collateral. Can be `true` only for assets with the `marginRatio` more than `0`. ```json title="Response example — 200: OK" { "assets": [ { "assetId": "btc", "assetName": "btc", "available": "0.031", "total": "0.031", "marginRatio": "1", "isSelected": true }, { "assetId": "eth", "assetName": "eth", "available": "0", "total": "0", "marginRatio": "1", "isSelected": false } ] } ``` ### Select margin asset [#select-margin-asset] `POST` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-7] Use this method to enable a particular asset to be used as collateral for margin trading. Only assets with the `marginRatio` more than `0` can be selected. #### Request [#request-7] ##### Path parameters [#path-parameters-1] **`assetId`** `required` The asset identifier. ```http title="Request example" POST /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json Accept: */* {} ``` #### Response [#response-7] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ### Disable margin asset [#disable-margin-asset] `DELETE` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-8] Use this method to prohibit a specific asset from being used as collateral for margin trading. #### Request [#request-8] ##### Path parameters [#path-parameters-2] **`assetId`** `required` The asset identifier. ```http title="Request example" DELETE /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-8] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ## Info [#info] ### Get server info [#get-server-info] `GET` `/frontoffice/api/v3/info` #### Summary [#summary-9] Use this method to retrieve current server time and timezone information. #### Request [#request-9] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`serverTime`** `string` The server time, in the Unix timestamp format. **`serverTimeZone`** `string` The server time zone. ```json title="Response example — 200: OK" { "serverTime": "1755190380", "serverTimeZone": "+00:00" } ``` ### Get server time zones [#get-server-time-zones] `GET` `/frontoffice/api/v3/info/time-zones` #### Summary [#summary-10] Use this method to retrieve available server time zones. #### Request [#request-10] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info/time-zones HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-10] In case of success, an array of objects will be returned. Each object contains the following information: **`id`** `string` The time zone identifier. **`offset`** `string` The UTC offset, in the following format: `HH:MM:SS`. **`offsetInMinutes`** `integer · int32` The UTC offset in minutes. **`shortLabel`** `string` The short label for the time zone. **`label`** `string` The display label for the time zone. ```json title="Response example — 200: OK" [ { "id": "Africa/Abidjan", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Abidjan", "label": "(UTC+00:00) Côte d’Ivoire Time" }, { "id": "Africa/Algiers", "offset": "01:00:00", "offsetInMinutes": 60, "shortLabel": "Africa/Algiers", "label": "(UTC+01:00) Central European Time (Algiers)" }, { "id": "Africa/Bissau", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Bissau", "label": "(UTC+00:00) Guinea-Bissau Time" }, ... ] ``` ## Webhooks [#webhooks] ### Create webhook API key [#create-webhook-api-key] `POST` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-11] Create a new webhook API key for receiving TradingView alerts. #### Request [#request-11] ##### Header parameters [#header-parameters] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Body [#body-2] **`name`** `string` `required` A descriptive name for the API key, up to 100 characters. ```http title="Request example" POST /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "name": "My TradingView Key" } ``` #### Response [#response-11] In case of success (`201`), the created API key object is returned. **`id`** `string` The unique identifier of the API key. **`apiKey`** `string` The full API key value. The key is shown only once at creation. **`name`** `string` The name assigned to the key. **`userId`** `string` The user identifier the key is bound to. **`status`** `string` The key status: `Active`. **`createdAt`** `string` The timestamp when the key was created. **`expiresAt`** `string` The timestamp when the key expires (one year from creation). ```json title="Response example" { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "apiKey": "wh_key_abc123def456...", "name": "My TradingView Key", "userId": "01JZ3CVZKN20410JPYYH1YZJSK", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ``` The API key is shown only once in the creation response. It can't be retrieved again after this call. *** ### List webhook API keys [#list-webhook-api-keys] `GET` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-12] Retrieve all webhook API keys for the authenticated user along with the webhook URL. #### Request [#request-12] ##### Header parameters [#header-parameters-1] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ```http title="Request example" GET /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-12] In case of success (`200`), the webhook URL and a list of API keys are returned. **`webhookUrl`** `string` The webhook URL to configure in TradingView alerts. **`apiKeys`** `array of objects` The list of API keys. **`apiKeys[].id`** `string` The unique identifier of the API key. **`apiKeys[].name`** `string` The name assigned to the key. **`apiKeys[].status`** `string` The key status. Possible values: * `Active` * `Revoked` * `Expired` **`apiKeys[].createdAt`** `string` The timestamp when the key was created. **`apiKeys[].expiresAt`** `string` The timestamp when the key expires. ```json title="Response example" { "webhookUrl": "https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3...", "apiKeys": [ { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "name": "My TradingView Key", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ] } ``` *** ### Revoke webhook API key [#revoke-webhook-api-key] `DELETE` `/frontoffice/api/v3/webhook/api-keys/{id}` #### Summary [#summary-13] Revoke an active webhook API key. After revocation, the key can no longer be used to authenticate webhook requests. #### Request [#request-13] ##### Header parameters [#header-parameters-2] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Path parameters [#path-parameters-3] **`id`** `string` `required` The unique identifier of the API key to revoke. ```http title="Request example" DELETE /frontoffice/api/v3/webhook/api-keys/01JZ3CVZKN20410JPYYH1YZJSK HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-13] In case of success (`200`), a confirmation object is returned. **`success`** `boolean` Indicates whether the key was revoked successfully. **`message`** `string` A description of the result. ```json title="Response example" { "success": true, "message": "API key revoked successfully" } ``` *** ### Receive TradingView alert [#receive-tradingview-alert] `POST` `/frontoffice/api/v3/webhook/alerts/{userId}` #### Summary [#summary-14] Accept a webhook alert from TradingView and place an order on the specified trading account. TradingView calls this endpoint when an alert triggers. #### Request [#request-14] ##### Path parameters [#path-parameters-4] **`userId`** `string` `required` The B2TRADER user identifier (ULID format). ##### Body [#body-3] **`apiKey`** `string` `required` The webhook API key for authentication. **`accountId`** `string` `required` The trading account identifier. **`symbol`** `string` `required` The market symbol with a type prefix (`spot.`, `cfd.`, or `perp.`) followed by the pair name. For example: `spot.btc_usdt`, `cfd.eur_usd`, `perp.btc_usdt`. **`side`** `string` `required` The order side. Possible values: * `buy` * `sell` **`quantity`** `decimal string` `required` The order quantity in the base asset. **`orderType`** `string` The order type. Default: `market`. Possible values: * `market` * `limit` * `stop` * `stop_limit` **`price`** `decimal string` The limit price. Required for `limit` and `stop_limit` orders. **`stopPrice`** `decimal string` The stop price. Required for `stop` and `stop_limit` orders. **`leverage`** `decimal string` The leverage ratio. Applicable to CFD and Perpetual Futures markets only. **`takeProfit`** `decimal string` The take profit trigger price. **`stopLoss`** `decimal string` The stop loss trigger price. **`timeInForce`** `string` The time-in-force policy. Default: `gtc`. Possible values: * `gtc` * `ioc` * `fok` * `day` **`comment`** `string` A custom comment, up to 256 characters. **`deduplicationId`** `string` A UUID for idempotency. Duplicate requests with the same ID within five minutes return a cached response. ```http title="Request example" POST /frontoffice/api/v3/webhook/alerts/01JZ3CVZKN... HTTP/1.1 Host: {host} Content-Type: application/json { "apiKey": "wh_key_abc123def456...", "accountId": "01JZ3CVZKN20410JPYYH1YZJSK", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01", "comment": "TV Strategy Signal" } ``` #### Response [#response-14] In case of success (`200`), an order confirmation is returned. **`success`** `boolean` Indicates whether the order was placed successfully. **`orderId`** `string` The unique identifier of the created order. **`orderStatus`** `string` The initial status of the order. **`message`** `string` A description of the result. **`timestamp`** `string` The timestamp of the response. ```json title="Response example" { "success": true, "orderId": "01JZ3CVZKN20410JPYYH1YZJSK", "orderStatus": "Working", "message": "Order placed successfully", "timestamp": "2026-02-02T12:34:56.789Z" } ``` #### Rate limits [#rate-limits] Webhook requests are limited to five requests per second per user. If the limit is exceeded, the response returns a `429` status code with the following headers: * `X-RateLimit-Limit`: Maximum requests per window * `X-RateLimit-Remaining`: Remaining requests in the current window * `X-RateLimit-Reset`: Unix timestamp when the window resets ## Orders [#orders] ### Place SPOT order [#place-spot-order] `POST` `/frontoffice/api/v3/orders` #### Summary [#summary] Use this method to create and submit a new order for SPOT markets. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Body [#body] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Limit", "timeInForce": "Gtc", "requestedAmount": 0.02, "requestedPrice": 115193.35, "comment": "Strategy A" } } ``` #### Response [#response] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. Right after the order is created commission is `0`. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K1ZTB4DB0S6Y2NH81S781BQX", "orderType": "Limit", "side": "Buy", "status": "Pending", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.02", "remainingAmount": "0.02", "requestedPrice": "115193.35", "executionPrice": "0", "createdAt": "2025-08-06T13:50:13.931Z", "updatedAt": "2025-08-06T13:50:13.9325008Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Place CFD order [#place-cfd-order] `POST` `/frontoffice/api/cfd/v4/orders` #### Summary [#summary-1] Use this method to create and submit a new order for CFD markets. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "timeInForce": "Gtd", "requestedLotAmount": 1, "requestedPrice": 3280, "leverage": 75, "cancellationDate": "2025-08-10T00:00:00Z", "stopLoss": { "price": 3320, "isTrailing": false }, "takeProfit": { "price": 3200 }, "comment": "Strategy A" } } ``` #### Response [#response-1] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2253Q9X3VTJ68PNWY40JC6Q", "status": "Pending" } } ``` ### Place PF order [#place-pf-order] `POST` `/frontoffice/api/perpetual/v4/orders` #### Summary [#summary-2] Use this method to create and submit a new order for Perpetual markets. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `perp.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "perp.eth_usdt", "side": "Buy", "orderType": "Market", "timeInForce": "Ioc", "requestedLotAmount": 10, "leverage": 159, "comment": "Strategy A" } } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K228VN55N7WFZRG70M24T9J1", "status": "Working" } } ``` ### Cancel order [#cancel-order] `DELETE` `/frontoffice/api/v3/orders/``{orderId}` #### Summary [#summary-3] Use this method to cancel an active order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`orderId`** `required` The order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/orders/01K2PF9XS29WN4JZRHMCTTQYJB HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` * `StopOrder` * `FixApi` * `System` **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.eth_usdt", "marketDisplayName": "SPOT ETH/USDT", "orderId": "01K2PF9XS29WN4JZRHMCTTQYJB", "orderType": "Limit", "side": "Buy", "status": "Cancelled", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.1", "remainingAmount": "0.1", "requestedPrice": "4450", "executionPrice": "0", "createdAt": "2025-08-15T08:59:51.97Z", "updatedAt": "2025-08-15T09:00:06.2791048Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Get SPOT order data [#get-spot-order-data] `POST` `/frontoffice/api/v3/order-data` #### Summary [#summary-4] Use this method to retrieve and validate order data for SPOT market orders before placing. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-3] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.requestedBaseAmount`** `decimal string | nullable` The requested amount in base asset units. **`order.requestedQuoteAmount`** `decimal string | nullable` The requested amount in quote asset units. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. ```http title="Request example" POST /frontoffice/api/v3/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=3.0 Accept: */* { "order": { "marketId": "spot.eth_usdt", "side": "Buy", "orderType": "Limit", "requestedBaseAmount": 0.2, "requestedPrice": 4600 } } ``` #### Response [#response-4] In case of success, an object will be returned. Each object contains the following information: **`baseAmount`** `decimal string` The calculated base asset amount for the order. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmount`** `decimal string` The estimated commission amount to be charged. **`total`** `decimal string` The total quote asset amount, including the estimated commission. ```json title="Response example — 200: OK" { "order": { "baseAmount": "0.2", "quoteAmount": "920", "commissionAmount": "9.2", "total": "929.2" } } ``` ### Get CFD order data [#get-cfd-order-data] `POST` `/frontoffice/api/cfd/v4/order-data` #### Summary [#summary-5] Use this method to retrieve and validate order data for CFD market orders before placing. #### Request [#request-5] ##### Header parameters [#header-parameters-5] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables the Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/cfd/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": 15000, "triggerType": "points" }, "stopLoss": { "triggerSize": "4020", "triggerType": "price", "isTrailing": false }, "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Market", "leverage": 135, "requestedLotAmount": 1 } } ``` #### Response [#response-5] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "34.4613643", "quoteAmount": "4004.345", "commissionAmountInRAT": "0", "marginLevel": "5.3015", "takeProfit": { "price": "3989.345", "rate": "0.0037", "points": 15000, "pnl": "17.42713545" }, "stopLoss": { "price": "4020", "rate": "-0.0039", "points": -15655, "pnl": "-18.18812036" } } } ``` ### Get PF order data [#get-pf-order-data] `POST` `/frontoffice/api/perpetual/v4/order-data` #### Summary [#summary-6] Use this method to retrieve and validate order data for Perpetual market orders before placing. #### Request [#request-6] ##### Header parameters [#header-parameters-6] **`accountId`** `required` The trading account identifier. ##### Body [#body-5] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/perpetual/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": "0.01", "triggerType": "rate" }, "stopLoss": { "triggerSize": "-100", "triggerType": "pnl", "isTrailing": false }, "marketId": "perp.btc_usdt", "side": "Buy", "orderType": "Limit", "leverage": 100, "requestedLotAmount": 0.5, "requestedPrice": 118450 } } ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "592.25", "quoteAmount": "59225", "commissionAmountInRAT": "0", "marginLevel": "0.3582", "takeProfit": { "price": "119634.5", "rate": "0.01", "points": 11845, "pnl": "592.25" }, "stopLoss": { "price": "118250", "rate": "-0.0016", "points": -2000, "pnl": "-100" } } } ``` ## Stop orders [#stop-orders] ### Place SPOT Stop order [#place-spot-stop-order] `POST` `/frontoffice/api/v3/stop-orders` #### Summary [#summary-7] Use this method to create and submit a new Stop order for SPOT markets. #### Request [#request-7] ##### Header parameters [#header-parameters-7] **`accountId`** `required` The trading account identifier. ##### Body [#body-6] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Market", "activationPrice": 128000, "requestedAmount": 0.01, "timeInForce": "Ioc", "comment": "Strategy A" } } ``` #### Response [#response-7] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order, same as in the request. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K2MNC3BVR5WRTBEE9YWAS91K", "orderType": "Market", "side": "Buy", "requestedPrice": "0", "activationPrice": "128000", "requestedAmount": "0.01", "timeInForce": "Ioc", "status": "WaitingForActivation", "createdAt": "2025-08-14T16:07:25.8193038Z", "updatedAt": "2025-08-14T16:07:25.8193044Z", "cancellationDate": null, "comment": null } } ``` ### Place CFD Stop order [#place-cfd-stop-order] `POST` `/frontoffice/api/cfd/v4/stop-orders` #### Summary [#summary-8] Use this method to create and submit a new Stop order for CFD markets. #### Request [#request-8] ##### Header parameters [#header-parameters-8] **`accountId`** `required` The trading account identifier. ##### Body [#body-7] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "activationPrice": 3200, "requestedLotAmount": 0.5, "timeInForce": "Gtd", "leverage": 76, "requestedPrice": 3500, "cancellationDate": "2025-08-18T00:00:00Z", "stopLoss": { "price": "3900", "isTrailing": false }, "takeProfit": { "price": "3100" }, "comment": "Strategy A" } } ``` #### Response [#response-8] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNRWP2J1S8T9TKTCXWYY87", "status": "WaitingForActivation" } } ``` ### Place PF Stop order [#place-pf-stop-order] `POST` `/frontoffice/api/perpetual/v4/stop-orders` #### Summary [#summary-9] Use this method to create and submit a new Stop order for Perpetual markets. #### Request [#request-9] ##### Header parameters [#header-parameters-9] **`accountId`** `required` The trading account identifier. ##### Body [#body-8] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "perp.btc_usdt", "side": "Sell", "orderType": "Market", "activationPrice": 115000, "requestedLotAmount": 1, "timeInForce": "Fok", "leverage": 22, "stopLoss": { "price": "118020", "isTrailing": true }, "takeProfit": { "price": "113873" }, "comment": "Strategy A" } } ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNM0S8B2R9DS7BWJ8PGYPR", "status": "WaitingForActivation" } } ``` ### Cancel Stop order [#cancel-stop-order] `DELETE` `/frontoffice/api/v3/stop-orders/``{orderId}` #### Summary [#summary-10] Use this method to cancel an active Stop order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-10] ##### Header parameters [#header-parameters-10] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The Stop order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/stop-orders/01K2MNGAWPMQJ7WGATFSCAS1G4 HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-10] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. ```json title="Response example — 200: OK" { "order": { "marketId": "perp.btc_usdt", "marketDisplayName": "Perpetual BTC/USDT", "orderId": "01K2MNGAWPMQJ7WGATFSCAS1G4", "orderType": "Limit", "side": "Sell", "requestedPrice": "115100", "activationPrice": "115000", "requestedAmount": "1", "timeInForce": "Gtc", "status": "Rejected", "createdAt": "2025-08-14T16:09:44.5986099Z", "updatedAt": "2025-08-14T16:09:44.5986103Z", "cancellationDate": null } } ``` ## Positions [#positions] ### Close position [#close-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/close` #### Summary [#summary-11] Use this method to close a specific position entirely or partially. #### Request [#request-11] ##### Header parameters [#header-parameters-11] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-2] **`positionId`** `required` The position identifier to close. ##### Body [#body-9] **`closePositionLotAmount`** `decimal string | nullable` The portion of the position to close, in lots. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PFXDP1FWCJSGTX4GJ6JHM0/close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-11] In case of success, an object will be returned. Each object contains the following information: **`positionId`** `string` The position identifier. ```json title="Response example — 200: OK" { "positionId": "01K2PFXDP1FWCJSGTX4GJ6JHM0" } ``` ### Bulk close positions [#bulk-close-positions] `POST` `/frontoffice/api/v4/positions/bulk-close` #### Summary [#summary-12] Use this method to close multiple positions simultaneously based on different criteria such as all positions, positive PnL only, or negative PnL only. #### Request [#request-12] ##### Header parameters [#header-parameters-12] **`accountId`** `required` The trading account identifier. ##### Body [#body-10] **`mode`** `string` `required` The bulk close mode. Possible values: * `AllPositions` — close all positions. * `PositivePnl` — close only positions with positive PnL. * `NegativePnl` — close only positions with negative PnL. ```http title="Request example" POST /frontoffice/api/v4/positions/bulk-close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "mode": "AllPositions" } ``` #### Response [#response-12] In case of success, an object will be returned containing identifiers of closed positions. ```json title="Response example — 200: OK" { "status": "accepted", "positionIds": [ "01K228VNC2Q7E7K9W8GABWBZ5Z", "01K22BZ2DCETJZKW6MK81N1T8Y", "01K2CXF06A3A5SK2YFJT67CMZ5", "01K2CXF2ZJ6MJYMEK663TBBY8K", "01K2PFXDP1FWCJSGTX4GJ6JHM0" ] } ``` ### Get trigger data [#get-trigger-data] `POST` `/frontoffice/api/v4/positions/``{positionId}``/trigger-data` #### Summary [#summary-13] Use this method to retrieve Stop loss and Take profit settings for an open position. #### Request [#request-13] ##### Header parameters [#header-parameters-13] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-3] **`positionId`** `required` The position identifier. ##### Body [#body-11] **`stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`stopLoss.isTrailing`** `boolean | nullable` Indicates if Stop loss is Trailing. **`takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/trigger-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "triggerSize": "-0.01", "triggerType": "rate", "isTrailing": true }, "takeProfit": { "triggerSize": 2500, "triggerType": "points" } } ``` #### Response [#response-13] In case of success, an object will be returned. Each object contains the following information: **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "takeProfit": { "price": "248.27", "rate": "0.1119", "points": 2500, "pnl": "21.5" }, "stopLoss": { "price": "221.04", "rate": "-0.01", "points": -223, "pnl": "-1.91" } } ``` ### Submit triggers [#submit-triggers] `PUT` `/frontoffice/api/v4/positions/``{positionId}``/triggers` #### Summary [#summary-14] Use this method to modify Stop loss and Take profit settings for an open position. #### Request [#request-14] ##### Header parameters [#header-parameters-14] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-4] **`positionId`** `required` The position identifier. ##### Body [#body-12] **`stopLoss.price`** `decimal string` The Stop loss trigger price. **`stopLoss.isTrailing`** `boolean` If `true`, enables the Trailing behavior for Stop loss. **`takeProfit.price`** `decimal string` The Take profit trigger price. ```http title="Request example" PUT /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/triggers HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "price": "165.13", "isTrailing": true }, "takeProfit": { "price": 250 } } ``` #### Response [#response-14] In case of success, an object will be returned containing the identifier of the updated position. ```json title="Response example — 200: OK" { "positionId": "01K2HYXA7N2G9NHTFEWYVM9SEQ" } ``` ## Commissions [#commissions] ### Get account trading volume [#get-account-trading-volume] `GET` `/frontoffice/api/v3/commission/``{dynamicCommissionGroupId}``/account-trading-volume` #### Summary [#summary-15] Use this method to obtain a cumulative account trading volume used for calculating the commission tier. #### Request [#request-15] ##### Header parameters [#header-parameters-15] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-5] **`dynamicCommissionGroupId`** `required` The dynamic commission group identifier. Use [Get market](settings#get-market) to obtain. ```http title="Request example" GET /frontoffice/api/v3/commission/{dynamicCommissionGroupId}/account-trading-volume HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-15] In case of success, an object will be returned containing current trading volume, in RAT, for the account. ```json title="Response example — 200: OK" { "currentTradingVolumeInRAT": "string" } ``` You can connect B2Trader to **ChatGPT** as a **connector**. It uses the same B2Trader MCP URL and OAuth sign-in as every other agent. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in ChatGPT's connector directory. Connector availability depends on your ChatGPT plan. ## Connect the B2Trader connector [#connect-the-b2trader-connector] 1. In ChatGPT, open **Settings** → **Connectors**. 2. Choose to add a connector by **URL** (custom connector). 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Confirm. ChatGPT reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — no API key is pasted into ChatGPT. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. ChatGPT lists the connector as connected, and the B2Trader tools become available to it. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — ChatGPT receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and ChatGPT stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector appears as connected in ChatGPT's settings. * B2Trader tools are available to ChatGPT in your chats. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In ChatGPT, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). You can connect B2Trader to **Claude** in two places: * **claude.ai** (web and desktop app) — add B2Trader as a **custom connector**. * **Claude Desktop** — add B2Trader as an MCP server; the OAuth sign-in completes through Claude's hosted redirect (`https://claude.ai/api/mcp/auth_callback`). Both use the same B2Trader MCP URL and the same OAuth sign-in. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in Claude's connector directory. ## Connect on claude.ai [#connect-on-claudeai] 1. Open **Settings** → **Connectors** in claude.ai. 2. Click **Add custom connector**. 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Click **Add**. Claude reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — you are **not** pasting an API key into Claude. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. Claude shows the connector as **Connected**, and the B2Trader tools appear in the tool list for your conversations. ## Connect in Claude Desktop [#connect-in-claude-desktop] 1. Open **Claude Desktop** → **Settings** → **Connectors**. 2. Add a new MCP server pointing at the B2Trader MCP URL for your surface. 3. Claude Desktop opens your browser for OAuth sign-in and completes the flow through Claude's **hosted** redirect (`https://claude.ai/api/mcp/auth_callback`), a pre-registered redirect URI. 4. Sign in and — for full access — approve the consent screen. 5. The B2Trader tools appear in Claude Desktop once the connector reports **Connected**. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — Claude receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and Claude stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector is listed as **Connected** in Claude's settings. * B2Trader tools (for example `trader_get_accounts`, plus platform market-data and portfolio tools) are available to Claude in your conversations. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In Claude, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). If you are building your own agent (for example with an Agent SDK) or using an MCP client that is not Claude or ChatGPT, you connect to the same two B2Trader endpoints and the same OAuth flow. This page covers the OAuth details a custom client needs. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` `` is the domain you open your B2Trader terminal on, not a separate API address. ## OAuth discovery [#oauth-discovery] Your client needs no B2Trader-specific configuration beyond the MCP URL. B2Trader is an OAuth 2.1 protected resource and advertises everything a compliant client needs: 1. Your client calls the MCP endpoint without a token and receives `401 Unauthorized` with a `WWW-Authenticate: Bearer resource_metadata="…"` header. 2. That header points at the protected-resource metadata (RFC 9728) for the surface you called — each surface has its own document: `https:///.well-known/oauth-protected-resource/mcp-read-only` and `https:///.well-known/oauth-protected-resource/mcp-full-access`. Fetching it returns the resource identifier, the authorization server (your broker's Keycloak realm), and `scopes_supported` — one scope only, matching the surface: `[mcp:read]` for `/mcp-read-only`, `[mcp:trade]` for `/mcp-full-access`. 3. Your client runs the standard OAuth 2.1 **authorization-code flow with PKCE** against that authorization server, requesting the scope for the surface you want. 4. B2Trader validates the token's audience (`bbp-mcp`) and the required scope (`mcp:read` for read-only, `mcp:trade` for full access) before serving any tool. Use a compliant MCP client library — it performs discovery, PKCE, and token refresh for you. You only supply the MCP URL. ## Pre-registered OAuth clients [#pre-registered-oauth-clients] B2Trader ships two pre-registered public OAuth clients. Use the one matching your surface: | Surface | `client_id` | Scope | Consent | | ----------- | ----------------- | ----------- | ---------------------------- | | Read-only | `mcp-read-only` | `mcp:read` | None | | Full access | `mcp-full-access` | `mcp:trade` | Explicit trade-scope consent | Both are **public** clients (no client secret) and require **PKCE (S256)**. A custom client authenticates as one of these `client_id`s and completes the browser sign-in as any other agent does. Depending on how your broker set up your platform, the page that opens is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account — your client behaves the same either way. ## Command-line agents (Codex CLI, Claude Code) [#command-line-agents-codex-cli-claude-code] Command-line MCP clients default to **Dynamic Client Registration (DCR)** — on first connect they try to register a brand-new OAuth client with the authorization server instead of using a fixed `client_id`. The B2Trader Keycloak realm does not permit anonymous DCR, so these tools must be told to use one of the pre-registered `client_id`s above: * **Codex CLI:** ```bash codex mcp add --url --oauth-client-id mcp-full-access codex mcp login ``` Use `mcp-read-only` in place of `mcp-full-access` for the read-only surface. * **Claude Code:** ```bash claude mcp add --transport http --client-id mcp-full-access --callback-port 8080 ``` Without an explicit `client_id`, both tools fall back to anonymous DCR, which the authorization server rejects — the connection fails before you reach the sign-in page. ## Redirect URIs [#redirect-uris] The pre-registered clients accept these redirect URIs: | Redirect URI | Use | | ------------------------------------------------------- | ----------------------------------------------------- | | `https://claude.ai/api/mcp/auth_callback` | Claude (claude.ai) | | `https://chatgpt.com/connector_platform_oauth_redirect` | ChatGPT | | `http://localhost:8080/*` | Claude Code — fixed callback port | | `http://127.0.0.1/*` | Codex CLI and other loopback clients — ephemeral port | If your custom agent runs locally, use one of the loopback redirects above. Most Agent SDKs and MCP client libraries (including Codex CLI) default to an ephemeral-port loopback callback on `127.0.0.1`, matching `http://127.0.0.1/*`, so no configuration change is needed. Claude Code is the exception: it needs a **fixed** callback port to match a registered redirect, so pass `--callback-port 8080` (matching `http://localhost:8080/*`) as shown above. ## Adding a custom redirect URI (broker step) [#adding-a-custom-redirect-uri-broker-step] If your agent runs on a hosted callback URL that is **not** one of the above (for example a server-side agent with its own public redirect), your broker must add that redirect URI to the pre-registered client in Keycloak before sign-in will succeed. A redirect URI that is not registered on the client fails at the sign-in step with an "Invalid redirect URI" error from Keycloak. Send your broker the exact callback URL your agent uses and which surface it needs (read-only or full access). Adding a redirect URI is a broker-side change to the MCP client registration. It requires no product change and is the documented path for onboarding custom, non-marketplace agents. ## Full access [#full-access] If your custom agent uses the full-access surface, the same [full-access safety](full-access-safety) rules apply: no per-action confirmation, irreversible actions, and the prompt-injection risk of an autonomous agent. Read that page before granting `mcp:trade`. The full-access surface (`/mcp-full-access`) lets a connected AI agent trade on your account **directly**. This page explains exactly what that means and how to stay in control. Read it before you approve the full-access consent screen. Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. ## No per-action confirmation [#no-per-action-confirmation] The in-terminal **AI Assistant chat** asks you to confirm each trade before it executes. The full-access MCP surface does **not**. Once connected, the agent can place, cancel, and close orders and set price triggers on its own, as fast as it decides to — there is no confirmation dialog and no "are you sure?" step. ## Actions are irreversible [#actions-are-irreversible] Trades execute against the live market. A filled order, a closed position, or a cancelled order **cannot be undone**. If your agent makes a mistake — or is manipulated into one — the market result stands. ## Prompt-injection risk [#prompt-injection-risk] An autonomous agent acts on the text it reads. If your agent processes untrusted content — a web page, an email, a chat message, a document — that content can contain hidden instructions telling the agent to trade against your interest. This is called **prompt injection**. Because the full-access surface has no confirmation gate, a successful injection can move real money before you notice. To reduce the risk: * Prefer the **read-only** surface unless you specifically need the agent to trade. * Only grant full access to agents and workflows you trust and control. * Be cautious about letting a full-access agent read untrusted external content in the same session it can trade. ## How to stop your agent [#how-to-stop-your-agent] You have two independent controls. Use either — or both. 1. **Stop it in the agent (fastest).** Disconnect or remove the B2Trader connector in your agent (Claude, ChatGPT, or your custom client). The agent immediately stops making new calls. 2. **Revoke the grant in B2Trader.** Open your **account console** (your broker's Keycloak account page) → **Applications**, find the connected MCP application, and **revoke** its access. This removes your consent so the agent cannot obtain a new token. There is no broker-side "kill switch" that instantly voids a token already in the agent's hands. A token the agent already holds stays valid until it expires (see [Access tokens are short-lived](#access-tokens-are-short-lived)). Revoking in the account console stops **new** tokens; disconnecting in the agent stops it using the one it has. Do both to be certain. ## You still get execution notifications [#you-still-get-execution-notifications] Every order the agent places, cancels, or closes fires the **same account notifications** you already receive for terminal activity. Your normal notification channels keep working, so a full-access agent cannot act silently — watch them to see what your agent is doing. ## Access tokens are short-lived [#access-tokens-are-short-lived] The agent's access token has a **short lifetime**. If you revoke consent in the account console, the agent can finish using its current token but cannot get a new one once it expires — so a revoked grant fully lapses within the token's short window, without any forced server-side revocation. ## Choosing read-only instead [#choosing-read-only-instead] If you do not need the agent to trade, connect the **read-only** surface (`/mcp-read-only`) instead. Its tools cannot place or change anything — the trading tools are not part of that surface at all. See [Overview](overview) for the comparison. B2Trader can expose your trading account to external AI agents through the **Model Context Protocol (MCP)** — an open standard that lets AI applications such as Claude and ChatGPT call a defined set of tools on your behalf. Once you connect an agent, it can read your market data and portfolio, and — on the full-access surface — place and manage orders directly. This is different from the **in-terminal AI Assistant chat**, which runs inside the B2Trader terminal and confirms each trade with you before it executes. An external MCP agent runs in *its own* application (Claude, ChatGPT, or your own client) and connects to B2Trader over the internet using your account sign-in. Connecting an AI agent is optional — it's your choice whether to use it. The MCP surfaces are available by default, though your broker can restrict or disable them for your platform. The MCP endpoints live on the same domain you use to open your B2Trader terminal, so wherever these pages show `https:///…`, that means your terminal address — not a separate API address. If a connection URL below doesn't work, contact your broker. ## Two surfaces [#two-surfaces] B2Trader publishes **two** separate MCP endpoints. You choose one when you connect your agent. | | Read-only | Full access | | ------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Endpoint path** | `/mcp-read-only` | `/mcp-full-access` | | **What the agent can do** | View market data, your portfolio, order and position history, and analytics | Everything in read-only **plus** place, cancel, and close orders and set price triggers | | **Tools exposed** | 23 | 39 | | **Trading** | None — mutating tools are not present at all | Full trading, with **no per-action confirmation** | | **OAuth scope** | `mcp:read` | `mcp:trade` | | **Consent screen** | No extra consent | Explicit trade-scope consent (see [Full-access safety](full-access-safety)) | | **Marketplace-listed** | Yes | No — connect by URL | The **read-only** surface is the one listed in AI marketplaces (for example the Claude and ChatGPT connector directories). It is safe to connect broadly: the trading tools are **structurally absent** — the agent cannot see or call them. The **full-access** surface is connected by pasting its URL directly. It grants your agent the ability to trade with no confirmation gate. Read [Full-access safety](full-access-safety) before you connect it. ## Tool categories [#tool-categories] Both surfaces expose the same read tools; the full-access surface adds the mutating ones. | Category | Read-only | Full access | | ------------------------------------------------------------------------------ | --------- | ----------- | | Market data — B2Trader platform prices (tickers, order book, market summaries) | Yes | Yes | | Portfolio & account (balances, margin, open positions) | Yes | Yes | | Order & position history | Yes | Yes | | Analytics & reference data | Yes | Yes | | Place / cancel / close orders (single) | No | Yes | | Bulk order / position actions | No | Yes | | Set & edit price triggers, other account mutations | No | Yes | | **Total tools** | **23** | **39** | The 16 tools that the full-access surface adds are the mutating actions: single trading actions, bulk trading actions, and non-trading account mutations. ## Which surface to choose [#which-surface-to-choose] * **Choose read-only** if you want an agent to analyze markets, summarize your portfolio, or answer questions about your trading history. This is the recommended default and the safest option. * **Choose full access** only if you deliberately want your agent to trade for you without confirming each action, and you understand the risks in [Full-access safety](full-access-safety). ## Prerequisites [#prerequisites] Before connecting any agent you need: * A **B2Trader account** on a platform that offers the MCP surfaces. They are available by default; a broker can restrict or disable them. * Your account must be **active** (`bbp.spot.status = Active`) — the same status required to trade in the terminal. A non-active account can sign in, but its tool calls are rejected by the platform. * An AI application that supports MCP with OAuth — for example [Claude](connect-claude), [ChatGPT](connect-chatgpt), or a [custom agent](connect-custom-agent). ## How connecting works [#how-connecting-works] You never paste an API key or password into your agent. Connection uses **OAuth 2.1 with PKCE**: 1. You add the B2Trader MCP URL to your agent. 2. The agent discovers B2Trader's authorization server automatically — it reads the endpoint's protected-resource metadata at `/.well-known/oauth-protected-resource/mcp-read-only` or `/.well-known/oauth-protected-resource/mcp-full-access`, depending on the surface. 3. Your browser opens the sign-in page for your platform, where you sign in with the credentials you normally use. 4. For the full-access surface, you approve an explicit consent screen describing what the agent may do. 5. The agent receives a short-lived access token and is connected. No long-lived secret is stored in the agent. The sign-in page you see depends on how your broker set up your platform: either the B2Trader sign-in form, or the sign-in page of the portal you normally use to access your account, which opens automatically. If you are already signed in there in the same browser, no sign-in prompt appears. The per-client steps are covered in the connection guides: * [Connect Claude](connect-claude) * [Connect ChatGPT](connect-chatgpt) * [Connect a custom agent](connect-custom-agent) * [Full-access safety](full-access-safety) ## Global interface controls [#global-interface-controls] ### Account selection [#account-selection] The **Account select** is located in the topbar and enables you to switch between your trading accounts. Each account shows its type: `H` (Hedging) or `N` (Netting). Once you switch the account, all the widgets automatically adjust to show relevant information for the selected account. Account select #### Account status [#account-status] An account can have a status that limits what you can do with it. When a status applies, a status indicator is shown on the account, and a banner explains the restriction. Account status is managed by your administrator. The following statuses are visible to you: * **Halted**: A banner reads *Account is locked for trading. Contact your administrator.* The trading controls are disabled, but you can still deposit and withdraw funds, and your balances, positions, and history stay visible. * **Frozen**: A banner reads *Account is frozen. Contact your administrator.* The account is view-only. All controls are disabled, while your balances, positions, and history stay visible. To restore trading on an account that is Halted or Frozen, contact your administrator. Archived accounts don't appear in the account list. ### Instrument selection [#instrument-selection] The **Instrument select** is located in the topbar and enables you to switch between various markets and trading pairs. Once you change the market, all the widgets automatically adjust to show relevant information for the selected instrument. Instrument select #### Favorite markets [#favorite-markets] Mark instruments as favorites for quick access. To add or remove a market from favorites, click the **star icon** next to the market name in the instrument selection list. Favorite markets can be accessed in two ways: * **Favorites tab** in the instrument selection panel — filters the list to show only your favorite markets. * **Favorites dropdown** in the topbar — provides quick access to favorite markets from anywhere in the terminal. ### Settings [#settings] Use this control to access interface and system settings. Refer to [Settings](settings) for details. Settings ### Other controls [#other-controls] * **Introduction tour**: Access the interactive platform walkthrough. Introduction tour * **Alerts**: View new system notifications. Unread alerts * **Analytics**: Open the **Account Analytics** view with the **Equity Curve** chart — your account balance and equity dynamics over time (Margin Balance, Equity, Total Equity, Unrealized PnL, Deposits / Withdrawals) for a selected period and granularity. The data updates hourly. Click **Back to Trading** to return to the terminal. Analytics * **Log out**: Log out of the system to securely terminate the session. After that you’re navigated to the Login page. Log out ## Working with widgets [#working-with-widgets] > For more information about available widgets, refer to the **Widgets** section of this guide. ### Add widgets to your workspace [#add-widgets-to-your-workspace] **To add a new widget**: 1. Click the **Add Widget** button. 2. Browse the available widgets. 3. Click any widget to add it to your workspace. Add Widget **To add widgets to existing panels**: 1. Look for the **+** button next to the tabs in a panel's header. 2. Click it to open the widget catalog. 3. Select a widget to add it as a new tab to that panel. Add widget tabs ### Move and position widgets [#move-and-position-widgets] **To move a widget**: 1. Click and hold the **move handle** in the top-right corner of the panel header. 2. Drag it to desired location on the page. 3. Drop it. Move widgets **To rearrange widget tabs within a panel**: 1. Click and hold any widget tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ### Resize widgets [#resize-widgets] **To resize a widget panel**: * **Single edge**: Hover over any edge until you see the resize cursor, then drag. * **Corner resize**: Drag a corner to adjust both width and height simultaneously. * **Precision**: Use edge dragging for fine-tuned sizing. Resize widgets ### Remove widgets and tabs [#remove-widgets-and-tabs] **To remove a tab**: 1. Click the **×** button in the top-right corner of the widget tab. 2. The tab will be removed immediately. 3. When you remove the last tab from a panel, the entire panel disappears. Remove tabs and widget panels ### Link panels to a group [#link-panels-to-a-group] Each panel header has a **Link to group** button — the circle icon **next to the move handle** in the top-right corner. Linking panels to the same colored group keeps them in sync: when you select an instrument in one linked panel, the other panels in the same group switch to it automatically. **To link a panel to a group**: 1. Click the **Link to group** button (next to the move handle) in the panel's top-right corner. 2. Select one of the color groups (Group 1–5). 3. Repeat for other panels, choosing the same group to keep them synchronized. Link to group ### Customize widget content [#customize-widget-content] Certain widgets let you customize which columns to display and their order: Look for the **column settings** button in the widget header. **To customize columns**: 1. Click the **column settings** button. 2. **Show/hide columns**: Check or uncheck boxes (grayed-out columns are required). 3. **Reorder columns**: Drag and drop items in the list. 4. **Reset**: Click *Reset to default* to restore original settings. Configure columns ## Managing workspaces [#managing-workspaces] ### Create new workspaces [#create-new-workspaces] **To create a workspace**: 1. Click the **+** tab next to your existing workspaces. 2. Choose a template: * **Pre-built templates**: Start with common widget combinations. * **Empty**: Build completely from scratch. 3. Enter a name for your workspace. 4. Start customizing. Add a new workspace ### Workspace management [#workspace-management] **To rename or delete a workspace**: 1. Click the menu icon on the workspace tab. 2. Select **Rename** or **Remove**. Workspace menu **To reorder workspaces**: 1. Click and hold any workspace tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ## Market info panel [#market-info-panel] Click the **info icon** next to a market symbol in widgets to view: * Detailed market information. * Trading session schedules. * Leverage details (for CFD and PF markets). * Fee details. * Funding details (for PF markets). Market info ## Pro tips [#pro-tips] ### Efficient layout building [#efficient-layout-building] * Start with a template that is close to your needs, then customize. * Group related widgets in tabs to save screen space. * Use larger panels for charts, smaller ones for order books. ### Layout best practices [#layout-best-practices] * **Save multiple workspaces** for different trading strategies. * **Test your layout** during low-activity periods. * **Keep essential widgets visible** (account info, positions, alerts). Access settings by clicking the **gear icon** in the topbar of the Trading terminal. Settings Settings are organized into tabs: * [Interface](#interface): Configure language, time display, and visual theme. * [Widgets](#widgets): Customize widget display options. * [Action Confirmation](#action-confirmation): Choose which actions require additional confirmation. * [Account margin](#account-margin): Manage collateral assets for margin trading. * [Trading report](#trading-report): Generate comprehensive trading and account reports. * [API token management](#api-token-management): Generate and manage tokens for accessing the Trading API. * [TradingView Webhooks](#tradingview-webhooks): Configure TradingView webhook alerts for automated order execution. ## Interface [#interface] Configure global interface preferences: **Language** Select the interface language from the dropdown menu. **24 hour mode** * Enable: Display time in 24-hour format. * Disable: Display time in 12-hour format with AM/PM. **Dark theme** * Enable: Apply dark color scheme. * Disable: Apply light color scheme. ## Widgets [#widgets] Configure display options for the following widgets. ### Price chart [#price-chart] **Display positions** When enabled, open positions are shown on the chart along with: * Position size and current PnL. * Quick access to edit price triggers and close positions. * Color coding: Long positions (green), Short positions (red). **Display orders and triggers** When enabled, the following orders and triggers are displayed on the chart: * Active Limit and Stop orders with order type, price, and amount. * Stop loss, Take profit, and Trailing stop triggers. * Quick access to edit triggers and cancel orders. * Color coding: Buy orders (green), Sell orders (red). **Display executed orders** When enabled, executed orders are shown on the chart with order type indicators: * Green `B` tag for Buy orders. * Red `S` tag for Sell orders. Clicking `B` or `S` will open details of one or more orders that were executed during the candle interval. **Market quick trade panel** When enabled, a panel is displayed on the chart for placing Market orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. **Limit quick trade panel** When enabled, a panel is displayed on the chart for placing Limit orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. ## Action Confirmation [#action-confirmation] Choose which trading actions require an additional confirmation dialog before execution. **Cancel orders** * Enable: A confirmation dialog is displayed before canceling orders. * Disable: Orders are canceled immediately without confirmation. This setting applies to single and bulk order cancellations from the **Open Orders** widget and the **Price chart**. The confirmation dialog includes a **"Don't ask again"** checkbox. To skip the confirmation for future order cancellations, check this box. **Full Close Positions** * Enable: A confirmation dialog is displayed before closing positions. * Disable: Positions are closed immediately without confirmation. This setting applies to single and bulk position closures from the **Open Positions** widget. **Limit order cross-TOB warning** * Enable: A confirmation dialog is displayed before a Limit order is submitted if its price crosses the current top-of-book — that is, when a Buy price is at or above the best ask, or a Sell price is at or below the best bid. The dialog shows the entered price and the current best bid/ask, and includes a **Do not show this warning again** checkbox. * Disable: Crossing Limit orders are submitted immediately without the warning. The warning is enabled by default. The dialog checkbox and this toggle share the same global setting and stay in sync. The warning is informational only — it does not block the order. If you confirm, the order is submitted with the original price. The warning applies only to standard Limit orders; Stop-limit, Take-profit-limit, IOC, FOK, and other order types are not affected. If best bid or best ask data is unavailable (empty book or disconnected feed), the order is submitted without the warning. ## Account margin [#account-margin] Control which assets can be used as collateral for margin trading. ### Asset list [#asset-list] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance available for trading, calculated as *Total – Halted*, where *Halted* represents funds locked for pending Limit orders. *** **Total** The complete asset balance including locked funds. *** **Margin ratio** The percentage of asset value that can be used as collateral for margin trading. *** **Use as margin** Enable this toggle to use the asset as collateral for margin trading. Configure which assets can be used as collateral for margin trading by toggling the **Use as margin** setting for each asset. Only assets with **Margin ratio** greater than 0 (zero) can be enabled. The platform root asset is enabled by default and can't be disabled. ### Filtering options [#filtering-options] Click the **funnel icon** to configure the asset list display: * **Show/Hide zero balances**: Control visibility of assets with zero balance. By default, hidden. * **Show/Hide assets unused as margin**: Control visibility of assets with disabled margin usage. * **Show/Hide assets with zero margin ratio**: Control visibility of assets that can't be used as collateral. By default, hidden. ## Trading report [#trading-report] Generate comprehensive reports containing: * **Trade history** * Closed positions * Executed orders * Individual trades * **Transfers history** * All account transfers * **Account statistics** * Total balance * Realized PnL * Position swaps * Position funding * Commissions To generate a report: 1. Select a custom period of time (UTC time), or generate a report for your entire account history using the **All data** range. The following timeframe presets have been implemented for your convenience: * **Today** * **Current**: week, month, quarter * **Previous**: week, month, quarter * **All data**. 2. Click **Download**. Once generated, the report will be automatically downloaded to your computer as a zipped CSV file. ## API token management [#api-token-management] Generate tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/): * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time To generate a token: 1. Click **+ Create new**. 2. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 3. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ## TradingView Webhooks [#tradingview-webhooks] Use TradingView Webhooks to automatically execute orders on your trading account based on alerts from TradingView. When a TradingView alert triggers, it sends a webhook request to B2TRADER, which places an order according to the parameters specified in the alert message. This feature supports all market types: Spot, CFD, and Perpetual Futures. ### Set up the webhook [#set-up-the-webhook] #### Step 1: Create a webhook API key [#step-1-create-a-webhook-api-key] To create a webhook API key in the Trading terminal: 1. Click the **gear icon** in the topbar to open Settings. 2. Navigate to the **TradingView Webhooks** tab. 3. Click **+ Create new**. 4. In the popup, fill in a **Name** for the key. 5. Click **Create**. The popup displays the generated API key and the webhook URL. Copy both values and store them securely. The API key is shown only once at creation. It can't be retrieved after closing the popup. The following limits apply: * Maximum 10 active keys per user * Each key is valid for 1 year from creation * Keys can be revoked at any time #### Step 2: Configure the alert in TradingView [#step-2-configure-the-alert-in-tradingview] 1. In TradingView, create a new alert or edit an existing one. 2. In the **Notifications** section, enable **Webhook URL**. 3. Paste the webhook URL copied from the terminal. 4. In the **Message** field, enter the alert body in JSON format (see [Alert message format](#alert-message-format)). 5. Save the alert. When the alert triggers, TradingView sends the message to B2TRADER, and the order is placed automatically. ### Alert message format [#alert-message-format] The alert message is a JSON object with the following fields: | Field | Required | Description | | ----------------- | ----------- | -------------------------------------------------------------------------- | | `apiKey` | Yes | Webhook API key generated in the terminal | | `accountId` | Yes | Trading account ID | | `symbol` | Yes | Market symbol with type prefix (see [Symbol format](#symbol-format)) | | `side` | Yes | Order side: `buy` or `sell` | | `quantity` | Yes | Order quantity in base asset | | `orderType` | No | `market` (default), `limit`, `stop`, or `stop_limit` | | `price` | Conditional | Limit price. Required for `limit` and `stop_limit` orders | | `stopPrice` | Conditional | Stop price. Required for `stop` and `stop_limit` orders | | `leverage` | No | Leverage ratio. Applicable to CFD and Perpetual Futures markets only | | `takeProfit` | No | Take profit trigger price | | `stopLoss` | No | Stop loss trigger price | | `timeInForce` | No | `gtc` (default), `ioc`, `fok`, or `day` | | `comment` | No | Custom comment, up to 256 characters | | `deduplicationId` | No | UUID for idempotency. Duplicates within 5 minutes return a cached response | #### Symbol format [#symbol-format] The symbol must include a market type prefix: | Market type | Prefix | Example | | ----------------- | ------- | --------------- | | Spot | `spot.` | `spot.btc_usdt` | | CFD | `cfd.` | `cfd.eur_usd` | | Perpetual Futures | `perp.` | `perp.btc_usdt` | #### Examples [#examples] **Market buy order (Spot):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01" } ``` **Limit sell order with TP/SL (CFD):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "cfd.eur_usd", "side": "sell", "orderType": "limit", "price": "1.0900", "quantity": "1000", "leverage": "10", "takeProfit": "1.0800", "stopLoss": "1.0950", "timeInForce": "gtc" } ``` ### Manage webhook API keys [#manage-webhook-api-keys] To view or manage your webhook API keys, navigate to **Settings** > **TradingView Webhooks**. The following information is provided about each key: | Column | Description | | ----------- | ----------------------------------------------- | | **Name** | The name assigned to the key at creation | | **Status** | Current key status: Active, Revoked, or Expired | | **Created** | The date and time the key was generated | | **Expires** | The date and time the key expires | To revoke a key, click the **Revoke** button next to the key entry. ### Rate limits [#rate-limits] Webhook requests are limited to 5 requests per second per user. If this limit is exceeded, the request returns a `429` error code and the order isn't placed. ### Troubleshooting [#troubleshooting] The following table describes common error scenarios and their solutions: | Issue | Cause | Solution | | -------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | | `Invalid API key` | The API key is incorrect or wasn't copied in full | Generate a new key and update the TradingView alert | | `API key expired` | The key has passed its 1-year validity period | Generate a new key | | `API key revoked` | The key was manually revoked | Generate a new key | | `Invalid symbol format` | The symbol is missing a market type prefix | Add the prefix: `spot.`, `cfd.`, or `perp.` | | `Price required for limit order` | A `limit` or `stop_limit` order is missing the `price` field | Add the `price` field to the alert message | | `Rate limit exceeded` | More than 5 requests were sent within 1 second | Reduce the alert frequency in TradingView | | `Account not found` | The `accountId` doesn't exist or isn't accessible | Verify the account ID in the terminal | A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to limit and stop limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to limit and stop limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the BP, without taking into account the time settings of the devices from which the BP is accessed. ## iOS v1.35 [#ios-v135] This version includes: * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. Select a time period and granularity level to filter performance data, and switch between accounts using the built-in account selector. * **AI Assistant** A new **AI Assistant** widget provides AI-powered market analysis for each instrument, including trade recommendations, market sentiment, signal drivers, suggested actions, and key metrics. * **Quick order from the chart** You can now place orders directly from the **Price chart** by tapping a price pin. The **Quick Order** panel opens pre-filled at the selected price level for faster order placement. * **Customizable workspace** You can now reorder and show or hide bottom tabs in **Settings**, allowing you to tailor the terminal layout to your trading preferences. * **Adaptive interface by market type** Tabs, **Margin Level**, and perpetual funding indicators are now automatically hidden for accounts that do not have access to the corresponding market types, providing a cleaner and more focused interface. * **Landscape mode for the chart** Tapping the **Expand** button on the **Price chart** now automatically rotates the chart to landscape mode for a wider view. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.34 [#ios-v134] This version includes: * **Drag Take Profit and Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be adjusted by dragging their lines directly on the **Price chart**. Changes are applied to the order immediately, with automatic rollback if an error occurs. * **Demo accounts** Demo trading accounts are now supported, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets appear as chips in the market list and are indicated with an icon in the terminal. * **Credit in margin details** A dedicated **Credit** row has been added to the margin details section, providing visibility into credit amounts allocated to your trading account. * **Comments for orders, positions, and trades** You can now add a comment when placing an order or managing a position. The comment is visible throughout the trading lifecycle — on open orders, open positions, and in trade history. * **Margin Level display** When **Margin Level** data is unavailable, the field now displays "–" instead of 0% for clearer data visibility. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.33 [#ios-v133] This version includes: * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Hide zero balances settings relocated** The **Hide zero balances** toggle has been moved to the **Assets** tab for more intuitive access. * **Improved backend error messages** Backend error messages are now mapped to user-friendly descriptions, providing clearer feedback when issues occur. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.32 [#ios-v132] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Quick cancel button for open orders** The **Open orders** widget now features a quick **Cancel** button on each order card, enabling faster order cancellation directly from the list view. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Redesigned account selection header** The account selection section in the terminal header has been redesigned for improved navigation and a cleaner appearance. * **Updated closed positions design** The **Closed positions** widget has been updated with a refreshed layout for better readability and consistency with other trading widgets. * **Confirmation bottom sheet** Order and position actions now display a confirmation bottom sheet, helping to prevent accidental trades and providing a clearer review step before execution. * **Settings button relocated** The **Settings** button has been moved from the **Price chart** widget to the terminal header for easier access across all views. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.31 [#ios-v131] This version includes: Experience an advanced trading workflow with the introduction of our new **tiered leverage system**, offering dynamic leverage based on position size and enhanced margin visibility. This update also brings improved commission transparency with a dedicated Fees tab, enhanced market info, a new deposit shortcut, and updated screens for tiered commissions. We've also refined formatters to respect your selected app language for a more consistent experience. *** ## iOS v1.30 [#ios-v130] This version includes: * **Notifications widget** A new **Notifications** widget has been implemented providing quick access to system notifications related to price changes, Margin calls, Stop outs, Take profit and Stop loss triggers. * **Closing open positions from the Price chart** Open positions can now be closed directly on the **Price chart** screen ensuring quick reaction to volatile market conditions and efficient trade management. This feature is available if the **Display positions** setting is activated for the Price chart. * **Closing all open positions** The **Open positions** tab now features the **Close all** button that liquidates all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Canceling all active orders** The **Open orders** tab now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * **Trading session status** The **Trading session status** in the **Position details** is now accompanied by an info icon and an explanatory tooltip. * **Automatic horizontal scrolling for tabs** The horizontal auto scroll has been added to tabs. Active tabs are now automatically centered for optimal visibility and better accessibility to all available tabs. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.29 [#ios-v129] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding**/**Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Updated account creation process** When creating a trading account in the app, the **account type** can now be selected: **Hedging** or **Netting**, enabling traders to plan and adjust their trading strategies to maximize profit or reduce risk. Depending on the platform settings, the option may be prefilled or require manual selection. The account type can’t be changed after the account is created. * **Support for Take Profit, Stop Loss, and Trailing Stop** The **Take Profit**, **Stop Loss**, and **Trailing Stop** triggers are now supported in the app for CFD and PF trading. They can be applied to Market, Limit, and Stop orders, as well as to currently open positions. * **Support for price alerts** Price alerts are now fully supported in the app: * Multiple alerts can be added to monitor different price levels for any instrument. * Configure alerts based on a fixed price or a percentage change. * View a list of all configured alerts for each instrument. * Adjust or delete existing alerts as needed. * Triggered alerts are automatically removed to keep the list up to date. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order history widget. * **Admin-managed orders and positions** On the **Open positions**, **Closed positions**, and **Order history** widgets, if BP Admins have managed positions or orders, this is now indicated in the **Reason** field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, mitigate risks, or resolve outstanding positions before account termination. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.28 [#ios-v128] This version includes: * **Performance upgrade** Streamlined top-of-the-book ask and bid prices in the Place Order widget are now received through a dedicated socket for faster obtaining and display. * **Mobile and Web Consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** Placeholders are now displayed for empty fields and widgets for improved UX clarity. * **Internal improvements** Enhanced system logs for better diagnostics. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## Android v2.12.0 [#android-v2120] This version includes: * **AI Assistant** A new **AI Assistant** provides AI-powered market analysis for each market, including trade recommendations, a 12-month price forecast, market sentiment, signal drivers, suggested actions, and key metrics. * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. * **Account status indicators** Account statuses such as **Halted** and **Frozen** are now shown with badges and a warning banner, and the related trading actions are restricted accordingly. * **Quick order from the chart** You can now place orders directly from the **Price chart**, enabling faster reaction to market movements. * **Take Profit / Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be set by dragging their lines directly on the **Price chart**, with support for trailing Stop Loss. * **Cross-price limit order warning** A warning is now displayed before you place a **Limit** order whose price crosses the top of the **Order book**. This warning can be enabled or disabled in **Settings**. * **Customizable trading terminal** You can now customize the trading terminal layout and tab order from the new **Workspace** settings. * **Adaptive interface by market type** Margin- and perpetual-related tabs and indicators are now hidden for accounts with access to **Spot** markets only, providing a cleaner interface tailored to the account type. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.11.0 [#android-v2110] This version includes: * **Comment field in Place Order** An optional **Comment** field has been added to the **Place order** form in **Advanced Mode**. The field supports up to 100 characters and is available for all order types across Spot, CFD, and Perpetual markets. * **Full-screen chart mode** The **Price chart** widget now supports full-screen mode. Tap the **Expand** button to switch to a landscape view for a more detailed chart analysis. * **Credit information in margin details** A **Credit** row has been added to the margin section, providing visibility into credit amounts allocated to trading accounts. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.10.0 [#android-v2100] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Demo accounts** Demo trading accounts are now supported in the app, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets are synchronized between the web and mobile terminals. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Improved market status display** The **Market Closed** label is now automatically removed once live data starts updating, providing a more accurate representation of market availability. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.9.0 [#android-v290] This version includes: This update introduces the new **tiered leverage system**, enhanced fee transparency and fully redesigned Fees tab, quick Deposit/Trade shortcuts on account cards for faster navigation and various UI improvements across the app. *** ## Android v2.8.0 [#android-v280] This version includes: * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.7.0 [#android-v270] This version includes: * **Key position parameters on the TP/SL editing** Key position parameters, such as **Name**, **Side**, **Amount**, **Open price**, **Current price**, and **Leverage** are displayed at the top of the Take Profit/Stop Loss configuration screen to give you immediate, accurate context and reduce input errors. Values are updated in real time. * **Closing positions on the Price chart** You can now close positions directly on the **Price chart** widget, by tapping a position indicator. * **Canceling all active orders** The **Open orders** widget now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Closing all open positions** The **Open positions** widget now features the **Close all** button allowing to liquidate all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Closed position details** The **Order type** and **Time in force** values are now displayed for every closed position to improve trade execution transparency. * **Price chart settings saved** The **Price chart** widget now remembers your preferred timeframe and chart type settings. Each time you open the terminal, it displays the chart with your last selected settings. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.6.0 [#android-v260] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding/Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order History widget. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * Expanded capabilities for account administration and risk management for Brokers have been added. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.5.0 [#android-v250] This version includes: * **Stop Loss and Take Profit on the Price chart widget** * Introduction of Stop-Loss (SL) and Take-Profit (TP) lines on the Price chart for enhanced trading insights. * TP and SL are displayed as color-coded lines with only abbreviations visible. * Tap to view prices on the Y-axis and access deletion options. * **Full support for price alerts in the app** * Alerts can be set for specific price levels. * Alerts can be configured based on either a set price or a percentage change. * A list of configured alerts is available for each instrument. * Options to delete or adjust alerts are provided. * Triggered alerts are automatically removed from the list. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.4.0 [#android-v240] This version includes: * **New mobile features** * Introduction of Take Profit, Stop Loss, and Trailing Stop functionalities in the Mobile app. * Support for Netting accounts in the Mobile app. * **Mobile and Web consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** For order lists, the All/Spot/CFD filter is only displayed when there are both Spot and CFD orders, for improved UX clarity. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## June 10, 2026 [#june-10-2026] ### New features [#new-features] #### Guest mode [#guest-mode] A new **Guest mode** lets you explore the Trading terminal without signing in. As a guest you can browse markets and market categories, follow live price streams and interactive charts, and open the **AI Assistant** widget for market analysis. A dedicated guest workspace is provided, and the [Place order](../widgets/place-order) panel opens in the advanced view by default. A **Sign in** action is always available so you can switch to a full trading session at any time. ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Full account history in Trading reports [#full-account-history-in-trading-reports] You can now generate [Trading reports](../get-started/settings) for your entire account history. The previous **92-day** limit has been removed, and a new **All data** range has been added to the report period selector alongside the existing presets. #### Stop orders during closed market sessions [#stop-orders-during-closed-market-sessions] You can now place **Stop** orders while a market is closed according to its trading schedule. The order is accepted and activates automatically once the market reopens, instead of being rejected at placement. #### More accurate unrealized PnL [#more-accurate-unrealized-pnl] Unrealized PnL is now calculated using the correct order book side for each position direction, improving the accuracy of the PnL shown across your widgets. #### Limit price crossing warning [#limit-price-crossing-warning] When you place a limit order at a price that crosses the current top of book, the terminal now shows a warning, helping you avoid an unintended immediate execution. ## April 9, 2026 [#april-9-2026] ### New features [#new-features-1] #### Trading credit [#trading-credit] Your broker can now grant you **trading credit** — a promotional bonus balance you can use for trading. Credit appears as a separate **Credit Balance** alongside your own funds and becomes available for placing trades immediately upon issuance. You are notified when credit is granted or revoked. Trading credit is a trading-only bonus and cannot be withdrawn as cash, so it is excluded from your withdrawable balance. *** ### Improvements [#improvements-1] #### Fee-aware 100% allocation [#fee-aware-100-allocation] The **100%** button in the [Place order](../widgets/place-order) widget now accounts for commissions and margin requirements when allocating funds, so the calculated amount reflects what is actually available for the trade. #### Faster price updates [#faster-price-updates] The price update frequency in terminal widgets has been increased, providing more responsive market data across your workspace. ## March 18, 2026 [#march-18-2026] ### New features [#new-features-2] #### Webhook API for TradingView alerts [#webhook-api-for-tradingview-alerts] A new **Webhook API** has been added, enabling you to connect **TradingView** alerts to your trading workflow. You can generate and copy authentication tokens directly from the Trading terminal to configure webhook-based alerts in **TradingView**. *** ### Resolved issues [#resolved-issues] There have been no customer-facing issues reported in this release. ## March 3, 2026 [#march-3-2026] ### New features [#new-features-3] #### Long-term trading data history [#long-term-trading-data-history] The three-month limit on trading data history has been removed. You can now access the full history of your orders, positions, and trades without time restrictions, enabling deeper analysis of past trading activity. #### AI Assistant widget [#ai-assistant-widget] A new **AI Assistant** widget is now available in the Trading terminal. The widget provides AI-powered market analysis for the selected instrument, including: * A recommendation gauge displaying a score from **Strong Sell** to **Strong Buy** * A 12-month price forecast with target price and percentage change * A market sentiment bar showing the bullish/bearish ratio * Signal drivers section with technical, on-chain, and sentiment factors * Suggested trading actions and key market metrics The widget can be added to any workspace like other terminal widgets. *** ### Improvements [#improvements-2] #### Updated order cancellation confirmation [#updated-order-cancellation-confirmation] The order cancellation confirmation dialog now includes a **Don't ask again** checkbox when canceling triggers from the **TradingView** chart. This allows you to skip the confirmation step for future trigger cancellations, streamlining the trading workflow. *** ### Resolved issues [#resolved-issues-1] There have been no customer-facing issues reported in this release. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-4] #### Redesigned Market Depth widget [#redesigned-market-depth-widget] The [Market Depth](../widgets/market-depth) widget has been completely redesigned with an updated visual layout. Bid and ask labels are now displayed when hovering over a price level, providing better visibility into the order book at a glance. #### Redesigned widget adding experience [#redesigned-widget-adding-experience] The process of adding widgets to workspaces has been redesigned with a more intuitive and streamlined flow. The new interface makes it easier to customize your trading workspace layout by providing a clearer visual selection of available widgets. #### Order and position comments [#order-and-position-comments] A new **Comment** field has been added to orders, positions, and trades throughout the Trading terminal. You can now attach notes directly to your trading activities, making it easier to annotate trading decisions and keep records of your reasoning. #### Favorites [#favorites] You can now mark instruments as favorites for quick access across the Trading terminal. The [Favorite markets](../get-started/customizing-your-terminal#favorite-markets) feature integrates with the instrument selection panel, making it faster to locate and trade your preferred instruments. #### Multi-language support [#multi-language-support] The Trading terminal now supports additional languages: **Chinese (Simplified)**, **Spanish**, **Portuguese**, **French**, **Turkish**, and **Farsi**. Existing translations have also been updated to reflect the latest interface changes. *** ### Improvements [#improvements-3] #### Updated order calculations [#updated-order-calculations] The **Value** and **Amount** calculation logic has been improved for more accurate order handling: * For **Stop Market** orders, the estimated values are now calculated using updated formulas that align with the actual execution logic. * For **Spot** market orders, the **Slippage Rate** is now correctly applied only to buy orders and has been removed from sell order calculations. * The **Slippage Rate** attribute has been removed from **CFD** and **PF** market forms and information displays, as it is not applicable to these market types. #### Improved TP/SL trigger management [#improved-tpsl-trigger-management] Removing Take Profit and Stop Loss triggers is now easier in the TradingView charting widget. Instead of opening a dialog and unchecking the trigger, you can now click the close button directly on the trigger to remove it immediately. #### Updated default columns [#updated-default-columns] The default columns displayed in the [Open positions](../widgets/open-positions) and [Open orders](../widgets/open-orders) widgets have been updated to show the most relevant information by default, reducing the need for manual customization. #### Account margin value formatting [#account-margin-value-formatting] Account margin values such as **Balance**, **Equity**, **Margin**, and **Free margin** in the [Margin](../widgets/margin) widget are now formatted according to the **Root Asset Scale**. This ensures that numerical precision matches the asset's defined scale, eliminating misleading decimal places. #### Updated Settings experience [#updated-settings-experience] The [Settings](../get-started/settings) experience has been improved: * The **Action Confirmation** section text has been rewritten for clarity. The description now reads: "Choose which actions will require additional confirmation," making the toggle behavior immediately clear. * The **One-click trading** configuration has been updated with improved toggle controls and clearer options for enabling or disabling confirmation dialogs on trading actions. #### Improved order validation [#improved-order-validation] Order validation logic has been updated across the Trading terminal, providing clearer feedback on invalid inputs and reducing errors during order placement and management. #### Workspace tab styling [#workspace-tab-styling] Visual improvements have been applied to workspace tabs: gaps have been added between tabs for better visual separation, tab padding has been corrected, and hovered tabs now display a proper card-style fill matching the updated design system. ## December 19, 2025 [#december-19-2025] ### New features [#new-features-5] #### Volume-based tiered commissions [#volume-based-tiered-commissions] You can now benefit from **volume-based commission tiers** that automatically reduce your trading fees as your monthly volume grows. **Key points**: * **Trade more, pay less**: For markets with tiered fees, your 30‑day trading volume (in the root asset, for example USD) is tracked across all markets included in the same group. As you move into higher tiers, your commission percentage decreases. * **Clear fee overview**: Open [Market info](../get-started/customizing-your-terminal#market-info-panel) and switch to the **Fees** tab to see your **Current volume** for the month, the configured **Min. fee**, and the full **Commission tiers** table with volume ranges and fee %. A check mark highlights the tier you are currently in. * **Grouped volume**: Your traded volume is aggregated across markets to which the dynamic commission is applied. * **No surprises**: Orders on markets without tiered fees continue to use the existing flat commission model. Tiered markets simply adjust your fee according to the tier that matches your current trading volume. #### New settings [#new-settings] The [Settings](../get-started/settings) menu has been enriched with the following configuration options: * **Widgets**: This updated section now provides access to multiple widgets’ display settings. Along with existing [Price chart](../widgets/price-chart), you can now configure: * One-click trading for [Open positions](../widgets/open-positions): When enabled, single and bulk position closing are executed immediately, without going through additional confirmation dialogs. * One-click trading for [Open orders](../widgets/open-orders): When enabled, single and bulk order cancellations are executed immediately, without going through additional confirmation dialogs. * **API token management**: This new section allows you to generate and manage tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/). Up to 10 tokens can be generated per account. The validity period for each token is one year. The tokens can be revoked or deleted anytime. *** ### Improvements [#improvements-4] #### Responsive widget layout [#responsive-widget-layout] Widget content now adapts dynamically to the available space, ensuring that key information such as primary values, titles, and critical actions remains visible even when widgets are resized or minimized. Layouts have been refined to avoid unnecessary empty areas while preventing clipping of important elements, delivering a more readable and informative experience across all widget sizes. #### Clearer margin level display [#clearer-margin-level-display] The [Margin](../widgets/margin) widget has been updated to provide a clearer signal. Now, whenever no margin is used (for example, when you have no open positions), the **used margin** value displays **–** instead of 0%. This aligns with common brokerage practices and helps you better understand the current risk state at a glance. #### Smarter default filters for Assets and Account margin [#smarter-default-filters-for-assets-and-account-margin] Certain default filters are now applied automatically when the Trading terminal is opened for the first time. In the [Assets](../widgets/assets) widget, **Hide zero balances** is enabled by default, so assets with zero balance are not shown. In the [Account margin](../get-started/settings#account-margin) settings, **Hide zero balances** and **Hide assets with zero margin ratio** are enabled by default, hiding assets that carry no margin or balance. If you change any of these filters, the platform remembers their states. #### Improved quick trade panels [#improved-quick-trade-panels] The **Market quick trade panel** has been moved not to cover the important controls of the [Price chart](../widgets/price-chart). Additionally, it now displays the **cross icon** to quickly close the panel if needed. *** ### Resolved issues [#resolved-issues-2] There have been no customer-facing issues reported in this release. ## November 7, 2025 [#november-7-2025] ### New features [#new-features-6] #### Tiered leverage system [#tiered-leverage-system] With this release, we're excited to introduce the **tiered leverage system** that provides more sophisticated leverage options based on your position sizes, offering better risk management. **Key points:** * **Dynamic leverage tiers**: Markets can now offer tiered leverage where your maximum available leverage decreases as your position size increases. This allows you to access higher leverage on smaller positions while maintaining appropriate risk controls on larger trades. * **Enhanced market information**: Markets with tiered leverage now display comprehensive leverage information in the **Market info** panel. A new **Leverage** tab shows all available tiers, including the notional value ranges and maximum leverage for each tier. * **Improved position tracking**: Your open positions now display both the leverage you selected when opening the position (**Requested leverage**) and the actual leverage being applied (**Leverage**). Detailed tooltips explain how these values are calculated, giving you better visibility into your margin usage. * **Smart leverage selection**: When placing orders on markets with tiered leverage, the system automatically calculates your margin requirements across all applicable tiers. You can see the exact margin required before placing your order. **How it works** For markets with dynamic leverage, your position is allocated across different tiers based on its notional value. Each tier has its own maximum leverage limit, typically starting with higher leverage for smaller positions and decreasing as position size grows. This allows you to maintain appropriate risk management. **Order placement** When trading on tiered markets, you can still select your preferred leverage (up to the maximum allowed for the first tier), and the system will automatically apply the appropriate leverage limits. The margin calculator shows you the exact requirements before you place your order. All existing positions continue to operate normally with no changes to your current trading experience. Markets without tiered leverage continue to work exactly as before. *** ### Improvements [#improvements-5] #### Improved documentation experience [#improved-documentation-experience] The documentation window is now fully resizable, allowing traders to adjust both vertical and horizontal dimensions independently. All screenshots can now be zoomed, making detailed interface elements clearly visible. #### Streamlined market selection [#streamlined-market-selection] The market selection control is now displayed as the **chevron icon** directly next to the market name in widgets. The magnifying glass icon has been removed. Both the market name and chevron are now clickable and open the market selector. #### Reorganized market information access [#reorganized-market-information-access] The market info popover has been relocated under the **info icon** in the widget header to maintain accessibility while keeping the market name area focused solely on selection functionality, creating a cleaner and more consistent user interface. #### Enhanced workspace tab design [#enhanced-workspace-tab-design] A clear distinction between active and inactive workspace tabs has been achieved due to intuitive styling. Workspace option buttons are now hidden by default to reduce visual clutter and only appear when tabs are active or being hovered over. This applies to both default and custom workspace tabs, creating a cleaner interface while maintaining full functionality when needed. *** ### Resolved issues [#resolved-issues-3] There have been no customer-facing issues reported in this release. ## October 9, 2025 [#october-9-2025] ### New features [#new-features-7] #### Placing orders from the Price chart [#placing-orders-from-the-price-chart] The [Price chart](../widgets/price-chart) widget now supports direct order placement with two new quick trading panels. The **Market quick trade panel** provides a persistent interface for instant buy/sell orders, while the **Limit quick trade panel** allows hover-based order placement at specific price levels. When enabled through **Price chart settings**, both panels offer configurable amount presets and leverage ratio selection for margin trading (when applicable), creating a seamless trading experience without leaving the chart view. #### Bulk order canceling [#bulk-order-canceling] The [Open orders](../widgets/open-orders) widget introduces a **Cancel all** button that closes all active orders simultaneously. This feature provides better risk management capabilities during volatile market conditions. #### In-platform documentation [#in-platform-documentation] User documentation is now integrated directly within the Trading terminal interface. This eliminates the need to switch between applications when accessing help materials or reference guides, keeping essential information readily available during trading sessions. #### New market subtype [#new-market-subtype] The new **Commodities** subtype has been added for CFD markets, enhancing the market categorization system. *** ### Improvements [#improvements-6] #### Enhanced position tracking [#enhanced-position-tracking] A new **Direction** column has been added to **Trades** info in the [Open positions](../widgets/open-positions) and [Closed positions](../widgets/closed-positions) widgets. It indicates whether a position size increased (In) or decreased (Out) as a result of each trade. This enhancement provides clearer visibility into position movement patterns. #### Cross rates calculation precision [#cross-rates-calculation-precision] Accuracy for cross-rate calculations has been improved by introducing a new cross-rate scale parameter. It has a default value of 8 and can be adjusted in configuration files. This addresses the previous limitation where cross rates were rounded to the root asset type scale (typically 2 decimal places), causing incorrect zero values in certain scenarios. The improvement ensures accurate cross-rate calculations across all currency and cryptocurrency pairs, regardless of their relative values. #### Redesigned Settings interface [#redesigned-settings-interface] The **Settings** menu has been restructured with a new tabbed popup interface. Related configuration options are now logically grouped, making settings easier to navigate and manage. #### Pre-filled Limit order price [#pre-filled-limit-order-price] Limit order placement now includes automatic price pre-population using the best bid or ask price from the order book. This static pre-fill reduces manual entry requirements and helps prevent pricing errors during order submission. #### Updated sorting of open positions [#updated-sorting-of-open-positions] [Open positions](../widgets/open-positions) are now sorted chronologically with the newest positions displayed at the top, improving visibility of recent trading activity. #### Improved messages [#improved-messages] User communications have been updated throughout the platform, including improved Introduction tour messaging for better onboarding and clearer system notifications. #### UI enhancements [#ui-enhancements] UI improvements for this release include: * **Support for dynamic resizing of the trading interface layout**: The trading interface now features a responsive layout system that dynamically adjusts to browser window resizing. Widgets automatically scale and reposition to maintain optimal viewing regardless of screen size changes. * **Loader**: [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now display loading indicators when fetching additional data. * **Improved PnL representation**: When displayed on charts, the PnL values are now accompanied by "+" or "–" signs for immediate profit/loss recognition. * **Improved scrollbars**: Scrollbar positioning has been refined to prevent overlay of table content, ensuring all data remains visible and accessible. *** ### Resolved issues [#resolved-issues-4] There have been no customer-facing issues reported in this release. ## July 2, 2025 [#july-2-2025] ### New features [#new-features-8] #### Trading reports [#trading-reports] We've implemented a new feature enabling you to generate trading reports for a specific period of time and download them as zipped CSV files to your computer. The report includes a detailed information on: * **Trade history** * Closed positions * Executed orders * Trades * **Transfers history** * **Account statistics** * Total balance * Realized PnL * Swaps * Funding * Commissions The data is available for any period within the last **92 days** (UTC time). The following timeframe presets have been implemented for your convenience: * Today * Current: week, month, quarter * Previous: week, month, quarter Access the new **Trading report** menu under the **Settings** icon on the topbar of the Trading terminal. *** ### Improvements [#improvements-7] #### Admin-managed orders and positions [#admin-managed-orders-and-positions] In the [Open positions](../widgets/open-positions), [Closed positions](../widgets/closed-positions), and [Order history](../widgets/order-history) widgets, if BP Admins have managed positions or orders, this is now indicated in the Reason field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, and mitigate risks. *** ### Resolved issues [#resolved-issues-5] There have been no customer-facing issues reported in this release. ## May 30, 2025 [#may-30-2025] ### New features [#new-features-9] #### PF trading [#pf-trading] We are excited to introduce **Perpetual Futures (PF) trading** on our platform. These contracts feature a funding fee mechanism based on the Mark price and Funding rate. A positive rate means Long positions pay Shorts, and a negative rate means the reverse. You can see the countdown to the next funding fee settlement in the [Market summary](../widgets/market-summary) widget. This update also includes a new market type — Perpetual — enhancing your trading opportunities. *** ### Improvements [#improvements-8] #### Price chart setting [#price-chart-setting] The [Price chart](../widgets/price-chart) widget now supports displaying of open positions, as well as open and executed orders. Click the **gear icon** in the topbar to access Price chart settings and enable desired options. #### Close all positions [#close-all-positions] The [Open positions](../widgets/open-positions) widget now features a new **Close all** option, offering enhanced management capabilities. This update provides a more efficient way to handle multiple positions by allowing you to simultaneously close: * All open positions * All open positions with positive PnL * All open positions with negative PnL #### Enhanced price control [#enhanced-price-control] The following enhancements have been implemented for the [Price control](../widgets/price-control) widget: * **Editable price alerts**: You can now adjust existing price alerts by clicking a price. * **Enhanced market additions**: Price and percentage fields now automatically open for editing when a new market is added to the widget. * **Visual indicators**: Arrows near price triggers aren’t shown if the price feed is unavailable, reducing clutter and potential confusion. #### Historical data limits [#historical-data-limits] The [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now provide historical data with a limit of **92 days**. *** ### Resolved issues [#resolved-issues-6] There have been no customer-facing issues reported in this release. ## April 17, 2025 [#april-17-2025] ### New features [#new-features-10] #### Netting account type [#netting-account-type] With this release, a new **Netting** account type has been enabled. It intelligently consolidates all orders placed on the same market into a single position. Previously, the system supported only Hedging, where each order opens a separate position. **Key points of netting** * **Reduced margin requirements**: Instead of calculating margin requirements separately for each position, netting combines them, lowering overall capital needs. * **Lower trading costs**: By holding opposing positions, traders often incur double position swaps. Netting treats these positions as one, reducing unnecessary costs. * **Streamlined position management**: Managing multiple positions manually can become complicated, especially when balancing between different trade sizes, directions, leverages and margin requirements. Netting helps with it by combining positions into a single one. **Netting VS Hedging** Netting may sometimes lack the flexibility required for complex hedging strategies. In contrast, hedging excels by allowing traders to hold both long and short positions simultaneously without offsetting them. This enhances the ability to track and adjust individual trades easily while permitting precise margin management for separate positions. The Hedging type is perfectly suited for traders seeking detailed control over their positions. On the other hand, the Netting type ensures simplicity and reduced margin requirements, making it the perfect choice for straightforward trading strategies. **Workflow changes** When opening a new trading account, you must now choose its type: either Hedging or Netting. This choice is permanent and influences all future trades in the account. In the account selection interface, each account displays its type: `H` for Hedging or `N` for Netting. All existing accounts are automatically assigned to the Hedging type. *** ### Improvements [#improvements-9] #### Improved widget control [#improved-widget-control] With this release, you now have enhanced control over the viewing experience: * **Configuring widget columns**: Certain widgets allow you to configure widget columns in a way that best suits your needs, offering you the flexibility to select which columns you wish to display or hide. Additionally, you can arrange the order of these columns for your convenience, ensuring that the information you prioritize is always at your fingertips. * **Rearranging widget tabs**: All widgets now feature drag-and-drop functionality for rearranging tabs effortlessly. This user-friendly feature offers a more customized and organized interface, making it easier than ever to personalize your widget experience. #### Enhanced Order book [#enhanced-order-book] The Order book widget has been upgraded with new customizable settings. This update introduces intuitive controls, empowering you to adjust the widget view according to your preference: * **Full view**: Shows both buy and sell orders along with the market spread. * **Buy only view**: Displays only buy orders and the market spread. * **Sell only view**: Displays only sell orders and the market spread. *** ### Resolved issues [#resolved-issues-7] There have been no customer-facing issues reported in this release. ## January 15, 2025 [#january-15-2025] ### New features [#new-features-11] #### Take profit, Stop loss, Trailing stop [#take-profit-stop-loss-trailing-stop] With this release, the following new triggers for open positions have been implemented on the platform: * **Take profit**: A take-profit trigger is used to close a position automatically once the market hits a predefined price, ensuring the trader locks in profits. * **Stop loss**: A stop-loss order is a trigger to limit potential losses. It automatically closes a position when its price changes to a predetermined level. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified value. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. These settings can be used when trading on CFD markets and can be applied to Market, Limit, and Stop orders, as well as for currently open positions. The new settings can be enabled when placing an order via the [Place order](../widgets/place-order) widget (Advanced mode). Until a position is fully closed, they can also be adjusted or canceled via the [Open positions](../widgets/open-positions) widget. The information about applied settings is also available in the corresponding widgets: [Closed positions](../widgets/closed-positions), [Open orders](../widgets/open-orders), and [Order history](../widgets/order-history). *** ### Resolved issues [#resolved-issues-8] There have been no customer-facing issues reported in this release. *** ## Past releases [#past-releases] ### December, 2024 [#december-2024] #### New features [#new-features-12] ##### CFD trading [#cfd-trading] With this release, we're excited to announce the support for CFD (Contract for Difference) trading on our brokerage platform. This empowers you to trade with dynamic leverage, using your funds as collateral to secure positions confidently. Enjoy the flexibility to go both long and short, capitalizing on both bullish and bearish markets. Our CFD trading support boasts an intuitive interface, robust risk management tools, and real-time data. ##### Innovative market approach and instrument picker [#innovative-market-approach-and-instrument-picker] * **Market type**: Markets are now classified into Spot and CFD, reflecting their differing parameters. A panel indicating CFD or Spot is now included in all widgets. * **Market parameters and trading schedule**: Click a market name to access its key parameters and scheduled trading sessions. * **Market categories**: Now accessible via the top bar, offering a hierarchical view for easier selection and switching between markets. ##### Account margin settings [#account-margin-settings] Access the new [Account margin settings](../get-started/settings) to monitor your balances and configure assets to be used as collateral for CFD trading. ##### Reworked Place order widget [#reworked-place-order-widget] Place any order with a [single widget](../widgets/place-order) now. Choose Quick IOC Market or Stop with adjusted leverage — all conveniently in one place, along with an order summary. ##### Positions [#positions] Discover two new widgets for position monitoring: * [Open positions](../widgets/open-positions): Offers real-time monitoring of currently open positions with price changes, PnL, used margin, and other parameters. * [Closed positions](../widgets/closed-positions): Provides historical data on position details, prices, and realized PnL. ##### Risk management [#risk-management] You now have three essential widgets to maintain control: * [Margin](../widgets/margin): Monitor your margin account parameters in real time and respond swiftly to changes. * [Price control](../widgets/price-control): Set price alerts tailored to your specific needs and parameters. * [Messages](../widgets/messages): Receive system notifications and price alerts directly. ##### Market data [#market-data] Two new widgets have been introduced to enhance market monitoring: * [Market summary](../widgets/market-summary): Provides detailed information and updates on price changes for a specific market. * [All markets](../widgets/all-markets): Displays price change statistics across all markets simultaneously. #### Improvements [#improvements-10] * Performance has increased significantly, allowing each trader to hold up to 1,000 CFD positions open. * Limits have been increased to 3,000 requests per second. #### Resolved issues [#resolved-issues-9] There have been no customer-facing issues reported in this release. *** ### June 20, 2024 [#june-20-2024] #### Improvements [#improvements-11] * Account selection is now available from the topbar of the Trading terminal. Once you change your account, all the widgets will automatically adjust to show relevant information for the selected account. * Tabs are now available in the Trading terminal. You can place up to 10 tabs to open multiple workspaces simultaneously for better information organization. You can utilize pre-configured layouts for your workspaces or create custom ones. *** ### June 13, 2024 [#june-13-2024] #### New features [#new-features-13] ##### iOS mobile application [#ios-mobile-application] With this release, our team is thrilled to announce the launch of the brand-new iOS mobile app. The mobile app is closely integrated with B2CORE mobile. Along with single sign-on implemented, it allows you to seamlessly navigate between the apps, without re-entering credentials. In the mobile app, just like in the web version of the Trading terminal, you can access all of your BP accounts, place orders, monitor market data, and so on. For your convenience, it all can be done in a very similar way as in the web version. A consistent and user-friendly interface makes using the app easy and intuitive. Among the key features and services that the new BP mobile offers: * The account list with detailed balances, to always keep your funds under control. Creation and renaming of accounts, to keep your funds well organized. * Asset balances screen, with the amounts of free and frozen funds specified and with the possibility to hide assets with zero balances. * The Order book and price chart, to monitor and analyze trading data and make buy or sell decisions, with a quick and easy jump to the order placing screen. * Candles and line charts, with easy switching and the possibility to scroll the data for historical values. * Limit & Market order placing, with all time in force options supported in the Web version (Market: IOC, FOK; Limit: IOC, FOK, GTC, GTD, Day). * Open and history orders lists, with easy access to order parameters and details, quick canceling or repeating an order. * Light and dark themes and many more. ### October 18, 2023 [#october-18-2023] #### New features [#new-features-14] With this initial release, our team is happy to announce the launch of our new Trading terminal. ##### Placing orders [#placing-orders] The platform currently supports placing Market, Limit, Stop Market, and Stop Limit orders (refer to [Order types](../knowledge-base/order-types)). You can also choose from various [Time in force](../knowledge-base/time-in-force) options such as FOK, IOC, GTC, GTD, and DAY. ##### Widgets [#widgets] The platform provides you with enhanced widgets that are specifically designed for convenient trading. These widgets allow you to easily place orders, access the Order book, monitor open orders and order history, and much more. Refer to [Place order](../widgets/place-order) and the other pages of the Widgets section for more information. ##### Dashboard [#dashboard] The customizable dashboard allows you to personalize the layout to suit your needs and keep you focused on what's important. Refer to [Interface overview](../get-started/customizing-your-terminal) to learn more about workspace customization. ## Summary [#summary] This widget provides AI-powered market analysis and trading recommendations for the selected market. AI Assistant The widget is organized into the following sections: * [AI Recommendation](#ai-recommendation): Overall recommendation score. * [Forecast](#forecast): Price target and market sentiment. * [Signal Drivers](#signal-drivers): Technical, on-chain, and sentiment signals. * [Suggested Actions](#suggested-actions): AI-generated trading suggestions. * [Key Metrics](#key-metrics): Market data overview. ## AI Recommendation [#ai-recommendation] Displays a numeric score from 0 to 100 representing the overall AI assessment of the market, along with a label such as **Strong Buy**, **Buy**, **Neutral**, **Sell**, or **Strong Sell**. A higher score indicates a more favorable outlook. ## Forecast [#forecast] **1Y Price Target** The forecasted price in one year and the expected percentage change from the current price. *** **Market Sentiment** A visual bar showing the ratio between bullish and bearish sentiment among market participants. ## Signal Drivers [#signal-drivers] Signals that influence the AI recommendation, categorized into three types: * **Technical**: Signals based on technical analysis indicators such as RSI and Moving Averages. * **On-Chain**: Signals based on blockchain data such as ETF inflows, active addresses, and total value locked (TVL). * **Sentiment**: Signals based on community and analyst opinions. Each signal includes a description and an impact assessment: **Bullish**, **Bearish**, or **Neutral**. ## Suggested Actions [#suggested-actions] A list of AI-generated trading suggestions based on the current market conditions. These are informational recommendations, not automated trading signals. ## Key Metrics [#key-metrics] The following market data is displayed: **All-Time High** The highest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **All-Time Low** The lowest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **24h Volume** The total trading volume over the last 24 hours in USD. *** **Market Cap** The total market capitalization of the asset in USD. AI-generated insights are for informational purposes only. The AI Assistant widget can be enabled or disabled by the platform administrator. If the widget isn't available in the **Add Widget** menu, contact your broker. ## Summary [#summary] Use this widget to monitor price data on all markets available on the platform. The widget is dynamic and is continuously updated in real time. All markets ## Fields [#fields] The following information is provided about each market: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current market price, in the quote asset and in the platform root asset. This value is green if the price is rising and red if it's falling. *** **24h change** The price change over the last 24 hours, in absolute and percentage values. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. ## Summary [#summary] This widget displays the list of all asset balances on your account. Assets ## Settings [#settings] ### Hide zero balances [#hide-zero-balances] Use this option to hide all assets with zero balances from the list. It's enabled by default. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance at your disposal, meaning the difference between your total assets and a sum of all limit orders placed by this time. This value is calculated as *Total – Halted*, where *Halted* is the asset amount frozen on the account for execution of placed Limit orders. *** **Available, \{RAT}** The available balance, in conversion to the platform root asset. *** **Total** The overall amount of the asset available in your wallet, including locked funds. *** **Total, \{RAT}** The total balance, in conversion to the platform root asset. ## Summary [#summary] This widget displays a list of your closed positions on the selected account. The entire history of your closed positions is available. Closed positions The widget lists only closed positions. For a list of currently open positions, use the [Open positions](open-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists closed positions for the last three months. To display positions closed during a specific time period, use the **Select date range** field. The most recently closed positions appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related orders [#view-related-orders] Click the **chevron icon** in a position row to expand a list of position-closing orders. As positions can be partially closed, there may be more than one line. For each executed position-closing order, a separate line is added. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Pos. closed size** The closed volume, in lots, which is equivalent to the corresponding filled order volume. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Close price** The volume-weighted average price (VWAP) of trades related to a position-closing order. *** **Close order ID** The identifier of an order closing the position. *** **Realized PnL, \{RAT}** The actual profit or loss earned, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). *** **\{RAT} notional** The equivalent of the closed volume in the platform root asset. *** **History rate to \{RAT}** The rate to the platform root asset at the moment of position closing. *** **Reason** The reason for closing a position. Possible values: * **Trader**: The position was closed by you. * **Admin**: The position was closed by an Admin. * **Stop-out**: The position was automatically closed by the system, as a result of Stop out. * **Stop loss**: The position was closed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The position was closed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The position was closed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. *** **Open date, time** The date and time when a position was opened. *** **Closed date, time** The date and time when a position-closing order was last updated (fully executed). ## Summary [#summary] This widget helps you monitor margin parameters and statistics. Margin ## Fields [#fields] All values are in displayed in conversion to the platform root asset: **Your margin level** The ratio of your funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. Possible values: * **Empty**: No open positions. * **Low risk**: Everything is ok. * **Margin call**: Your margin level fell below the set Margin call value. You received a notification urging you to increase the margin level to avoid a Stop out. Remember that if you ignore this warning, the margin level may continue to decrease. During the Margin call, you can only close existing positions; opening new positions isn’t possible. * **Stop out level**: Your margin level fell below the set Stop out value; the platform started a process of liquidating your positions. This process continues until the margin level exceeds this required value. **ANY** currently open position can be closed regardless of its side and volume. *** **Margin balance** The total amount of your funds that can be used as a collateral for CFD trading. It’s calculated as Σ(*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*), where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the platform root asset. The Margin balance is continually recalculated based on price fluctuations. An increase in the prices of assets boosts available Balance & Free margin. Conversely, a decrease in asset prices may reduce the available Balance and Free margin. Additionally, a decline in the prices of assets with open positions may trigger Margin calls and Stop outs. *** **Credit** A promotional bonus granted by your broker for margin (CFD and Perpetual) trading, shown in the platform root asset (RAT). When you have no credit, this row shows 0. Credit increases your Equity and Free margin and can be used as collateral to open positions. It becomes available immediately when granted and never expires. However, credit cannot be withdrawn as cash, so it is excluded from your withdrawable balance. Your broker can revoke credit at any time, and the row updates in real time when this happens. The row includes an info tooltip that reads: *Promotional credit for margin trading only. Cannot be withdrawn.* *** **Equity** The potential balance of your account if all your positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. *** **Used margin** The amount of funds that is used for maintaining all your open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **Example** **Step 1: Initial balance** * Margin balance: $10,000 * Opened positions: 0 * Free margin: $10,000 * Used margin: $0 **Step 2: Open a long position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 100 = $1,001 * After opening: * Free margin: $8,999 * Used margin: $1,001 **Step 3: Open a long position (Leverage 1:20)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 20 = $5,005 * After opening: * Free margin: $3,994 * Used margin: $6,006 **Step 4: Open a short position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 9 lots (900,000 units) * Current price: $1 * Required margin: $(900,000 × 1.001) / 100 = $9,009. The system verifies that upon opening this position, the MarketUsedMargin remains valid by satisfying the condition: **MarketUsedMargin** = MAX(*MarketPositionLong*, *MarketPositionShort*) = MAX(6,006, 9,009) = 9,009. Since the condition is met, the position opens. * After opening: * Free margin: $991 * Used margin: $9,009 As a result, you can open multiple opposite positions without significantly increasing the Used margin. Furthermore, closing positions never increases the Used margin. *** **Free margin** The amount of funds that can be used for opening new positions. *** **Unrealized PnL** The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) ## Summary [#summary] Use this widget to assess the current market depth indicating the actual liquidity of an asset, which is evaluated based on the number of currently open orders to buy and sell it as well asset prices and volumes at various price levels. Market depth The widget is dynamic and is continuously updated in real time. The widget displays a chart indicating the overall volume of buy (green) and sell (red) orders at various price levels awaiting execution at the moment. You can hover the mouse pointer over the chart to learn the exact price and volume of an asset traded at a specific price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ## Summary [#summary] Use this widget to monitor statistics on a specific instrument. The widget is dynamic and is continuously updated in real time. Market summary To monitor multiple instruments at a time, use the [Watch list](watch-list) widget. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the first column. To change the market, click the market symbol and select a different one from the list. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current top-of-the-book price, in the quote asset. *** **Current price, \{RAT}** The current top-of-the-book price, in conversion to the platform root asset. *** **24h change** The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h high** The highest trade price over the last 24 hours. This value is always green. *** **24h low** The lowest trade price over the last 24 hours. This value is always red. *** **Info icon** Click this icon to view market details and trading sessions schedule. ## Summary [#summary] This widget displays a list of received notifications, both system and configured via the [Price control](price-control) widget. Messages ## Settings [#settings] ### Mark as read [#mark-as-read] Unread alerts are marked with a red dot in the list: * Click the dot to mark the notification as read. * Click **Mark all as read** to mark all new notifications as read at once. * Click the **three dots** icon in the upper right corner of the widget to access the **Hide read notifications option**. The counter of unread alerts is also displayed on the **bell icon** in the topbar. ## Summary [#summary] This widget displays a list of Limit orders that have been placed from this specific account and are currently open and assigned one of the following [statuses](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. Open orders The widget lists only open orders, that are currently not filled or partially filled. For a list of orders in the final statuses, use the [Order history](order-history) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders for all the time. To display orders for a specific time period, use the **Select date range** field. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled so far. *** **Fee** The total commission paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that hasn’t yet been filled. *** **Limit price** For Limit orders, the Limit price set when placing the order. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set. *** **Used leverage** For margin trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Valid until** The date and time when an order expires. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Admin**: The order was placed by an Admin. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Cancel orders [#cancel-orders] To cancel an order, click the **×** in the corresponding row. To cancel all active orders at once, click the **Cancel all** button in the widget header. ## Summary [#summary] This widget displays a list of your positions currently open on the selected account. Open positions The widget lists only open positions. For a list of closed positions, use the [Closed positions](closed-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists open positions for all the time. To display positions opened during a specific time period, use the **Select date range** field. The most recent position appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related trades [#view-related-trades] Click the **chevron icon** in a position row to expand a list of related trades. ### Close positions [#close-positions] To close a position, hover over it and click the **CLOSE** button that appears. To close all/multiple positions at once, click **Close all** and select the desired option: close all positions or close positions with positive/negative PnL. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Position size** The current position volume, in lots. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Current price** The current market price of the base asset: bid for Long positions and ask for Short positions. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Unrealized PnL, DAY, \{RAT}** The potential profit or loss earned for a current day, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. *** **Unrealized PnL, DAY, %** The potential profit or loss earned for a current day, in percents. *** **Unrealized PnL, Total, \{RAT}** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). *** **Unrealized PnL, Total, %** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset, in percents. *** **Used margin, \{RAT}** The amount of your funds used for maintaining a position, in conversion to the platform root asset. *** **Leverage** The actual leverage ratio used for opening a position. *** **Req. leverage** The leverage ratio you requested when opening a position. *** **\{RAT} notional** The current position size equivalent in the platform root asset. *** **Rate to \{RAT}** The current exchange rate of a quote asset to the platform root asset. *** **Open date, time** The date and time when a position was opened. *** **Updated date, time** The date and time of the latest position-related trade. *** **Reason** The reason for opening a position: * **Trader**: The position was opened by you. * **Admin**: The position was opened by an Admin. * **Webhook alert**: The position was opened via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. ## Summary [#summary] This widget displays a list of currently open buy and sell limit orders for a selected asset along with the current bid-ask spread. Order book The widget is dynamic and is continuously updated in real time. It provides three different sections displaying the following information: * Open sell orders are highlighted in red and listed in the top section. The best ask, which is the sell order with the lowest price, is displayed at the bottom of this list. * Open buy orders are highlighted in green and listed in the bottom section. The best bid, which is the buy order with the highest price, is displayed at the top of this list. * The middle section displays the current bid-ask spread indicating the gap between the best ask and bid prices declared for an asset. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Display only asks/bids [#display-only-asksbids] In the upper part of the widget, you can choose how to display the Order book: * Full view. * Buy orders only + spread. * Sell orders only + spread. ## Fields [#fields] Each row of the Order book provides the following information about a selected market: **Price, \{QUOTE}** The price, in the quote asset. *** **Amount, \{BASE}** The total amount of the base asset available at a corresponding price level. *** **Total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. In addition, you can use the [Market depth](market-depth) widget to evaluate the liquidity of a specific asset based on the overall volume of orders traded at various price levels. For Spot markets, hover over Order book rows to view additional information and buy or sell assets in click: **Average price** The average price, in the quote asset. *** **Total volume** The total amount of the base asset available at a corresponding price level. *** **Grand total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. *** **Buy** / **Sell** Click the button to instantly place a Market order to buy or sell the asset at the selected price level. ## Summary [#summary] This widget provides up-to-date information about the orders executed on a selected market partially or in full, as well as the orders that were canceled, rejected, and expired. The entire order history of your account is available. Order history The widget lists only the orders to which final statuses are assigned. For a list of orders that are still being executed, use the [Open orders](open-orders) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders with the *Completed* status for the last three months. To display orders for a specific time period, use the **Select date range** field. To display orders with specific statuses, select one or more from the dropdown above the list. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled. *** **Fee** The total commissions paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that wasn't filled. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Completed*, *Cancelled*, *Rejected*, or *Expired*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Stop loss**: The order was placed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The order was placed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Summary [#summary] Use this widget to place new orders. Place order The widget has two states: ### The PRO toggle is disabled [#the-pro-toggle-is-disabled] In this state, you can quickly place **IOC Market** and **GTC Limit** orders by selecting the order side (Buy/Sell) and type (Market/Limit), and specifying the order size (in lots) and price (for Limit orders). You can also place orders on CFD markets with the maximum leverage automatically applied. ### The PRO toggle is enabled [#the-pro-toggle-is-enabled] In this state, you get access to more precise order settings, such as: * **Stop orders** * **Time in force** * **Leverage** * **Take profit, Stop loss, Trailing stop** * **Comment** * **Complete order information** The **Comment** field allows you to attach a text note to the order (up to 100 characters). The comment is inherited by the resulting position and can't be edited after the order is placed. ## Settings [#settings] ### Select a market [#select-a-market] The market on which the order will be placed is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Place an order [#place-an-order] To place an order, fill in the parameters, review order details and preliminary calculated values, and then confirm the order by clicking the **Place** button. For a Limit order whose price crosses the current top-of-book — Buy at or above the best ask, or Sell at or below the best bid — the platform shows a confirmation dialog before submission. The dialog shows the entered price and the current best bid/ask, and lets you confirm or cancel the order. This warning is enabled by default; you can disable it from the dialog (**Do not show this warning again**) or from the **Limit order cross-TOB warning** toggle in [Settings](../get-started/settings#action-confirmation). ### Set price triggers [#set-price-triggers] If using **Take profit, Stop loss, Trailing stop**, set the prices in consideration of the current highest market bid/ask or a specified Limit price: These values can be adjusted any time until the position is fully closed via the [Open positions](open-positions) widget. You can't place orders during non-trading hours, according to the trading calendar schedule. The order controls are disabled when the selected account is Halted or Frozen. For more information, see [Account status](../get-started/customizing-your-terminal#account-status). You will not be able to place an order if the execution of the order causes your margin level to fall below the *Margin call* level. The same conditions apply to withdrawal operations. ## Summary [#summary] This widget displays a price chart showing fluctuation of prices for a selected market over a certain time period. Price chart The horizontal axis (X-axis) represents the time scale, and the vertical axis (Y-axis) indicates the price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Customization [#customization] Multiple customization options are provided, allowing you to configure the chart according to your preferences. You can switch between bar, candle, Heikin Ashi, line, area and baseline views, as well as specify the time period for which data should be displayed. The chart supports numerous financial indicators, such as moving averages and regressions, and can feature a variety of custom shapes, including arrows and lines, pitchforks, and various ranges, allowing you to perform an in-depth market analysis. ### Display options [#display-options] The widget supports displaying of open positions, price triggers, open and executed orders. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart) to enable desired options. ## Placing orders [#placing-orders] ### Enable placing orders [#enable-placing-orders] To enable placing orders directly from the Price chart, you need to activate the corresponding settings: 1. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart). 2. Activate the **Market quick trade panel** or **Limit quick trade panel** toggle, or both. 3. If needed, adjust the amount presets. These amounts will be available for quick selection when placing an order. ### Market quick trade panel [#market-quick-trade-panel] If the corresponding setting is activated, the draggable **Market quick trade panel** is constantly displayed on the Price chart. ### Limit quick trade panel [#limit-quick-trade-panel] If the corresponding setting is activated, the **+** will appear when hovering over price levels on the chart. Clicking it will open the **Limit quick trade panel**: * in the upper half of the chart — to sell; * in the lower half of the chart — to buy. ### Place a new order [#place-a-new-order] To place a new Market or Limit order from the Price chart, when a corresponding panel is displayed: 1. Select the **amount** from configured presets. 2. Select a **leverage** ratio, if trading on CFD or PF markets. 3. Click **Buy** or **Sell**. The order will be placed according to the selected type. ## Summary [#summary] Use this widget to configure alerts that will be delivered to the [Messages](messages) widget when an instrument price reaches the specified level. Price control ## Settings [#settings] ### Configure a new alert [#configure-a-new-alert] To configure a new alert: 1. Click the **Add market** button to select a required market from the list. 2. Click the **+** icon below the instrument name to add a new alert trigger. 3. In the displayed fields, specify the exact price or the price change in percents (positive or negative). The other value will be calculated automatically. 4. Click the **check mark icon** to add the trigger. Now you will receive a notification in the [Messages](messages) widget, once the instrument price hits the specified level. You can configure multiple triggers for each instrument. ### Edit alerts [#edit-alerts] Click the price to edit the existing alert. ### Remove alerts [#remove-alerts] Click the **×** button on the trigger panel to remove it and stop receiving corresponding notifications. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ## Summary [#summary] This widget displays a list of untriggered Stop orders created on the selected account. Once a market price reaches your predetermined Stop price, the Stop order is activated and submitted as either a Market or Limit order. It's then removed from this widget. You can now find it in either the [Open orders](open-orders) or [Order history](order-history) widget, depending on its current status. Stop orders ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the Stop Market and Stop Limit orders for all the time. The most recent order appears at the top of the list. To display orders for a specific time period, use the **Select date range** field. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types): Stop Market or Stop Limit. *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Stop price** The stop price specified when creating an order. When the market reaches this price, the Stop order will be placed (as a Market or Limit order. *** **Limit price** The price of a Limit order that will be placed when the Stop price is triggered. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Order ID** The system identifier of an order. ## Summary [#summary] Use this widget to monitor statistics on multiple instruments at a time. The widget is dynamic and is continuously updated in real time. Watch list ## Settings [#settings] ### Add/remove instruments [#addremove-instruments] Click the **Add market** button to select a required market from the list. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Last price** The price of the last trade. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h low** The lowest trade price over the last 24 hours. *** **24h high** The highest trade price over the last 24 hours. Understand the basics and learn everything you need to start using the B2TRADER API Understand the basics and learn everything you need to start using the B2TRADER API Consult an in-depth reference describing REST API requests and responses Consult an in-depth reference describing REST API requests and responses Explore the supported WebSocket API methods and streams Explore the supported WebSocket API methods and streams Connect to the FIX 4.4 API for market data streaming and order execution Connect to the FIX 4.4 API for market data streaming and order execution ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Trading API: Stop orders for closed markets [#trading-api-stop-orders-for-closed-markets] The **Trading API** now accepts **Stop** orders for markets that are closed according to their trading calendar. The order is stored and activates automatically when the market reopens, instead of being rejected at submission. #### Reports API: full account history [#reports-api-full-account-history] Trading reports can now be generated for the entire account history. The previous **92-day** limit has been removed, and an **All data** range is now available for report generation. #### Trading API: market asset identifiers [#trading-api-market-asset-identifiers] The `baseAssetId` and `quoteAssetId` fields have been added to the v6 `/markets` responses, allowing clients to resolve the base and quote assets of each market without additional lookups. #### Accurate unrealized PnL [#accurate-unrealized-pnl] Unrealized PnL returned by the API is now calculated using the correct order book side for each position direction, improving the accuracy of PnL values in position and margin responses. *** ### Resolved issues [#resolved-issues] * Resolved an issue where `WebhookAlert` order reason and position modifier values were returned as numeric codes instead of API enum strings in History API `/v2/orders` responses. ## April 9, 2026 [#april-9-2026] ### New features [#new-features] #### Trading credit in API responses [#trading-credit-in-api-responses] Broker-issued **trading credit** is now exposed through the API. The account margin data response and the real-time margin stream include the current credit amount in the Reference Asset (`creditInRAT`). Credit is included in the account equity and excluded from the withdrawable amount. *** ### Improvements [#improvements-1] #### Webhook Trading API: webhook URL in key listing [#webhook-trading-api-webhook-url-in-key-listing] The list webhook API keys response now includes the `webhookUrl` field, so the configured webhook endpoint can be retrieved for each key. ## March 16, 2026 [#march-16-2026] ### New features [#new-features-1] #### Webhook Trading API [#webhook-trading-api] A new **Webhook Trading API** has been added, enabling automated order creation via webhook alerts with API key authentication. **Key points:** * Create and manage webhook API keys for secure authentication * Receive trading alerts and create orders automatically * Idempotency supported via deduplication ID * Market type routing by symbol prefix (spot, CFD, perpetual) #### Public Account ID [#public-account-id] A new `publicAccountId` field has been added across all API endpoints, providing a human-readable account identifier as an alternative to internal UUIDs. **Affected APIs:** * Trading API — account-related responses and filters * Settings API — account configuration endpoints * History API — all REST endpoints and WebSocket streams * Reports API — report responses and filters #### Long-term trading data history [#long-term-trading-data-history] Date range restrictions have been removed from **Order History** and **Closed Positions** endpoints, allowing access to full trading history without time-based limitations. *** ### Improvements [#improvements-2] #### Transfer subtype field [#transfer-subtype-field] A new `subtype` field has been added to transfer responses in the History API to distinguish **Negative Balance Protection** transfers from manual ones. #### Rounded position prices [#rounded-position-prices] The `positionPriceInRAT` values are now properly rounded in closed position API responses according to the Reference Asset (RAT) scale. *** ### Resolved issues [#resolved-issues-1] * Resolved an issue where `/total-swaps` requests returned HTTP 504 timeout errors. ## March 11, 2026 [#march-11-2026] ### Added FIX API documentation [#added-fix-api-documentation] Added new FIX API section covering Market Data and Trading sessions via the FIX 4.4 protocol. ## March 11, 2026 [#march-11-2026-1] ### Initial version [#initial-version] ## March 2, 2026 [#march-2-2026] ### New features [#new-features-2] #### Trading Terminal AI assistant [#trading-terminal-ai-assistant] A new **AI assistant** has been added to the Trading Terminal, providing traders with an intelligent widget for market analysis and trading support. *** ### Improvements [#improvements-3] #### Public Account ID (preview) [#public-account-id-preview] The `publicAccountId` field has been added to account-related API responses as a preview, ahead of the full rollout across all endpoints. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-3] #### Funding Rates API [#funding-rates-api] New API endpoints have been added for retrieving funding rate data synchronized from **B2CONNECT**, including funding rates, mark price, and funding interval for Perpetual Futures markets. **Key points:** * Funding rate values streamed in real time * Mark price used for position valuation when available from LP * Funding interval synchronized per market configuration * FIX API contract extended with funding data fields #### OHLC Candlestick API [#ohlc-candlestick-api] A new API endpoint has been added for retrieving OHLC (candlestick) data, supporting both **Spot** and **Perpetual Futures** markets. Minute-level candle data is now stored for up to 5 years. OHLC candle data streaming is also available via the WebSocket API using gRPC transport, providing real-time candlestick updates. #### Favorite markets [#favorite-markets] A new **Favorite markets** feature has been added, allowing traders to manage personalized market lists via the Trading API. #### Comment field for orders and positions [#comment-field-for-orders-and-positions] A new `comment` field has been added to order and position responses across REST, WebSocket, and History APIs. The comment can be set when placing an order and is propagated to the associated position and execution records. #### B2COPY Integration API [#b2copy-integration-api] New API endpoints have been added for **B2COPY** and IB (Introducing Broker) integrations, including special account types for copy trading. The `isCopyTradingAccount` field has been added to the `/api/v1/total-fundings` endpoint. *** ### Improvements [#improvements-4] #### FIX API: enhanced request throughput [#fix-api-enhanced-request-throughput] The FIX API trading request processing has been optimized to support up to 100 requests per second per connection. All `TimeInForce` types are now supported, including **GTD** (Good Till Date). #### Multilingual support [#multilingual-support] Trading API, Settings API, and Reports API endpoints now support multilingual content with full Unicode character support, enabling localized responses for configurable fields, report names, and templates. #### Stop Market order calculation [#stop-market-order-calculation] The **Value** and **Amount** calculation for **Stop Market** orders has been corrected for **Spot** markets. **Slippage Rate** has been removed from **CFD** and **Perpetual Futures** order calculations. #### Trading API: empty categories hidden [#trading-api-empty-categories-hidden] Empty market categories are now automatically excluded from Trading API responses, reducing unnecessary data in category listings. #### Balance API: zero balance for all assets [#balance-api-zero-balance-for-all-assets] Assets without prior balance operations now return a zero balance in API responses instead of being omitted. #### Cross-rate market configuration [#cross-rate-market-configuration] Markets used exclusively for cross-rate calculations can now be disabled for trading while remaining active for rate conversion. #### History API: extended contracts [#history-api-extended-contracts] Positions and Events API responses have been extended with additional fields. The `updatedAt` field is now available as a sorting and filtering parameter in History Server API endpoints. #### Settings API: market update endpoint [#settings-api-market-update-endpoint] The market update endpoint has been changed from `PATCH` to `PUT` semantics, requiring the full market object in the request body. #### Settings API: legacy endpoints removed [#settings-api-legacy-endpoints-removed] Legacy commission and routing rule endpoints have been removed following the tier commission update. Use the current endpoints as documented in the API reference. *** ### Resolved issues [#resolved-issues-2] * Resolved an issue where `takeProfitPrice` and `stopLossPrice` values were missing from the History Server `/v2/orders` endpoint responses. * Resolved an issue where bulk order cancellation returned a successful result for non-existing orders. * Resolved an issue where bulk order cancellation returned a successful result for orders that could not be cancelled. * Resolved incorrect error codes returned when `closePositionLotAmount` was set to `0`, a negative value, or an empty string. * Resolved an issue where the WebSocket Book stream continued sending prices with an outdated tick size after market parameter changes. * Resolved an issue where negative spreads in the **Market Data API** were not handled correctly. * Resolved an issue where orders could not be created when using the default 24/7 calendar. * Resolved an issue where the `/external-orders` API returned `null` for `rejectReason` although the Trading Server received a reason from the LP. Customize your Trading Terminal and configure settings Customize your Trading Terminal and configure settings Explore and manage all available trading widgets Explore and manage all available trading widgets Learn basic terms and values used across the platform Learn basic terms and values used across the platform The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](trading) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `V` — Market Data Request (Client → B2TRADER) * `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER) * `X` — Market Data — Incremental Refresh (Client ← B2TRADER) * `Y` — Market Data Request Reject (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Market Data session, use the following parameters provided by B2TRADER: * **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint) * **SenderCompID**: Your client identifier for the Market Data session * **TargetCompID**: The server identifier for the Market Data session * **Protocol**: FIX 4.4 The Market Data connection does not require SSL. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request. ```text title="Example" 8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Optional. ```text title="Example" 8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^ ``` *** ## Market Data Request (V) [#market-data-request-v] This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol. After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update. To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout. **`262 MDReqID`** `String` The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard. **`263 SubscriptionRequestType`** `int` The type of response expected from the server. Required. Possible values: * `1` — Subscribe: receive updates as the market status changes * `2` — Unsubscribe: stop streaming market data for the specified symbol **`264 MarketDepth`** `int` The market depth for an order book snapshot. Required. Possible values: * `0` — Full order book * `1` — Top-of-the-book prices **`265 MDUpdateType`** `int` The update type. Required. Must be `1` (incremental updates for changed price levels only). **`267 NoMDEntryTypes`** `int` The number of `<269>` MDEntryType entries requested. Required. > Repeating group: **`269 MDEntryType`** `int` The side of the quote. Required. Possible values: * `0` — Bid * `1` — Ask **`146 NoRelatedSym`** `int` The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each. > Repeating group: **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```text title="Example (Client → B2TRADER)" 8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^ ``` ## Market Data — Snapshot/Full Refresh (W) [#market-data--snapshotfull-refresh-w] This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^ ``` ## Market Data — Incremental Refresh (X) [#market-data--incremental-refresh-x] This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. * Must be unique among active entries when `<279>` MDUpdateAction is `0` (New) * Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete) **`279 MDUpdateAction`** `int` The update type. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — New * `1` — Change * `2` — Delete **`58 Text`** `String` Additional context. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^ ``` ## Market Data Request Reject (Y) [#market-data-request-reject-y] This message is sent by the server to reject a Market Data Request due to business or technical reasons. **`262 MDReqID`** `String` The identifier of the rejected Market Data Request. Required. **`281 MDReqRejReason`** `int` The reason why the request is rejected. Optional. Possible values: * `0` — Unknown symbol * `1` — Duplicate MDReqID * `2` — Insufficient bandwidth * `3` — Insufficient permissions * `4` — Unsupported SubscriptionRequestType * `5` — Unsupported MarketDepth * `6` — Unsupported MDUpdateType * `8` — Unsupported MDEntryType **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^ ``` The Trading session enables order placement and execution management via the FIX 4.4 protocol. Use this session to submit orders and receive real-time execution reports for your trading activity. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Trading** session only. For real-time order book streaming, use the [Market Data](market-data) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `D` — New Order Single (Client → B2TRADER) * `8` — Execution Report (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Trading session, use the following parameters provided by B2TRADER: * **Host and port**: The Trading endpoint (provided separately from the Market Data endpoint) * **SenderCompID**: Your client identifier for the Trading session * **TargetCompID**: The server identifier for the Trading session * **Protocol**: FIX 4.4 The Trading connection requires SSL with a self-signed certificate. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=117^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=117^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=93^35=A^1=68a4446ac84827ff5cd35c74^34=225^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=054^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Conditional — required when sent in response to a Test Request. ```text title="Example" 8=FIX.4.4^9=79^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=156^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Required. ```text title="Example" 8=FIX.4.4^9=87^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=250^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=90^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=176^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=105^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=Session terminated by client^10=183^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=81^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=009^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Execution Report with rejected status and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=128^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=11^372=D^373=1^58=Required tag missing: ClOrdID^10=126^ ``` *** ## New Order Single (D) [#new-order-single-d] This message is sent by the client to place a new order. The server responds with an Execution Report confirming the order status. For details on supported order types, see [Order types](../get-started/order-types). For details on time-in-force options, see [Time in force](../get-started/time-in-force). **`11 ClOrdID`** `String` The unique client-assigned order identifier. Required. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`38 OrderQty`** `Qty` The order quantity. Required. Must be greater than zero. The decimal precision must not exceed the market's amount scale, and the value must be at least the market's minimum amount. **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`59 TimeInForce`** `char` The order's time-in-force policy. Required. Possible values: * `0` — Day * `1` — Good Till Cancel (GTC) * `3` — Immediate or Cancel (IOC) * `4` — Fill or Kill (FOK) * `6` — Good Till Date (GTD) **`44 Price`** `Price` The order price. Conditional — required when `<40>` OrdType is `2` (Limit), must not be present when `<40>` OrdType is `1` (Market). Must be greater than zero. The decimal precision must not exceed the market's price scale. **`126 ExpireTime`** `UTCTimestamp` The order expiration time. Conditional — required when `<59>` TimeInForce is `6` (GTD), must not be present otherwise. **`60 TransactTime`** `UTCTimestamp` The time of order creation. Required. ```text title="Limit order example (Client → B2TRADER)" 8=FIX.4.4^9=168^35=D^34=3^52=20231220-09:15:30.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order001^55=spot.btc_usdt^54=1^38=0.5^40=2^44=42500.00^59=1^60=20231220-09:15:30.000^10=123^ ``` ```text title="Market order example (Client → B2TRADER)" 8=FIX.4.4^9=155^35=D^34=4^52=20231220-09:16:00.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order002^55=spot.btc_usdt^54=2^38=0.1^40=1^59=3^60=20231220-09:16:00.000^10=045^ ``` ## Execution Report (8) [#execution-report-8] This message is sent by the server to confirm order status changes, including acknowledgment of new orders, fills, partial fills, cancellations, and rejections. For details on order statuses, see [Order statuses](../get-started/order-statuses). **`37 OrderID`** `String` The server-assigned unique order identifier. Required. **`11 ClOrdID`** `String` The client-assigned order identifier from the original New Order Single. Required. **`17 ExecID`** `String` The unique execution identifier. Present for trade executions. **`150 ExecType`** `char` The type of execution being reported. Required. Possible values: * `0` — New: order has been accepted * `4` — Canceled: order has been canceled by the server (e.g., IOC order partially filled, GTD order expired, or market settings changed) * `8` — Rejected: order has been rejected * `F` — Trade: order has been partially or fully filled **`39 OrdStatus`** `char` The current order status. Required. Possible values: * `0` — New * `1` — Partially filled * `2` — Filled * `4` — Canceled * `8` — Rejected **`1 Account`** `String` The account identifier. Required. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`44 Price`** `Price` The order price. Present for Limit orders. **`6 AvgPx`** `Price` The average price of all fills on this order. Required. **`14 CumQty`** `Qty` The total filled quantity. Required. **`151 LeavesQty`** `Qty` The remaining quantity to be filled. Required. Set to `0` for Canceled or Rejected orders. **`31 LastPx`** `Price` The price of the last fill. Present when `<150>` ExecType is `F` (Trade). **`32 LastQty`** `Qty` The quantity of the last fill. Present when `<150>` ExecType is `F` (Trade). **`15 Currency`** `String` The quote asset identifier. Optional. **`60 TransactTime`** `UTCTimestamp` The transaction time. Required. **`64 SettlDate`** `String` The settlement date in `YYYYMMDD` format. Required. **`58 Text`** `String` Additional information, such as the rejection reason. Optional. ```text title="New order accepted (B2TRADER → Client)" 8=FIX.4.4^9=220^35=8^34=5^52=20231220-09:15:30.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^150=0^39=0^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=0^14=0^151=0.5^60=20231220-09:15:30.100^64=20231220^10=087^ ``` ```text title="Trade execution (B2TRADER → Client)" 8=FIX.4.4^9=245^35=8^34=6^52=20231220-09:15:30.200^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^17=01HBXK5V3R8NQ7YR^150=F^39=2^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=42500.00^14=0.5^151=0^31=42500.00^32=0.5^15=usdt^60=20231220-09:15:30.200^64=20231220^10=154^ ``` ```text title="Order rejected (B2TRADER → Client)" 8=FIX.4.4^9=214^35=8^34=7^52=20231220-09:16:00.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YS^11=order002^150=8^39=8^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=2^40=1^6=0^14=0^151=0^58=Insufficient balance^60=20231220-09:16:00.100^64=20231220^10=201^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard session-level Reject or Execution Report rejection. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=100^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=006^ ``` Each trading account has an `accountStatus` field that determines which operations are permitted on the account. The field is returned on account objects by the API, such as in [Get accounts](../rest-api/settings). An account can be assigned one of the following statuses: * **Active**: All operations are permitted, including placing, modifying, and canceling orders, opening and closing positions, deposits, and withdrawals. * **Halted**: Trader-initiated trading is blocked. Requests to place, modify, or cancel orders and to open or close positions are rejected. Deposits and withdrawals remain allowed. Managed trading through the Management API (MAM, B2COPY) continues to work. * **Frozen**: All operations are blocked. Trading, deposits, and withdrawals are unavailable, and the account is view-only. Stop-out liquidation still executes as a safety mechanism. * **Archived**: The account is decommissioned and hidden from all user-facing surfaces. Real-time profit and loss, equity, margin level, and funding settlement continue for all statuses. Archived accounts are never returned in the trading API account list. They are excluded server-side, so an account that changes to *Archived* stops appearing in [Get accounts](../rest-api/settings) responses. A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. ## Introduction [#introduction] B2TRADER provides developers with three distinct methods for data delivery, each optimized for specific use cases and performance requirements: REST, WebSocket, and FIX APIs. The **REST API** provides read access to market data as well as both read and write access to trading operations. It serves as the foundation for synchronous data operations where immediate confirmation and guaranteed delivery are essential. The **WebSocket API** provides access to public market data streaming as well as private account updates. It delivers real-time updates with low latency, making it ideal for live trading environments. The **FIX API** provides direct access to market data and trading via the FIX 4.4 protocol. It is designed for institutional clients and algorithmic trading systems that require standardized, low-latency connectivity using the industry-standard Financial Information eXchange protocol. This approach provides developers with flexible options for building robust, scalable trading applications that can handle both operational requirements and real-time market dynamics. ### When to use REST API [#when-to-use-rest-api] * **Account configuration and settings**: Managing user preferences and system configurations. * **Order placement and modification**: Creating, updating, and canceling trading orders. * **Historical data retrieval**: Accessing past trading records and market data. * **One-time data requests**: Retrieving specific information that doesn't require continuous updates. * **Administrative operations**: Account management and system administration tasks. ### When to use WebSocket API [#when-to-use-websocket-api] * **Real-time price monitoring**: Live market price feeds and ticker updates. * **Live position tracking**: Continuous monitoring of open and closed positions. * **Order book visualization**: Real-time depth of market data. * **Market data feeds**: Streaming market statistics and trading activity. * **Account balance monitoring**: Live updates of account equity and margin status. ### When to use FIX API [#when-to-use-fix-api] * **Institutional connectivity**: Standardized FIX 4.4 protocol for professional trading infrastructure. * **Algorithmic trading**: Low-latency order execution and market data for automated strategies. * **Market data streaming**: Real-time order book snapshots and incremental updates via FIX protocol. * **Multi-venue integration**: Unified FIX connectivity for systems already integrated with other FIX-based venues. ## General considerations [#general-considerations] The following applies to all interface descriptions provided in this documentation: * **Endpoints**: All endpoints are relative and resolved based on a specified hostname (indicated as `{host}`). * **Authentication**: REST and WebSocket APIs require an access token (see [Authentication](#authentication)). The FIX API uses in-band authentication via the Logon message with Username, Password, and Account fields provided by B2TRADER. * **Data format**: REST and WebSocket APIs return results in JSON format. The FIX API uses the standard FIX 4.4 message format. * **Security**: All communications use secure protocols (HTTPS for REST, WSS for WebSocket, encrypted TCP for FIX). ### Authentication [#authentication] API access requires an access token for both REST and WebSocket connections. Authentication follows a two-step process: 1. Generate an offline token in the Trading terminal. 2. Exchange the offline token for an access token via API call. #### Token types [#token-types] **Offline token** * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time * **Purpose**: Generate access tokens **Access token** * **Type**: Bearer token * **Validity**: 60 minutes * **Purpose**: Authorize API requests ### Generate offline token [#generate-offline-token] To generate an offline token: 1. In the Trading terminal, open **Settings** and select **API token management**. 2. Click **+ Create new**. 3. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 4. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ### Obtain access token [#obtain-access-token] Request an access token using your offline token. **Endpoint**: `POST` `/frontoffice/api/v4/access-token` **Request body**: ```json { "token": "{YOUR_OFFLINE_TOKEN}" } ``` **Response** (Success): ```json { "accessToken": "{YOUR_ACCESS_TOKEN}", "expiresIn": 3600, "tokenType": "Bearer" } ``` **`accessToken`** `string` The access token for API authorization. **`expiresIn`** `integer` The token lifetime, in seconds. **`tokenType`** `string` The authentication type, always `"Bearer"`. ### Using access tokens [#using-access-tokens] Include the access token in API requests: ```http title="REST" Authorization: Bearer {YOUR_ACCESS_TOKEN} ``` ```http title="WebSocket" {URL}?access_token={YOUR_ACCESS_TOKEN} ``` Access tokens must be refreshed before expiration by repeating the Step 2 with your offline token. ## REST API: Synchronous data operations [#rest-api-synchronous-data-operations] The REST API serves as the foundation for synchronous data operations within the B2TRADER platform. This approach follows standard HTTP protocols and is ideal for operations requiring immediate confirmation and guaranteed delivery. ### Key characteristics [#key-characteristics] * **Request-response operations** where immediate confirmation is required. * **Account management** including settings and configuration. * **Order placement and modification** with guaranteed delivery. * **Historical data retrieval** for analysis and reporting. * **Stateless operations** that don't require persistent connections. ### HTTP response codes [#http-response-codes] B2TRADER API uses conventional HTTP response codes to indicate the success or failure of requests. **Success codes:** * `200 OK` — Request successful **Error codes:** * `400 Bad Request` — Invalid request parameters * `401 Unauthorized` — Authentication required * `403 Forbidden` — Insufficient permissions * `404 Not Found` — Resource not found * `429 Too Many Requests` — [Rate limit](#rate-limits) exceeded * `500 Internal Server Error` — Server error In case of an error, an object will be returned with the following structure: ```json { "code": "text", "message": "text", "details": { "source": "text", "message": "text", "stackTrace": "text" } } ``` ### Available endpoints [#available-endpoints] * **[Trading operations](../rest-api/trading)**: Create, modify, and cancel orders; open, close, and modify positions; control price trigger settings. * **[Trading history](../rest-api/history)**: Retrieve detailed execution records for positions and orders. * **[Settings and configurations](../rest-api/settings)**: Access account information, market specifications, trading sessions, and asset details. ### Rate limits [#rate-limits] Rate limits are applied per minute for each unique **AccountId** to ensure fair resource usage and maintain optimal API performance. All limits use the **Fixed Window** strategy. When rate limits are exceeded, the API returns a `429 Too Many Requests` HTTP status code. #### Trading methods [#trading-methods] * **Default limit**: 600 requests per minute for all methods. * **Reduced limit (200 rpm)** applies to: * Get order data methods * Bulk close positions method * Price triggers methods #### History methods [#history-methods] * **All request types**: 60 requests per minute. #### Settings methods [#settings-methods] * **GET requests**: 100 requests per minute. * **POST and DELETE requests**: 60 requests per minute. Rate limits are calculated independently for each method category. For example, you can make 100 GET requests to Settings methods and 60 requests to History methods within the same minute without hitting rate limits. ## WebSocket API: Real-time data streaming [#websocket-api-real-time-data-streaming] The WebSocket API delivers real-time updates with minimal latency, essential for modern trading applications. The implementation uses unidirectional communication from server to client, ensuring efficient data delivery. ### Key characteristics [#key-characteristics-1] * **Unidirectional communication** from server to client for optimal performance. * **Real-time market data** for live trading environments. * **Position and order updates** as they occur in real-time. * **Low-latency data delivery** for time-sensitive trading operations. * **Persistent connections** maintaining continuous data flow. ### SignalR implementation [#signalr-implementation] B2TRADER utilizes **AspNetCore SignalR** for WebSocket message organization and transmission, providing a robust and scalable real-time communication framework. **Resources:** * [Official GitHub Repository](https://github.com/dotnet/aspnetcore/tree/main/src/SignalR) * [Official Documentation](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr) SignalR provides a structured approach to real-time communication through standardized message formatting and connection management. ### Connection lifecycle [#connection-lifecycle] The data transfer process consists of two essential phases: 1. **Connection establishment** — Initial handshake, authentication, and subscription setup. 2. **Data streaming** — Continuous real-time data flow with automatic reconnection handling. ### Message types [#message-types] SignalR utilizes numerical `type` indicators for different operations: ### Available stream types [#available-stream-types] * **[Trading streams](../ws-api/trading)**: Track active orders, open and closed positions. * **[Market data streams](../ws-api/market-data)**: Get real-time order book updates, market statistics and price changes. * **[Account information streams](../ws-api/account-info)**: Get live account balance and margin updates. ## FIX API: Standardized protocol connectivity [#fix-api-standardized-protocol-connectivity] The FIX API provides direct access to B2TRADER via the FIX 4.4 protocol, the industry standard for electronic trading communication. It is designed for institutional clients and algorithmic trading systems. ### Key characteristics [#key-characteristics-2] * **FIX 4.4 protocol** for standardized, vendor-neutral connectivity. * **Dedicated sessions** for Market Data and Trading with separate endpoints. * **In-band authentication** via Logon message (Username, Password, Account). * **Real-time market data** with order book snapshots and incremental updates. * **Session management** with Heartbeat, Test Request, and Sequence Reset support. ### Authentication [#authentication-1] Unlike REST and WebSocket APIs, the FIX API does not use access tokens. Authentication is performed in-band as part of the FIX Logon message using credentials provided by B2TRADER: * **Username** (`<553>`): The client username * **Password** (`<554>`): The client password * **Account** (`<1>`): The account identifier ### Available session types [#available-session-types] * **[Market Data](../fix-api/market-data)**: Subscribe to real-time order book updates, snapshots, and incremental refreshes. * **[Trading](../fix-api/trading)**: Place orders and receive execution reports in real time. ## Integration best practices [#integration-best-practices] ### API selection strategy [#api-selection-strategy] * Use **REST API** for operational tasks requiring confirmation (order placement, account management). * Use **WebSocket API** for real-time monitoring and market data visualization. * Use **FIX API** for institutional connectivity, algorithmic trading, and integration with existing FIX-based infrastructure. * Implement multiple APIs in comprehensive trading applications for optimal functionality. ### Performance optimization [#performance-optimization] * Implement proper connection pooling for REST API requests. * Use WebSocket subscriptions efficiently by subscribing only to required data streams. * Handle reconnection logic for WebSocket connections to ensure data continuity. * Implement appropriate error handling and retry mechanisms. ### Security considerations [#security-considerations] * Store authentication tokens securely and implement token refresh mechanisms. * Use secure connections (HTTPS/WSS) for all API communications. * Implement proper input validation and sanitization. * Monitor API usage and implement rate limiting on the client side. This comprehensive API architecture enables developers to build sophisticated trading applications that can handle both real-time market dynamics and operational trading requirements efficiently. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all Limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the platform, without taking into account the time settings of the devices from which the platform is accessed. ## Get full balance [#get-full-balance] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"FullBalance"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "FullBalance", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of balance objects. **`item.assetId`** `string` The asset identifier. **`item.available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`item.total`** `decimal string` The overall amount of the asset, including locked funds. **`item.locked`** `decimal string` The asset amount locked on the account for execution of all placed Limit orders. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "assetId": "eur", "available": "497838.8", "total": "497838.8", "locked": "0" } ] } ``` ## Get margin data [#get-margin-data] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"MarginData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "MarginData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.marginBalanceInRAT`** `decimal string` The total amount of funds that can be used as a collateral for trading, in RAT. This value is calculated as SUM (*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*) Where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the BP root asset. **`item.creditInRAT`** `decimal string` The promotional trading credit granted to the account by the broker, in RAT. Credit is included in the account equity but excluded from the withdrawable amount. During a rolling deployment, older payloads might omit this field. In that case, default it to `0`. **`item.unrealizedPnlInRAT`** `decimal string` The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) **`item.equityInRAT`** `decimal string` The potential balance if all open positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. **`item.usedMarginInRAT`** `decimal string` The amount of funds that is used for maintaining all open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **`item.freeMarginInRAT`** `decimal string` The amount of funds that can be used for opening new positions. **`item.marginLevel`** `decimal string` The ratio of funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "marginBalanceInRAT": "497838.8", "creditInRAT": "0", "unrealizedPnlInRAT": "-5.25", "equityInRAT": "497833.55", "usedMarginInRAT": "100.18", "freeMarginInRAT": "497733.37", "marginLevel": "4969.3905" } } ``` ## Get order book [#get-order-book] ### Connection [#connection] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Book"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eur_chf" ], "invocationId": "0", "target": "Book", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.askTotalAmount`** `string` The total ask amount. **`item.bidTotalAmount`** `string` The total bid amount. **`item.asks`** `array of objects` The array of ask price objects. **`item.asks.price`** `string` The price, in the quote asset. **`item.asks.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.asks.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.bids`** `array of objects` The array of bid price objects. **`item.bids.price`** `string` The price, in the quote asset. **`item.bids.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.bids.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.version`** `string` The order book version. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eur_chf", "askTotalAmount": "18700000", "bidTotalAmount": "19100000", "asks": [ { "price": "0.93677", "amount": "5000000", "total": "4683850" }, { "price": "0.93676", "amount": "0", "total": "0" }, { "price": "0.93676", "amount": "0", "total": "0" } ], "bids": [ { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93655", "amount": "5000000", "total": "4682750" } ], "version": "12498", "snapshot": false } } ``` ## Get trading data [#get-trading-data] ### Connection [#connection-1] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"TradingData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.bnb_btc" ] ], "invocationId": "0", "target": "TradingData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.markets.displayName`** `string` The market ticker. **`item.markets.fullName`** `string` The market full name or description (optional). **`item.markets.price`** `decimal string` The current top-of-the-book price, in the quote asset. **`item.markets.priceInRAT`** `decimal string` The current top-of-the-book price, in conversion to the root asset of the platform. **`item.markets.priceChange24hr`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.markets.priceChangeAbs24hr`** `decimal string` The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. **`item.markets.highPrice24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.markets.lowPrice24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.markets.markPrice`** `decimal string` *Applicable to Perpetual markets only.* The mid-spread price, in conversion to RAT. **`item.markets.fundingRate`** `decimal string` *Applicable to Perpetual markets only.* The current funding rate. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "cfd.eur_chf", "type": "Cfd", "displayName": "cfd.eur_chf", "fullName": "", "price": "0.93586", "priceInRAT": "1", "priceChange24hr": "-0.0006", "priceChangeAbs24hr": "-0.00049", "highPrice24hr": "0.93695", "lowPrice24hr": "0.93134", "markPrice": null, "fundingRate": null } ], "snapshot": false } } ``` ## Get top of the book [#get-top-of-the-book] ### Connection [#connection-2] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Tob"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.eth_usdt" ] ], "invocationId": "0", "target": "Tob", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.ask`** `decimal string` The top-of-the-book ask price. **`item.markets.bid`** `decimal string` The top-of-the-book bid price. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "spot.eth_usdt", "ask": "2483.82", "bid": "2483.81" } ], "snapshot": false } } ``` ## Get trading chart [#get-trading-chart] ### Connection [#connection-3] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` and `timescale` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Chart"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eth_eur@15m" ], "invocationId": "0", "target": "Chart", "type": 4 } ``` *** ### Message [#message-3] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.low`** `decimal string` The lowest base asset price within the specified time interval. **`item.high`** `decimal string` The highest base asset price within the specified time interval. **`item.open`** `decimal string` The base asset price at the beginning of the specified time interval. **`item.close`** `decimal string` The base asset price at the end of the specified time interval. **`item.start`** `dateTime` The beginning of the specified time interval, in ISO 8601 format. **`item.end`** `dateTime` The end of the specified time interval, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eth_eur", "low": "2240.88", "high": "2270.29", "open": "2265.63", "close": "2255.99", "start": "2025-05-21T15:30:00Z", "end": "2025-05-21T15:45:00Z" } } ``` ## Get market summary [#get-market-summary] ### Connection [#connection-4] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Summary"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "cfd.eur_chf" ] ], "invocationId": "0", "target": "Summary", "type": 4 } ``` *** ### Message [#message-4] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.items`** `array of objects` The array of data objects. **`item.items.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.items.last`** `decimal string` The price of the last trade. **`item.items.high24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.items.low24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.items.percentChange`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "items": [ { "marketId": "cfd.eur_chf", "last": "0.93597", "high24hr": "0.93695", "low24hr": "0.93134", "percentChange": "-0.02" } ], "snapshot": false } } ``` ## Get open orders [#get-open-orders] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenOrders", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of market objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.status`** `string` The current [order status](../get-started/order-statuses). Possible values: * `Started` * `Pending` * `Working` **`item.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`item.reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`item.remainingAmount`** `decimal string` The order amount that hasn't yet been filled, in the base asset. **`item.requestedPrice`** `decimal string` The limit price for Limit orders; `null` for Market orders. **`item.executionPrice`** `decimal string` The volume-weighted average price of the order executions. **`item.createdAt`** `dateTime` The timestamp when the order was created, in ISO 8601 format. **`item.updatedAt`** `dateTime` The timestamp of the most recent update to the order, in ISO 8601 format. **`item.cancellationDate`** `dateTime` The timestamp when the order was cancelled or expired, in ISO 8601 format; `null` if not cancelled. **`item.commissionAssetId`** `string` The currency in which the commission was held. **`item.commissionAmount`** `decimal string` The total commissions put on hold for executing the order. **`item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when placing the order. **`item.fillFactor`** `decimal string` The proportion of the order amount filled so far, where `1` represents 100% fulfillment. **`item.comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.stopLoss`** `decimal string` The Stop Loss price, if set. ```json { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "orderId": "01JVQBFSTVC40VK03A0AY7K016", "timeInForce": "Gtc", "status": "Pending", "source": "Manual", "reason": "Trader", "side": "Buy", "orderType": "Limit", "requestedAmount": "10000", "remainingAmount": "10000", "requestedPrice": "0.9", "executionPrice": "0", "createdAt": "2025-05-20T17:22:31.899Z", "updatedAt": "2025-05-20T17:22:31.9001213Z", "cancellationDate": null, "commissionAssetId": "eur", "commissionAmount": "0", "leverage": 1, "fillFactor": "0", "takeProfit": null, "stopLoss": null, "comment": null } ] } ``` ## Get open positions [#get-open-positions] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenPositions"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenPositions", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.item`** `array of objects` The array of position objects. **`item.item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.item.marketDisplayName`** `string` The market ticker. **`item.item.marketFullName`** `string` The market full name or description (optional). **`item.item.createdAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. **`item.item.updatedAt`** `dateTime` The timestamp of the most recent update to the position, in ISO 8601 format. **`item.item.side`** `string` The position side. Possible values: * `Buy` * `Sell` **`item.item.status`** `string` The current position status. Always `"Open"`. **`item.item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when opening the position. **`item.item.positionLotAmount`** `decimal string` The position volume, in lots. **`item.item.positionPriceInRAT`** `decimal string` The current position price, in conversion to RAT. **`item.item.rateToRAT`** `decimal string` The current exchange rate of a quote asset to RAT. **`item.item.usedMarginInRAT`** `decimal string` The amount of trader’s funds used for maintaining a position, in conversion to RAT. **`item.item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.item.currentMarketPrice`** `decimal string` The current market price of the base asset: bid for Long positions and ask for Short positions. **`item.item.unrealizedPnlDayInRAT`** `decimal string` The potential profit or loss earned for a current day, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. **`item.item.unrealizedPnlDayPercent`** `decimal string` The potential profit or loss earned for a current day, in percents. **`item.item.unrealizedPnlTotalInRAT`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). **`item.item.unrealizedPnlTotalPercent`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT, in percents. **`item.item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.item.stopLoss`** `decimal string` The Stop Loss price, if set. **`item.item.positionModifier`** `string` The reason for the latest position update. **`item.item.comment`** `string | nullable` The text note inherited from the opening order, up to 100 characters. **`snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "item": [ { "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-03-12T06:36:31.257Z", "updatedAt": "2025-03-12T06:36:31.257Z", "side": "Buy", "status": "Open", "leverage": 1, "positionLotAmount": "0.01", "positionPriceInRAT": "1000.46", "rateToRAT": "1.07", "usedMarginInRAT": "1000.53", "openPrice": "0.96304", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "1.86", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-29.93", "unrealizedPnlTotalPercent": "-0.0291", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null }, { "positionId": "01JVQB9ZWJ6G4QV0P98X0QWNA7", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-05-20T17:19:21.49Z", "updatedAt": "2025-05-20T17:19:21.491321Z", "side": "Buy", "status": "Open", "leverage": 100, "positionLotAmount": "0.1", "positionPriceInRAT": "10004.6", "rateToRAT": "1.07", "usedMarginInRAT": "100.06", "openPrice": "0.93666", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "18.61", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-17.02", "unrealizedPnlTotalPercent": "-0.0017", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null } ], "snapshot": false } } ``` ## Get closed positions [#get-closed-positions] ### Connection [#connection-2] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"ClosePositionsOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "ClosePositionsOrders", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of position objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.positionCloseLotAmount`** `decimal string` The closed volume, in lots, which is equivalent to the corresponding filled order volume. **`item.reason`** `string` The reason for position closing. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.realizedPnlInRAT`** `decimal string` The actual profit or loss earned, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). **`item.closedAt`** `dateTime` The timestamp when the position was closed, in ISO 8601 format. **`item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`item.positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`item.rateToRAT`** `decimal string` The conversion rate to RAT. **`item.openedAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketFullName": "", "marketDisplayName": "EUR/CHF", "marketType": "Cfd", "orderId": "01JVSQ8WFA3QZ6AQTKYPXVXDWA", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.01", "reason": "Trader", "realizedPnlInRAT": "-29.25", "closedAt": "2025-05-21T15:26:57.0027785Z", "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "openPrice": "0.96304", "closePrice": "0.93571", "positionPriceInRAT": "1001.2", "rateToRAT": "1.07", "openedAt": "2025-03-12T06:36:31.257Z" } ] } ``` ## Open positions [#open-positions] ### Get executions for an open position [#get-executions-for-an-open-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/executions/list` #### Summary [#summary] Use this method to retrieve execution details for a specific open position using its position identifier. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`positionId`** `required` The position identifier. ##### Body [#body] **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`offset`** `integer · int32 | nullable` The number of items to skip before starting to collect the result set. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PMT0VMJG5B8XBDNZ7FNM1F/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "offset": 0 } ``` #### Response [#response] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VNWB23GSRN2XQAJD6Q", "baseAmount": "0.314", "executionPrice": "4603.5", "commissionAmountInRAT": "0", "commissions": [], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VN1F2JPM14AEV6V8YJ", "baseAmount": "0.045", "executionPrice": "4603.49", "commissionAmountInRAT": "0", "commissions": [], "comment": null } ] } ``` ### Get executions for open positions [#get-executions-for-open-positions] `POST` `/frontoffice/api/v4/positions/executions/list` #### Summary [#summary-1] Use this method to retrieve execution details for multiple open positions by providing an array of position identifiers. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`positionIds`** `array · string[]` The array of position identifiers. **`limit`** `integer · int32 | nullable` The maximum number of items to return. ```http title="Request example" POST /frontoffice/api/v4/positions/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "positionIds": [ "01K2PMT0VMJG5B8XBDNZ7FNM1F", "01K2PMXY63HESK110WT1CHMAFA" ], "limit": 5 } ``` #### Response [#response-1] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMXY63HESK110WT1CHMAFA", "orderId": "01K2PMXY1894RC6E2BYFR00T87", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:38:10.627Z", "executionId": "01K2PMXY63NXM30VNWPDECSFJR", "baseAmount": "15", "executionPrice": "4333.69288", "commissionAmountInRAT": "32.27", "commissions": [ { "assetId": "eur", "amount": "32.27" } ], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.292Z", "executionId": "01K2PMT0VMPCZW0JB2C9J6B405", "baseAmount": "0.141", "executionPrice": "4602.3", "commissionAmountInRAT": "5", "commissions": [ { "assetId": "eur", "amount": "5" } ], "comment": null } ] } ``` ## Closed positions [#closed-positions] ### Get orders for closed positions [#get-orders-for-closed-positions] `POST` `/frontoffice/api/v4/orders/closed-positions` #### Summary [#summary-2] Use this method to retrieve orders associated with closed positions within specified date ranges and market filters. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`createdAtFrom`** `string · date-time | nullable` The start date of the period when the positions were opened. **`createdAtTo`** `string · date-time | nullable` The end date of the period when the positions were opened. **`closedAtFrom`** `string · date-time | nullable` The start date of the period when the positions were closed. **`closedAtTo`** `string · date-time | nullable` The end date of the period when the positions were closed. **`marketId`** `string | nullable` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`marketType`** `string | nullable` The market type. Possible values: * `Cfd` * `Perp` **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastOrderId`** `string | nullable` The identifier of the final order to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/closed-positions HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "createdAtFrom": "2025-08-01T12:00:32.886Z", "createdAtTo": "2025-08-15T12:00:32.886Z" } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier. **`marketFullName`** `string | nullable` The market full name or description (optional). **`marketDisplayName`** `string | nullable` The market ticker. **`marketType`** `string` The market type. Possible values: * `Cfd` * `Perp` **`orderId`** `string` The order identifier. **`orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`timeInForce`** `string` The [time-in-force setting](../get-started/time-in-force) of the order. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`side`** `string` The order side. Possible values: * `Buy` * `Sell` **`positionCloseLotAmount`** `decimal string` The position amount closed by the order, in lots. **`reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`closedAt`** `string · date-time | nullable` The date and time when the position was closed. **`positionId`** `string` The position identifier. **`openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`rateToRAT`** `decimal string` The conversion rate to RAT. **`openedAt`** `string · date-time` The date and time when the position was opened. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "data": [ { "marketId": "cfd.eth_eur", "marketFullName": null, "marketDisplayName": "CFD ETH/EUR", "marketType": "Cfd", "orderId": "01K2PNGX50SR1FRE6P14PJC17E", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "15", "reason": "Trader", "realizedPnlInRAT": "-144.64", "closedAt": "2025-08-15T10:48:32.393Z", "positionId": "01K2PMXY63HESK110WT1CHMAFA", "openPrice": "4333.69288", "closePrice": "3370.58389", "positionPriceInRAT": "50558.75", "rateToRAT": "1", "openedAt": "2025-08-15T10:38:10.628Z", "comment": null }, { "marketId": "perp.eth_usdt", "marketFullName": "ETH/USDT_4s8hKqiPXmXOEhsO1J6W", "marketDisplayName": "ETH/USDT_jC6Im5PxwgZLrwyccRcI", "marketType": "Perpetual", "orderId": "01K2PNG3N6NKAJVV4RV5E2V0HK", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.5", "reason": "Trader", "realizedPnlInRAT": "13.42", "closedAt": "2025-08-15T10:48:06.234Z", "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "openPrice": "4603.1607", "closePrice": "4634.3915", "positionPriceInRAT": "1992.78", "rateToRAT": "0.86", "openedAt": "2025-08-15T10:36:02.293Z", "comment": null } ], "isExceeded": true } ``` ### Get executions for a closing order [#get-executions-for-a-closing-order] `POST` `/frontoffice/api/v5/orders/``{orderId}``/executions/list` #### Summary [#summary-3] Use this method to retrieve execution details for a specific position-closing order using its identifier. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The order identifier. ##### Body [#body-3] **`positionId`** `string | nullable` The position identifier. **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastExecutionId`** `string | nullable` The identifier of the final execution to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/01K2PNG3N6NKAJVV4RV5E2V0HK/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 5 } ``` #### Response [#response-3] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed amount of the base asset. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T19:02:22.196Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true } ], "isExceeded": true } ``` ### Get executions for closing orders [#get-executions-for-closing-orders] `POST` `/frontoffice/api/v5/orders/executions/list` #### Summary [#summary-4] Use this method to retrieve execution details for multiple position-closing orders by providing an array of order identifiers. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`orderId`** `string` The order identifier. **`positionId`** `string` The order identifier. ```http title="Request example" POST /frontoffice/api/v4/orders/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "orderPositionPairs": [ { "orderId": "01K31APDKZCVGWZA3XTF5JPAMD", "positionId": "01K31APDWF2EBHRKHH15VGB1ST" } ], "limit": 0 } ``` #### Response [#response-4] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T18:53:15.657Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true, "comment": null } ], "isExceeded": true } ``` ## Accounts [#accounts] ### Get accounts [#get-accounts] `GET` `/frontoffice/api/v3/accounts` #### Summary [#summary] Use this method to retrieve a list of all trading accounts with their basic information including account type and total balance. #### Request [#request] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/accounts HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response] In case of success, an array of objects will be returned. Each object contains the following information: **`accountId`** `string` The trading account identifier. **`publicAccountId`** `integer` The public account identifier for display purposes. **`accountName`** `string` The account name. **`accountType`** `string` The account type. Possible values: * `Hedging` * `Netting` **`accountStatus`** `string` The account status, which determines the permitted operations. For a description of each value, see [Account statuses](../get-started/account-statuses). Possible values: * `Active` * `Halted` * `Frozen` **`totalBalanceInRAT`** `decimal string` The total balance, in RAT. **`isCopyTradingAccount`** `boolean` Indicates if the account is `Copy`. ```json title="Response example — 200: OK" [ { "accountId": "685a7eaa360f9e7416221a61", "publicAccountId": 1234567, "accountName": "B2TRADER Hedging account", "accountType": "Hedging", "accountStatus": "Active", "totalBalanceInRAT": "6020.12", "isCopyTradingAccount": false }, { "accountId": "6891e70db552ff9c6fbbccf5", "publicAccountId": 1234568, "accountName": "B2TRADER Netting account", "accountType": "Netting", "accountStatus": "Halted", "totalBalanceInRAT": "10987.39", "isCopyTradingAccount": false } ] ``` ## Assets [#assets] ### Get assets [#get-assets] `GET` `/frontoffice/api/v3/assets` #### Summary [#summary-1] Use this method to retrieve a list of available assets on the platform. #### Request [#request-1] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-1] In case of success, an array of objects will be returned. Each object contains the following information: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`isRootAsset`** `boolean` Indicates whether this is a root asset. ```json title="Response example — 200: OK" [ { "assetId": "usdt", "assetName": "Tether", "isRootAsset": true }, { "assetId": "xrp", "assetName": "Ripple", "isRootAsset": false } ] ``` ## Markets [#markets] ### Get markets [#get-markets] `GET` `/frontoffice/api/v6/markets` #### Summary [#summary-2] Use this method to retrieve a list of available markets with their type, subtype, and favorite status. #### Request [#request-2] ##### Query parameters [#query-parameters] **`categoryId`** The market category identifier. **`dynamicCommissionGroupId`** The dynamic commission group identifier. **`isFavorite`** `boolean` Filter by favorite status. If set to `true`, only markets marked as favorites are returned. ```http title="Request example" GET /frontoffice/api/v6/markets?isFavorite=true HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} ``` #### Response [#response-2] In case of success, an array of market objects is returned. Each market object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description. **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" [ { "marketId": "spot.btc_usdt", "displayName": "BTC/USDT", "fullName": null, "type": "Spot", "subtype": null, "isFavorite": true }, { "marketId": "cfd.eth_btc", "displayName": "ETH/BTC", "fullName": "Ethereum to Bitcoin", "type": "Cfd", "subtype": "Crypto", "isFavorite": false }, { "marketId": "perp.trx_usdt", "displayName": "TRX/USDT", "fullName": "TRX to Tether Perpetual", "type": "Perpetual", "subtype": null, "isFavorite": false } ] ``` ### Get market [#get-market] `GET` `/frontoffice/api/v6/markets/``{marketId}` #### Summary [#summary-3] Use this method to retrieve detailed information about a specific market using its market identifier. #### Request [#request-3] ##### Path parameters [#path-parameters] **`marketId`** `required` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```http title="Request example" GET /frontoffice/api/v6/markets/{marketId} HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description (optional). **`baseAssetId`** `string` The base asset identifier. **`quoteAssetId`** `string` The quote asset identifier. **`minAmount`** `decimal string | nullable` *Applicable to Spot markets only.* The minimum tradable amount of the base asset. **`maxBaseAmount`** `decimal string | nullable` The maximum tradable amount of the base asset. **`priceDeviation`** `decimal string` The allowed price deviation for Limit orders placed on the market. Supports decimal values in the range `[0, 1]`, with up to 4 decimal places, for example: * `0.1` = 10% * `0.01` = 1% * `0.001` = 0.1% * `0.0001` = 0.01% If set to `0`, no restriction is applied, the price deviation is ignored. **`priceScale`** `integer` The price precision, which is the number of digits after a decimal separator. Also determines the minimum allowed trade price. Supports only integer values in the range `[2, 8]`. For example, `2` means the following price format: `0.01`, and `8`: `0.00000001`. **`amountScale`** `integer | nullable` *Applicable to Spot markets only.* The amount precision, which is the number of digits after a decimal separator. Also determines the minimum trade amount. Supports only integer values in the range `[0, 8]`. For example: * `0` means `1` (no digits after the decimal separator) * `5` means `0.00001` (five digits after the decimal separator) * `8` means `0.00000001` (eight digits after the decimal separator) **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`swapSettings`** `object | nullable` *Applicable to CFD markets only.* The fee type charged for holding open positions overnight. The amount can be negative for rebates. Possible values: * `FixPerLot`: The fixed amount per lot. * `Percent`: The fixed amount in points which is applied to the position size, in the range `[-1, 1]`, with up to 5 decimal places. * `Points`: The fixed amount of percents which is applied to the position size, with up to 3 decimal places. Structure: * **`type`** `string` — Swap calculation type. Possible values: `FixPerLot`, `Percent`, `Points`. * **`shortPositionSettings`** `object` — Settings for Short positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` * **`longPositionSettings`** `object` — Settings for Long positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` **`lotSize`** `integer | nullable` *Not applicable to Spot markets.* The standardized quantity of the base asset per lot. Supports only integer values in the range `[1, 1000000]`. **`minLotAmount`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum order amount, in lots, that can be placed and executed. Supports values in the range `[0.00000001, 1]`. **`maxLotAmount`** `integer | nullable` *Not applicable to Spot markets.* The maximum order amount, in lots, that can be placed and executed. Supports only integer values in the range `[1, 10000]`. **`tickSize`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum price increment. **`lotStep`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum lot amount increment. Supports values in the range `[0.00000001, 1]`. By default, equals to the `minLotAmount`. **`slippageRate`** `decimal string` The expected slippage, that is, the difference between the expected execution price and the actual one. This value is used as a multiplier to calculate the funds to be put on hold for a market order execution. Supports values in the range `[1, 10]`, including decimal values with up to 4 decimal places. The default value is `1` which means that only the current bid/ask price is put on hold. For example, `1.1` means that the current bid or ask price + 10% is put on hold for each order, to cover the 10% slippage. **Mind that** the total amount funds to be held depends on the order parameters and takes into account many conditions, the slippage rate is only one of them. **`calendar`** `object` The trading calendar defining market trading hours. Structure: * **`timeZoneId`** `string` — IANA time zone identifier. * **`tradingSessions`** `array` — Weekly trading sessions: * **`dayOfWeek`** `string` — One of: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. * **`timeIntervals`** `array` — List of intervals with: * **`start`** `string` (time) — Start time in `calendar.timeZoneId`. * **`end`** `string` (time) — End time in `calendar.timeZoneId`. * **`sessionOverrides`** `array` — Optional specific-date overrides: * **`date`** `string` (date) — In `YYYY-MM-DD` format. * **`timeIntervals`** `array | nullable` — Intervals for that date. **`fundingStartTime`** `string | nullable` *Applicable to Perpetual markets only.* The time of the first funding settlement, in the following format: `HH:MM:SS`. **`fundingIntervalInHours`** `integer | nullable` *Applicable to Perpetual markets only.* The funding settlement interval, in hours. Possible values: 1, 2, 3, 4, 6, 8, 12, 24. **`leverageProfile`** `object` *Not applicable to Spot markets.* The leverage profile. Structure: * **`leverageType`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`leverage`** `object` * **`useOnlyMaxLeverage`** `boolean` * **`maxLeverage`** `integer` — For `Fixed` leverage type only. * **`tiers`** `array` — For `Dynamic` leverage type only. * **`maxLeverage`** `integer` — The maximum allowed leverage for this tier. * **`maxNotionalValueInRAT`** `string | nullable` — The maximum position notional for this tier. **`commissionSettings`** `object` The commission settings. Structure: * **`type`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`charge`** `object` * **`type`** `string` — Possible values: `Percent`, `FixPerLot`. * **`assetId`** `string | nullable` — For `Fixed` commission type only. * **`size`** `decimal string` — For `Fixed` commission type only. * **`tiers`** `array` — For `Dynamic` commission type only. * **`size`** `string` — The commission amount for this tier. * **`minTradingVolumeInRAT`** `string` — The minimum required trading volume for this tier. * **`minCommissionInRAT`** `decimal string | nullable` * **`dynamicCommissionGroupId`** **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" { "marketId": "string", "displayName": "string", "fullName": "string", "baseAssetId": "string", "quoteAssetId": "string", "minAmount": "string", "maxBaseAmount": "string", "minQuoteAmount": "string", "priceDeviation": "string", "priceScale": 0, "amountScale": 0, "type": "Spot", "subtype": "Cash", "swapSettings": { "type": "FixPerLot", "shortPositionSettings": { "size": "string", "assetId": "string" }, "longPositionSettings": { "size": "string", "assetId": "string" } }, "lotSize": 0, "minLotAmount": "string", "maxLotAmount": 0, "tickSize": "string", "lotStep": "string", "slippageRate": "string", "calendar": { "timeZoneId": "string", "tradingSessions": [ { "dayOfWeek": "Monday", "timeIntervals": [ { "start": "string", "end": "string" } ] } ], "sessionOverrides": [ { "date": "2025-12-18", "timeIntervals": [ { "start": "string", "end": "string" } ] } ] }, "fundingStartTime": "string", "fundingIntervalInHours": 0, "leverageProfile": { "leverageType": "Fixed", "leverage": { "useOnlyMaxLeverage": true, "maxLeverage": 0 } }, "commissionSettings": { "type": "Dynamic", "сharge": { "type": "Percent", "tiers": [ { "size": "string", "minTradingVolumeInRAT": "string" }, { "size": "string", "minTradingVolumeInRAT": "string" } ], "minCommissionInRAT": "string" }, "dynamicCommissionGroupId": "string" }, "isFavorite": true } ``` *** ### Add favorite market [#add-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/add` #### Summary [#summary-4] Add a market to the current user's favorites list. #### Request [#request-4] ##### Body [#body] **`marketId`** `string` `required` The market identifier to add to favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/add HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-4] In case of success (`200`), an empty object is returned. *** ### Remove favorite market [#remove-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/delete` #### Summary [#summary-5] Remove a market from the current user's favorites list. #### Request [#request-5] ##### Body [#body-1] **`marketId`** `string` `required` The market identifier to remove from favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/delete HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-5] In case of success (`200`), an empty object is returned. ## Account margin settings [#account-margin-settings] ### Get margin assets [#get-margin-assets] `GET` `/frontoffice/api/v4/account-margin-settings/assets` #### Summary [#summary-6] Use this method to retrieve a list of assets that can be used as collateral for margin trading. #### Request [#request-6] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v4/account-margin-settings/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`assets`** `array` A list of assets that can be used as a collateral for margin trading. Each array item contains: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`total`** `decimal string` The overall amount of the asset, including locked funds. **`marginRatio`** `decimal string` The percentage of the asset value used as a collateral. Supports values in the range `[0, 1]`, where `1` represents 100.00%. **`isSelected`** `boolean` Indicates whether the asset is selected to be used as collateral. Can be `true` only for assets with the `marginRatio` more than `0`. ```json title="Response example — 200: OK" { "assets": [ { "assetId": "btc", "assetName": "btc", "available": "0.031", "total": "0.031", "marginRatio": "1", "isSelected": true }, { "assetId": "eth", "assetName": "eth", "available": "0", "total": "0", "marginRatio": "1", "isSelected": false } ] } ``` ### Select margin asset [#select-margin-asset] `POST` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-7] Use this method to enable a particular asset to be used as collateral for margin trading. Only assets with the `marginRatio` more than `0` can be selected. #### Request [#request-7] ##### Path parameters [#path-parameters-1] **`assetId`** `required` The asset identifier. ```http title="Request example" POST /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json Accept: */* {} ``` #### Response [#response-7] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ### Disable margin asset [#disable-margin-asset] `DELETE` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-8] Use this method to prohibit a specific asset from being used as collateral for margin trading. #### Request [#request-8] ##### Path parameters [#path-parameters-2] **`assetId`** `required` The asset identifier. ```http title="Request example" DELETE /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-8] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ## Info [#info] ### Get server info [#get-server-info] `GET` `/frontoffice/api/v3/info` #### Summary [#summary-9] Use this method to retrieve current server time and timezone information. #### Request [#request-9] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`serverTime`** `string` The server time, in the Unix timestamp format. **`serverTimeZone`** `string` The server time zone. ```json title="Response example — 200: OK" { "serverTime": "1755190380", "serverTimeZone": "+00:00" } ``` ### Get server time zones [#get-server-time-zones] `GET` `/frontoffice/api/v3/info/time-zones` #### Summary [#summary-10] Use this method to retrieve available server time zones. #### Request [#request-10] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info/time-zones HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-10] In case of success, an array of objects will be returned. Each object contains the following information: **`id`** `string` The time zone identifier. **`offset`** `string` The UTC offset, in the following format: `HH:MM:SS`. **`offsetInMinutes`** `integer · int32` The UTC offset in minutes. **`shortLabel`** `string` The short label for the time zone. **`label`** `string` The display label for the time zone. ```json title="Response example — 200: OK" [ { "id": "Africa/Abidjan", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Abidjan", "label": "(UTC+00:00) Côte d’Ivoire Time" }, { "id": "Africa/Algiers", "offset": "01:00:00", "offsetInMinutes": 60, "shortLabel": "Africa/Algiers", "label": "(UTC+01:00) Central European Time (Algiers)" }, { "id": "Africa/Bissau", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Bissau", "label": "(UTC+00:00) Guinea-Bissau Time" }, ... ] ``` ## Webhooks [#webhooks] ### Create webhook API key [#create-webhook-api-key] `POST` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-11] Create a new webhook API key for receiving TradingView alerts. #### Request [#request-11] ##### Header parameters [#header-parameters] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Body [#body-2] **`name`** `string` `required` A descriptive name for the API key, up to 100 characters. ```http title="Request example" POST /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "name": "My TradingView Key" } ``` #### Response [#response-11] In case of success (`201`), the created API key object is returned. **`id`** `string` The unique identifier of the API key. **`apiKey`** `string` The full API key value. The key is shown only once at creation. **`name`** `string` The name assigned to the key. **`userId`** `string` The user identifier the key is bound to. **`status`** `string` The key status: `Active`. **`createdAt`** `string` The timestamp when the key was created. **`expiresAt`** `string` The timestamp when the key expires (one year from creation). ```json title="Response example" { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "apiKey": "wh_key_abc123def456...", "name": "My TradingView Key", "userId": "01JZ3CVZKN20410JPYYH1YZJSK", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ``` The API key is shown only once in the creation response. It can't be retrieved again after this call. *** ### List webhook API keys [#list-webhook-api-keys] `GET` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-12] Retrieve all webhook API keys for the authenticated user along with the webhook URL. #### Request [#request-12] ##### Header parameters [#header-parameters-1] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ```http title="Request example" GET /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-12] In case of success (`200`), the webhook URL and a list of API keys are returned. **`webhookUrl`** `string` The webhook URL to configure in TradingView alerts. **`apiKeys`** `array of objects` The list of API keys. **`apiKeys[].id`** `string` The unique identifier of the API key. **`apiKeys[].name`** `string` The name assigned to the key. **`apiKeys[].status`** `string` The key status. Possible values: * `Active` * `Revoked` * `Expired` **`apiKeys[].createdAt`** `string` The timestamp when the key was created. **`apiKeys[].expiresAt`** `string` The timestamp when the key expires. ```json title="Response example" { "webhookUrl": "https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3...", "apiKeys": [ { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "name": "My TradingView Key", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ] } ``` *** ### Revoke webhook API key [#revoke-webhook-api-key] `DELETE` `/frontoffice/api/v3/webhook/api-keys/{id}` #### Summary [#summary-13] Revoke an active webhook API key. After revocation, the key can no longer be used to authenticate webhook requests. #### Request [#request-13] ##### Header parameters [#header-parameters-2] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Path parameters [#path-parameters-3] **`id`** `string` `required` The unique identifier of the API key to revoke. ```http title="Request example" DELETE /frontoffice/api/v3/webhook/api-keys/01JZ3CVZKN20410JPYYH1YZJSK HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-13] In case of success (`200`), a confirmation object is returned. **`success`** `boolean` Indicates whether the key was revoked successfully. **`message`** `string` A description of the result. ```json title="Response example" { "success": true, "message": "API key revoked successfully" } ``` *** ### Receive TradingView alert [#receive-tradingview-alert] `POST` `/frontoffice/api/v3/webhook/alerts/{userId}` #### Summary [#summary-14] Accept a webhook alert from TradingView and place an order on the specified trading account. TradingView calls this endpoint when an alert triggers. #### Request [#request-14] ##### Path parameters [#path-parameters-4] **`userId`** `string` `required` The B2TRADER user identifier (ULID format). ##### Body [#body-3] **`apiKey`** `string` `required` The webhook API key for authentication. **`accountId`** `string` `required` The trading account identifier. **`symbol`** `string` `required` The market symbol with a type prefix (`spot.`, `cfd.`, or `perp.`) followed by the pair name. For example: `spot.btc_usdt`, `cfd.eur_usd`, `perp.btc_usdt`. **`side`** `string` `required` The order side. Possible values: * `buy` * `sell` **`quantity`** `decimal string` `required` The order quantity in the base asset. **`orderType`** `string` The order type. Default: `market`. Possible values: * `market` * `limit` * `stop` * `stop_limit` **`price`** `decimal string` The limit price. Required for `limit` and `stop_limit` orders. **`stopPrice`** `decimal string` The stop price. Required for `stop` and `stop_limit` orders. **`leverage`** `decimal string` The leverage ratio. Applicable to CFD and Perpetual Futures markets only. **`takeProfit`** `decimal string` The take profit trigger price. **`stopLoss`** `decimal string` The stop loss trigger price. **`timeInForce`** `string` The time-in-force policy. Default: `gtc`. Possible values: * `gtc` * `ioc` * `fok` * `day` **`comment`** `string` A custom comment, up to 256 characters. **`deduplicationId`** `string` A UUID for idempotency. Duplicate requests with the same ID within five minutes return a cached response. ```http title="Request example" POST /frontoffice/api/v3/webhook/alerts/01JZ3CVZKN... HTTP/1.1 Host: {host} Content-Type: application/json { "apiKey": "wh_key_abc123def456...", "accountId": "01JZ3CVZKN20410JPYYH1YZJSK", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01", "comment": "TV Strategy Signal" } ``` #### Response [#response-14] In case of success (`200`), an order confirmation is returned. **`success`** `boolean` Indicates whether the order was placed successfully. **`orderId`** `string` The unique identifier of the created order. **`orderStatus`** `string` The initial status of the order. **`message`** `string` A description of the result. **`timestamp`** `string` The timestamp of the response. ```json title="Response example" { "success": true, "orderId": "01JZ3CVZKN20410JPYYH1YZJSK", "orderStatus": "Working", "message": "Order placed successfully", "timestamp": "2026-02-02T12:34:56.789Z" } ``` #### Rate limits [#rate-limits] Webhook requests are limited to five requests per second per user. If the limit is exceeded, the response returns a `429` status code with the following headers: * `X-RateLimit-Limit`: Maximum requests per window * `X-RateLimit-Remaining`: Remaining requests in the current window * `X-RateLimit-Reset`: Unix timestamp when the window resets ## Orders [#orders] ### Place SPOT order [#place-spot-order] `POST` `/frontoffice/api/v3/orders` #### Summary [#summary] Use this method to create and submit a new order for SPOT markets. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Body [#body] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Limit", "timeInForce": "Gtc", "requestedAmount": 0.02, "requestedPrice": 115193.35, "comment": "Strategy A" } } ``` #### Response [#response] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. Right after the order is created commission is `0`. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K1ZTB4DB0S6Y2NH81S781BQX", "orderType": "Limit", "side": "Buy", "status": "Pending", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.02", "remainingAmount": "0.02", "requestedPrice": "115193.35", "executionPrice": "0", "createdAt": "2025-08-06T13:50:13.931Z", "updatedAt": "2025-08-06T13:50:13.9325008Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Place CFD order [#place-cfd-order] `POST` `/frontoffice/api/cfd/v4/orders` #### Summary [#summary-1] Use this method to create and submit a new order for CFD markets. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "timeInForce": "Gtd", "requestedLotAmount": 1, "requestedPrice": 3280, "leverage": 75, "cancellationDate": "2025-08-10T00:00:00Z", "stopLoss": { "price": 3320, "isTrailing": false }, "takeProfit": { "price": 3200 }, "comment": "Strategy A" } } ``` #### Response [#response-1] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2253Q9X3VTJ68PNWY40JC6Q", "status": "Pending" } } ``` ### Place PF order [#place-pf-order] `POST` `/frontoffice/api/perpetual/v4/orders` #### Summary [#summary-2] Use this method to create and submit a new order for Perpetual markets. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `perp.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "perp.eth_usdt", "side": "Buy", "orderType": "Market", "timeInForce": "Ioc", "requestedLotAmount": 10, "leverage": 159, "comment": "Strategy A" } } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K228VN55N7WFZRG70M24T9J1", "status": "Working" } } ``` ### Cancel order [#cancel-order] `DELETE` `/frontoffice/api/v3/orders/``{orderId}` #### Summary [#summary-3] Use this method to cancel an active order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`orderId`** `required` The order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/orders/01K2PF9XS29WN4JZRHMCTTQYJB HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` * `StopOrder` * `FixApi` * `System` **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.eth_usdt", "marketDisplayName": "SPOT ETH/USDT", "orderId": "01K2PF9XS29WN4JZRHMCTTQYJB", "orderType": "Limit", "side": "Buy", "status": "Cancelled", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.1", "remainingAmount": "0.1", "requestedPrice": "4450", "executionPrice": "0", "createdAt": "2025-08-15T08:59:51.97Z", "updatedAt": "2025-08-15T09:00:06.2791048Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Get SPOT order data [#get-spot-order-data] `POST` `/frontoffice/api/v3/order-data` #### Summary [#summary-4] Use this method to retrieve and validate order data for SPOT market orders before placing. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-3] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.requestedBaseAmount`** `decimal string | nullable` The requested amount in base asset units. **`order.requestedQuoteAmount`** `decimal string | nullable` The requested amount in quote asset units. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. ```http title="Request example" POST /frontoffice/api/v3/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=3.0 Accept: */* { "order": { "marketId": "spot.eth_usdt", "side": "Buy", "orderType": "Limit", "requestedBaseAmount": 0.2, "requestedPrice": 4600 } } ``` #### Response [#response-4] In case of success, an object will be returned. Each object contains the following information: **`baseAmount`** `decimal string` The calculated base asset amount for the order. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmount`** `decimal string` The estimated commission amount to be charged. **`total`** `decimal string` The total quote asset amount, including the estimated commission. ```json title="Response example — 200: OK" { "order": { "baseAmount": "0.2", "quoteAmount": "920", "commissionAmount": "9.2", "total": "929.2" } } ``` ### Get CFD order data [#get-cfd-order-data] `POST` `/frontoffice/api/cfd/v4/order-data` #### Summary [#summary-5] Use this method to retrieve and validate order data for CFD market orders before placing. #### Request [#request-5] ##### Header parameters [#header-parameters-5] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables the Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/cfd/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": 15000, "triggerType": "points" }, "stopLoss": { "triggerSize": "4020", "triggerType": "price", "isTrailing": false }, "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Market", "leverage": 135, "requestedLotAmount": 1 } } ``` #### Response [#response-5] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "34.4613643", "quoteAmount": "4004.345", "commissionAmountInRAT": "0", "marginLevel": "5.3015", "takeProfit": { "price": "3989.345", "rate": "0.0037", "points": 15000, "pnl": "17.42713545" }, "stopLoss": { "price": "4020", "rate": "-0.0039", "points": -15655, "pnl": "-18.18812036" } } } ``` ### Get PF order data [#get-pf-order-data] `POST` `/frontoffice/api/perpetual/v4/order-data` #### Summary [#summary-6] Use this method to retrieve and validate order data for Perpetual market orders before placing. #### Request [#request-6] ##### Header parameters [#header-parameters-6] **`accountId`** `required` The trading account identifier. ##### Body [#body-5] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/perpetual/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": "0.01", "triggerType": "rate" }, "stopLoss": { "triggerSize": "-100", "triggerType": "pnl", "isTrailing": false }, "marketId": "perp.btc_usdt", "side": "Buy", "orderType": "Limit", "leverage": 100, "requestedLotAmount": 0.5, "requestedPrice": 118450 } } ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "592.25", "quoteAmount": "59225", "commissionAmountInRAT": "0", "marginLevel": "0.3582", "takeProfit": { "price": "119634.5", "rate": "0.01", "points": 11845, "pnl": "592.25" }, "stopLoss": { "price": "118250", "rate": "-0.0016", "points": -2000, "pnl": "-100" } } } ``` ## Stop orders [#stop-orders] ### Place SPOT Stop order [#place-spot-stop-order] `POST` `/frontoffice/api/v3/stop-orders` #### Summary [#summary-7] Use this method to create and submit a new Stop order for SPOT markets. #### Request [#request-7] ##### Header parameters [#header-parameters-7] **`accountId`** `required` The trading account identifier. ##### Body [#body-6] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Market", "activationPrice": 128000, "requestedAmount": 0.01, "timeInForce": "Ioc", "comment": "Strategy A" } } ``` #### Response [#response-7] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order, same as in the request. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K2MNC3BVR5WRTBEE9YWAS91K", "orderType": "Market", "side": "Buy", "requestedPrice": "0", "activationPrice": "128000", "requestedAmount": "0.01", "timeInForce": "Ioc", "status": "WaitingForActivation", "createdAt": "2025-08-14T16:07:25.8193038Z", "updatedAt": "2025-08-14T16:07:25.8193044Z", "cancellationDate": null, "comment": null } } ``` ### Place CFD Stop order [#place-cfd-stop-order] `POST` `/frontoffice/api/cfd/v4/stop-orders` #### Summary [#summary-8] Use this method to create and submit a new Stop order for CFD markets. #### Request [#request-8] ##### Header parameters [#header-parameters-8] **`accountId`** `required` The trading account identifier. ##### Body [#body-7] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "activationPrice": 3200, "requestedLotAmount": 0.5, "timeInForce": "Gtd", "leverage": 76, "requestedPrice": 3500, "cancellationDate": "2025-08-18T00:00:00Z", "stopLoss": { "price": "3900", "isTrailing": false }, "takeProfit": { "price": "3100" }, "comment": "Strategy A" } } ``` #### Response [#response-8] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNRWP2J1S8T9TKTCXWYY87", "status": "WaitingForActivation" } } ``` ### Place PF Stop order [#place-pf-stop-order] `POST` `/frontoffice/api/perpetual/v4/stop-orders` #### Summary [#summary-9] Use this method to create and submit a new Stop order for Perpetual markets. #### Request [#request-9] ##### Header parameters [#header-parameters-9] **`accountId`** `required` The trading account identifier. ##### Body [#body-8] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "perp.btc_usdt", "side": "Sell", "orderType": "Market", "activationPrice": 115000, "requestedLotAmount": 1, "timeInForce": "Fok", "leverage": 22, "stopLoss": { "price": "118020", "isTrailing": true }, "takeProfit": { "price": "113873" }, "comment": "Strategy A" } } ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNM0S8B2R9DS7BWJ8PGYPR", "status": "WaitingForActivation" } } ``` ### Cancel Stop order [#cancel-stop-order] `DELETE` `/frontoffice/api/v3/stop-orders/``{orderId}` #### Summary [#summary-10] Use this method to cancel an active Stop order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-10] ##### Header parameters [#header-parameters-10] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The Stop order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/stop-orders/01K2MNGAWPMQJ7WGATFSCAS1G4 HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-10] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. ```json title="Response example — 200: OK" { "order": { "marketId": "perp.btc_usdt", "marketDisplayName": "Perpetual BTC/USDT", "orderId": "01K2MNGAWPMQJ7WGATFSCAS1G4", "orderType": "Limit", "side": "Sell", "requestedPrice": "115100", "activationPrice": "115000", "requestedAmount": "1", "timeInForce": "Gtc", "status": "Rejected", "createdAt": "2025-08-14T16:09:44.5986099Z", "updatedAt": "2025-08-14T16:09:44.5986103Z", "cancellationDate": null } } ``` ## Positions [#positions] ### Close position [#close-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/close` #### Summary [#summary-11] Use this method to close a specific position entirely or partially. #### Request [#request-11] ##### Header parameters [#header-parameters-11] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-2] **`positionId`** `required` The position identifier to close. ##### Body [#body-9] **`closePositionLotAmount`** `decimal string | nullable` The portion of the position to close, in lots. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PFXDP1FWCJSGTX4GJ6JHM0/close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-11] In case of success, an object will be returned. Each object contains the following information: **`positionId`** `string` The position identifier. ```json title="Response example — 200: OK" { "positionId": "01K2PFXDP1FWCJSGTX4GJ6JHM0" } ``` ### Bulk close positions [#bulk-close-positions] `POST` `/frontoffice/api/v4/positions/bulk-close` #### Summary [#summary-12] Use this method to close multiple positions simultaneously based on different criteria such as all positions, positive PnL only, or negative PnL only. #### Request [#request-12] ##### Header parameters [#header-parameters-12] **`accountId`** `required` The trading account identifier. ##### Body [#body-10] **`mode`** `string` `required` The bulk close mode. Possible values: * `AllPositions` — close all positions. * `PositivePnl` — close only positions with positive PnL. * `NegativePnl` — close only positions with negative PnL. ```http title="Request example" POST /frontoffice/api/v4/positions/bulk-close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "mode": "AllPositions" } ``` #### Response [#response-12] In case of success, an object will be returned containing identifiers of closed positions. ```json title="Response example — 200: OK" { "status": "accepted", "positionIds": [ "01K228VNC2Q7E7K9W8GABWBZ5Z", "01K22BZ2DCETJZKW6MK81N1T8Y", "01K2CXF06A3A5SK2YFJT67CMZ5", "01K2CXF2ZJ6MJYMEK663TBBY8K", "01K2PFXDP1FWCJSGTX4GJ6JHM0" ] } ``` ### Get trigger data [#get-trigger-data] `POST` `/frontoffice/api/v4/positions/``{positionId}``/trigger-data` #### Summary [#summary-13] Use this method to retrieve Stop loss and Take profit settings for an open position. #### Request [#request-13] ##### Header parameters [#header-parameters-13] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-3] **`positionId`** `required` The position identifier. ##### Body [#body-11] **`stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`stopLoss.isTrailing`** `boolean | nullable` Indicates if Stop loss is Trailing. **`takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/trigger-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "triggerSize": "-0.01", "triggerType": "rate", "isTrailing": true }, "takeProfit": { "triggerSize": 2500, "triggerType": "points" } } ``` #### Response [#response-13] In case of success, an object will be returned. Each object contains the following information: **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "takeProfit": { "price": "248.27", "rate": "0.1119", "points": 2500, "pnl": "21.5" }, "stopLoss": { "price": "221.04", "rate": "-0.01", "points": -223, "pnl": "-1.91" } } ``` ### Submit triggers [#submit-triggers] `PUT` `/frontoffice/api/v4/positions/``{positionId}``/triggers` #### Summary [#summary-14] Use this method to modify Stop loss and Take profit settings for an open position. #### Request [#request-14] ##### Header parameters [#header-parameters-14] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-4] **`positionId`** `required` The position identifier. ##### Body [#body-12] **`stopLoss.price`** `decimal string` The Stop loss trigger price. **`stopLoss.isTrailing`** `boolean` If `true`, enables the Trailing behavior for Stop loss. **`takeProfit.price`** `decimal string` The Take profit trigger price. ```http title="Request example" PUT /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/triggers HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "price": "165.13", "isTrailing": true }, "takeProfit": { "price": 250 } } ``` #### Response [#response-14] In case of success, an object will be returned containing the identifier of the updated position. ```json title="Response example — 200: OK" { "positionId": "01K2HYXA7N2G9NHTFEWYVM9SEQ" } ``` ## Commissions [#commissions] ### Get account trading volume [#get-account-trading-volume] `GET` `/frontoffice/api/v3/commission/``{dynamicCommissionGroupId}``/account-trading-volume` #### Summary [#summary-15] Use this method to obtain a cumulative account trading volume used for calculating the commission tier. #### Request [#request-15] ##### Header parameters [#header-parameters-15] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-5] **`dynamicCommissionGroupId`** `required` The dynamic commission group identifier. Use [Get market](settings#get-market) to obtain. ```http title="Request example" GET /frontoffice/api/v3/commission/{dynamicCommissionGroupId}/account-trading-volume HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-15] In case of success, an object will be returned containing current trading volume, in RAT, for the account. ```json title="Response example — 200: OK" { "currentTradingVolumeInRAT": "string" } ``` You can connect B2Trader to **ChatGPT** as a **connector**. It uses the same B2Trader MCP URL and OAuth sign-in as every other agent. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in ChatGPT's connector directory. Connector availability depends on your ChatGPT plan. ## Connect the B2Trader connector [#connect-the-b2trader-connector] 1. In ChatGPT, open **Settings** → **Connectors**. 2. Choose to add a connector by **URL** (custom connector). 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Confirm. ChatGPT reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — no API key is pasted into ChatGPT. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. ChatGPT lists the connector as connected, and the B2Trader tools become available to it. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — ChatGPT receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and ChatGPT stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector appears as connected in ChatGPT's settings. * B2Trader tools are available to ChatGPT in your chats. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In ChatGPT, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). You can connect B2Trader to **Claude** in two places: * **claude.ai** (web and desktop app) — add B2Trader as a **custom connector**. * **Claude Desktop** — add B2Trader as an MCP server; the OAuth sign-in completes through Claude's hosted redirect (`https://claude.ai/api/mcp/auth_callback`). Both use the same B2Trader MCP URL and the same OAuth sign-in. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in Claude's connector directory. ## Connect on claude.ai [#connect-on-claudeai] 1. Open **Settings** → **Connectors** in claude.ai. 2. Click **Add custom connector**. 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Click **Add**. Claude reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — you are **not** pasting an API key into Claude. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. Claude shows the connector as **Connected**, and the B2Trader tools appear in the tool list for your conversations. ## Connect in Claude Desktop [#connect-in-claude-desktop] 1. Open **Claude Desktop** → **Settings** → **Connectors**. 2. Add a new MCP server pointing at the B2Trader MCP URL for your surface. 3. Claude Desktop opens your browser for OAuth sign-in and completes the flow through Claude's **hosted** redirect (`https://claude.ai/api/mcp/auth_callback`), a pre-registered redirect URI. 4. Sign in and — for full access — approve the consent screen. 5. The B2Trader tools appear in Claude Desktop once the connector reports **Connected**. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — Claude receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and Claude stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector is listed as **Connected** in Claude's settings. * B2Trader tools (for example `trader_get_accounts`, plus platform market-data and portfolio tools) are available to Claude in your conversations. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In Claude, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). If you are building your own agent (for example with an Agent SDK) or using an MCP client that is not Claude or ChatGPT, you connect to the same two B2Trader endpoints and the same OAuth flow. This page covers the OAuth details a custom client needs. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` `` is the domain you open your B2Trader terminal on, not a separate API address. ## OAuth discovery [#oauth-discovery] Your client needs no B2Trader-specific configuration beyond the MCP URL. B2Trader is an OAuth 2.1 protected resource and advertises everything a compliant client needs: 1. Your client calls the MCP endpoint without a token and receives `401 Unauthorized` with a `WWW-Authenticate: Bearer resource_metadata="…"` header. 2. That header points at the protected-resource metadata (RFC 9728) for the surface you called — each surface has its own document: `https:///.well-known/oauth-protected-resource/mcp-read-only` and `https:///.well-known/oauth-protected-resource/mcp-full-access`. Fetching it returns the resource identifier, the authorization server (your broker's Keycloak realm), and `scopes_supported` — one scope only, matching the surface: `[mcp:read]` for `/mcp-read-only`, `[mcp:trade]` for `/mcp-full-access`. 3. Your client runs the standard OAuth 2.1 **authorization-code flow with PKCE** against that authorization server, requesting the scope for the surface you want. 4. B2Trader validates the token's audience (`bbp-mcp`) and the required scope (`mcp:read` for read-only, `mcp:trade` for full access) before serving any tool. Use a compliant MCP client library — it performs discovery, PKCE, and token refresh for you. You only supply the MCP URL. ## Pre-registered OAuth clients [#pre-registered-oauth-clients] B2Trader ships two pre-registered public OAuth clients. Use the one matching your surface: | Surface | `client_id` | Scope | Consent | | ----------- | ----------------- | ----------- | ---------------------------- | | Read-only | `mcp-read-only` | `mcp:read` | None | | Full access | `mcp-full-access` | `mcp:trade` | Explicit trade-scope consent | Both are **public** clients (no client secret) and require **PKCE (S256)**. A custom client authenticates as one of these `client_id`s and completes the browser sign-in as any other agent does. Depending on how your broker set up your platform, the page that opens is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account — your client behaves the same either way. ## Command-line agents (Codex CLI, Claude Code) [#command-line-agents-codex-cli-claude-code] Command-line MCP clients default to **Dynamic Client Registration (DCR)** — on first connect they try to register a brand-new OAuth client with the authorization server instead of using a fixed `client_id`. The B2Trader Keycloak realm does not permit anonymous DCR, so these tools must be told to use one of the pre-registered `client_id`s above: * **Codex CLI:** ```bash codex mcp add --url --oauth-client-id mcp-full-access codex mcp login ``` Use `mcp-read-only` in place of `mcp-full-access` for the read-only surface. * **Claude Code:** ```bash claude mcp add --transport http --client-id mcp-full-access --callback-port 8080 ``` Without an explicit `client_id`, both tools fall back to anonymous DCR, which the authorization server rejects — the connection fails before you reach the sign-in page. ## Redirect URIs [#redirect-uris] The pre-registered clients accept these redirect URIs: | Redirect URI | Use | | ------------------------------------------------------- | ----------------------------------------------------- | | `https://claude.ai/api/mcp/auth_callback` | Claude (claude.ai) | | `https://chatgpt.com/connector_platform_oauth_redirect` | ChatGPT | | `http://localhost:8080/*` | Claude Code — fixed callback port | | `http://127.0.0.1/*` | Codex CLI and other loopback clients — ephemeral port | If your custom agent runs locally, use one of the loopback redirects above. Most Agent SDKs and MCP client libraries (including Codex CLI) default to an ephemeral-port loopback callback on `127.0.0.1`, matching `http://127.0.0.1/*`, so no configuration change is needed. Claude Code is the exception: it needs a **fixed** callback port to match a registered redirect, so pass `--callback-port 8080` (matching `http://localhost:8080/*`) as shown above. ## Adding a custom redirect URI (broker step) [#adding-a-custom-redirect-uri-broker-step] If your agent runs on a hosted callback URL that is **not** one of the above (for example a server-side agent with its own public redirect), your broker must add that redirect URI to the pre-registered client in Keycloak before sign-in will succeed. A redirect URI that is not registered on the client fails at the sign-in step with an "Invalid redirect URI" error from Keycloak. Send your broker the exact callback URL your agent uses and which surface it needs (read-only or full access). Adding a redirect URI is a broker-side change to the MCP client registration. It requires no product change and is the documented path for onboarding custom, non-marketplace agents. ## Full access [#full-access] If your custom agent uses the full-access surface, the same [full-access safety](full-access-safety) rules apply: no per-action confirmation, irreversible actions, and the prompt-injection risk of an autonomous agent. Read that page before granting `mcp:trade`. The full-access surface (`/mcp-full-access`) lets a connected AI agent trade on your account **directly**. This page explains exactly what that means and how to stay in control. Read it before you approve the full-access consent screen. Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. ## No per-action confirmation [#no-per-action-confirmation] The in-terminal **AI Assistant chat** asks you to confirm each trade before it executes. The full-access MCP surface does **not**. Once connected, the agent can place, cancel, and close orders and set price triggers on its own, as fast as it decides to — there is no confirmation dialog and no "are you sure?" step. ## Actions are irreversible [#actions-are-irreversible] Trades execute against the live market. A filled order, a closed position, or a cancelled order **cannot be undone**. If your agent makes a mistake — or is manipulated into one — the market result stands. ## Prompt-injection risk [#prompt-injection-risk] An autonomous agent acts on the text it reads. If your agent processes untrusted content — a web page, an email, a chat message, a document — that content can contain hidden instructions telling the agent to trade against your interest. This is called **prompt injection**. Because the full-access surface has no confirmation gate, a successful injection can move real money before you notice. To reduce the risk: * Prefer the **read-only** surface unless you specifically need the agent to trade. * Only grant full access to agents and workflows you trust and control. * Be cautious about letting a full-access agent read untrusted external content in the same session it can trade. ## How to stop your agent [#how-to-stop-your-agent] You have two independent controls. Use either — or both. 1. **Stop it in the agent (fastest).** Disconnect or remove the B2Trader connector in your agent (Claude, ChatGPT, or your custom client). The agent immediately stops making new calls. 2. **Revoke the grant in B2Trader.** Open your **account console** (your broker's Keycloak account page) → **Applications**, find the connected MCP application, and **revoke** its access. This removes your consent so the agent cannot obtain a new token. There is no broker-side "kill switch" that instantly voids a token already in the agent's hands. A token the agent already holds stays valid until it expires (see [Access tokens are short-lived](#access-tokens-are-short-lived)). Revoking in the account console stops **new** tokens; disconnecting in the agent stops it using the one it has. Do both to be certain. ## You still get execution notifications [#you-still-get-execution-notifications] Every order the agent places, cancels, or closes fires the **same account notifications** you already receive for terminal activity. Your normal notification channels keep working, so a full-access agent cannot act silently — watch them to see what your agent is doing. ## Access tokens are short-lived [#access-tokens-are-short-lived] The agent's access token has a **short lifetime**. If you revoke consent in the account console, the agent can finish using its current token but cannot get a new one once it expires — so a revoked grant fully lapses within the token's short window, without any forced server-side revocation. ## Choosing read-only instead [#choosing-read-only-instead] If you do not need the agent to trade, connect the **read-only** surface (`/mcp-read-only`) instead. Its tools cannot place or change anything — the trading tools are not part of that surface at all. See [Overview](overview) for the comparison. B2Trader can expose your trading account to external AI agents through the **Model Context Protocol (MCP)** — an open standard that lets AI applications such as Claude and ChatGPT call a defined set of tools on your behalf. Once you connect an agent, it can read your market data and portfolio, and — on the full-access surface — place and manage orders directly. This is different from the **in-terminal AI Assistant chat**, which runs inside the B2Trader terminal and confirms each trade with you before it executes. An external MCP agent runs in *its own* application (Claude, ChatGPT, or your own client) and connects to B2Trader over the internet using your account sign-in. Connecting an AI agent is optional — it's your choice whether to use it. The MCP surfaces are available by default, though your broker can restrict or disable them for your platform. The MCP endpoints live on the same domain you use to open your B2Trader terminal, so wherever these pages show `https:///…`, that means your terminal address — not a separate API address. If a connection URL below doesn't work, contact your broker. ## Two surfaces [#two-surfaces] B2Trader publishes **two** separate MCP endpoints. You choose one when you connect your agent. | | Read-only | Full access | | ------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Endpoint path** | `/mcp-read-only` | `/mcp-full-access` | | **What the agent can do** | View market data, your portfolio, order and position history, and analytics | Everything in read-only **plus** place, cancel, and close orders and set price triggers | | **Tools exposed** | 23 | 39 | | **Trading** | None — mutating tools are not present at all | Full trading, with **no per-action confirmation** | | **OAuth scope** | `mcp:read` | `mcp:trade` | | **Consent screen** | No extra consent | Explicit trade-scope consent (see [Full-access safety](full-access-safety)) | | **Marketplace-listed** | Yes | No — connect by URL | The **read-only** surface is the one listed in AI marketplaces (for example the Claude and ChatGPT connector directories). It is safe to connect broadly: the trading tools are **structurally absent** — the agent cannot see or call them. The **full-access** surface is connected by pasting its URL directly. It grants your agent the ability to trade with no confirmation gate. Read [Full-access safety](full-access-safety) before you connect it. ## Tool categories [#tool-categories] Both surfaces expose the same read tools; the full-access surface adds the mutating ones. | Category | Read-only | Full access | | ------------------------------------------------------------------------------ | --------- | ----------- | | Market data — B2Trader platform prices (tickers, order book, market summaries) | Yes | Yes | | Portfolio & account (balances, margin, open positions) | Yes | Yes | | Order & position history | Yes | Yes | | Analytics & reference data | Yes | Yes | | Place / cancel / close orders (single) | No | Yes | | Bulk order / position actions | No | Yes | | Set & edit price triggers, other account mutations | No | Yes | | **Total tools** | **23** | **39** | The 16 tools that the full-access surface adds are the mutating actions: single trading actions, bulk trading actions, and non-trading account mutations. ## Which surface to choose [#which-surface-to-choose] * **Choose read-only** if you want an agent to analyze markets, summarize your portfolio, or answer questions about your trading history. This is the recommended default and the safest option. * **Choose full access** only if you deliberately want your agent to trade for you without confirming each action, and you understand the risks in [Full-access safety](full-access-safety). ## Prerequisites [#prerequisites] Before connecting any agent you need: * A **B2Trader account** on a platform that offers the MCP surfaces. They are available by default; a broker can restrict or disable them. * Your account must be **active** (`bbp.spot.status = Active`) — the same status required to trade in the terminal. A non-active account can sign in, but its tool calls are rejected by the platform. * An AI application that supports MCP with OAuth — for example [Claude](connect-claude), [ChatGPT](connect-chatgpt), or a [custom agent](connect-custom-agent). ## How connecting works [#how-connecting-works] You never paste an API key or password into your agent. Connection uses **OAuth 2.1 with PKCE**: 1. You add the B2Trader MCP URL to your agent. 2. The agent discovers B2Trader's authorization server automatically — it reads the endpoint's protected-resource metadata at `/.well-known/oauth-protected-resource/mcp-read-only` or `/.well-known/oauth-protected-resource/mcp-full-access`, depending on the surface. 3. Your browser opens the sign-in page for your platform, where you sign in with the credentials you normally use. 4. For the full-access surface, you approve an explicit consent screen describing what the agent may do. 5. The agent receives a short-lived access token and is connected. No long-lived secret is stored in the agent. The sign-in page you see depends on how your broker set up your platform: either the B2Trader sign-in form, or the sign-in page of the portal you normally use to access your account, which opens automatically. If you are already signed in there in the same browser, no sign-in prompt appears. The per-client steps are covered in the connection guides: * [Connect Claude](connect-claude) * [Connect ChatGPT](connect-chatgpt) * [Connect a custom agent](connect-custom-agent) * [Full-access safety](full-access-safety) ## Global interface controls [#global-interface-controls] ### Account selection [#account-selection] The **Account select** is located in the topbar and enables you to switch between your trading accounts. Each account shows its type: `H` (Hedging) or `N` (Netting). Once you switch the account, all the widgets automatically adjust to show relevant information for the selected account. Account select #### Account status [#account-status] An account can have a status that limits what you can do with it. When a status applies, a status indicator is shown on the account, and a banner explains the restriction. Account status is managed by your administrator. The following statuses are visible to you: * **Halted**: A banner reads *Account is locked for trading. Contact your administrator.* The trading controls are disabled, but you can still deposit and withdraw funds, and your balances, positions, and history stay visible. * **Frozen**: A banner reads *Account is frozen. Contact your administrator.* The account is view-only. All controls are disabled, while your balances, positions, and history stay visible. To restore trading on an account that is Halted or Frozen, contact your administrator. Archived accounts don't appear in the account list. ### Instrument selection [#instrument-selection] The **Instrument select** is located in the topbar and enables you to switch between various markets and trading pairs. Once you change the market, all the widgets automatically adjust to show relevant information for the selected instrument. Instrument select #### Favorite markets [#favorite-markets] Mark instruments as favorites for quick access. To add or remove a market from favorites, click the **star icon** next to the market name in the instrument selection list. Favorite markets can be accessed in two ways: * **Favorites tab** in the instrument selection panel — filters the list to show only your favorite markets. * **Favorites dropdown** in the topbar — provides quick access to favorite markets from anywhere in the terminal. ### Settings [#settings] Use this control to access interface and system settings. Refer to [Settings](settings) for details. Settings ### Other controls [#other-controls] * **Introduction tour**: Access the interactive platform walkthrough. Introduction tour * **Alerts**: View new system notifications. Unread alerts * **Analytics**: Open the **Account Analytics** view with the **Equity Curve** chart — your account balance and equity dynamics over time (Margin Balance, Equity, Total Equity, Unrealized PnL, Deposits / Withdrawals) for a selected period and granularity. The data updates hourly. Click **Back to Trading** to return to the terminal. Analytics * **Log out**: Log out of the system to securely terminate the session. After that you’re navigated to the Login page. Log out ## Working with widgets [#working-with-widgets] > For more information about available widgets, refer to the **Widgets** section of this guide. ### Add widgets to your workspace [#add-widgets-to-your-workspace] **To add a new widget**: 1. Click the **Add Widget** button. 2. Browse the available widgets. 3. Click any widget to add it to your workspace. Add Widget **To add widgets to existing panels**: 1. Look for the **+** button next to the tabs in a panel's header. 2. Click it to open the widget catalog. 3. Select a widget to add it as a new tab to that panel. Add widget tabs ### Move and position widgets [#move-and-position-widgets] **To move a widget**: 1. Click and hold the **move handle** in the top-right corner of the panel header. 2. Drag it to desired location on the page. 3. Drop it. Move widgets **To rearrange widget tabs within a panel**: 1. Click and hold any widget tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ### Resize widgets [#resize-widgets] **To resize a widget panel**: * **Single edge**: Hover over any edge until you see the resize cursor, then drag. * **Corner resize**: Drag a corner to adjust both width and height simultaneously. * **Precision**: Use edge dragging for fine-tuned sizing. Resize widgets ### Remove widgets and tabs [#remove-widgets-and-tabs] **To remove a tab**: 1. Click the **×** button in the top-right corner of the widget tab. 2. The tab will be removed immediately. 3. When you remove the last tab from a panel, the entire panel disappears. Remove tabs and widget panels ### Link panels to a group [#link-panels-to-a-group] Each panel header has a **Link to group** button — the circle icon **next to the move handle** in the top-right corner. Linking panels to the same colored group keeps them in sync: when you select an instrument in one linked panel, the other panels in the same group switch to it automatically. **To link a panel to a group**: 1. Click the **Link to group** button (next to the move handle) in the panel's top-right corner. 2. Select one of the color groups (Group 1–5). 3. Repeat for other panels, choosing the same group to keep them synchronized. Link to group ### Customize widget content [#customize-widget-content] Certain widgets let you customize which columns to display and their order: Look for the **column settings** button in the widget header. **To customize columns**: 1. Click the **column settings** button. 2. **Show/hide columns**: Check or uncheck boxes (grayed-out columns are required). 3. **Reorder columns**: Drag and drop items in the list. 4. **Reset**: Click *Reset to default* to restore original settings. Configure columns ## Managing workspaces [#managing-workspaces] ### Create new workspaces [#create-new-workspaces] **To create a workspace**: 1. Click the **+** tab next to your existing workspaces. 2. Choose a template: * **Pre-built templates**: Start with common widget combinations. * **Empty**: Build completely from scratch. 3. Enter a name for your workspace. 4. Start customizing. Add a new workspace ### Workspace management [#workspace-management] **To rename or delete a workspace**: 1. Click the menu icon on the workspace tab. 2. Select **Rename** or **Remove**. Workspace menu **To reorder workspaces**: 1. Click and hold any workspace tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ## Market info panel [#market-info-panel] Click the **info icon** next to a market symbol in widgets to view: * Detailed market information. * Trading session schedules. * Leverage details (for CFD and PF markets). * Fee details. * Funding details (for PF markets). Market info ## Pro tips [#pro-tips] ### Efficient layout building [#efficient-layout-building] * Start with a template that is close to your needs, then customize. * Group related widgets in tabs to save screen space. * Use larger panels for charts, smaller ones for order books. ### Layout best practices [#layout-best-practices] * **Save multiple workspaces** for different trading strategies. * **Test your layout** during low-activity periods. * **Keep essential widgets visible** (account info, positions, alerts). Access settings by clicking the **gear icon** in the topbar of the Trading terminal. Settings Settings are organized into tabs: * [Interface](#interface): Configure language, time display, and visual theme. * [Widgets](#widgets): Customize widget display options. * [Action Confirmation](#action-confirmation): Choose which actions require additional confirmation. * [Account margin](#account-margin): Manage collateral assets for margin trading. * [Trading report](#trading-report): Generate comprehensive trading and account reports. * [API token management](#api-token-management): Generate and manage tokens for accessing the Trading API. * [TradingView Webhooks](#tradingview-webhooks): Configure TradingView webhook alerts for automated order execution. ## Interface [#interface] Configure global interface preferences: **Language** Select the interface language from the dropdown menu. **24 hour mode** * Enable: Display time in 24-hour format. * Disable: Display time in 12-hour format with AM/PM. **Dark theme** * Enable: Apply dark color scheme. * Disable: Apply light color scheme. ## Widgets [#widgets] Configure display options for the following widgets. ### Price chart [#price-chart] **Display positions** When enabled, open positions are shown on the chart along with: * Position size and current PnL. * Quick access to edit price triggers and close positions. * Color coding: Long positions (green), Short positions (red). **Display orders and triggers** When enabled, the following orders and triggers are displayed on the chart: * Active Limit and Stop orders with order type, price, and amount. * Stop loss, Take profit, and Trailing stop triggers. * Quick access to edit triggers and cancel orders. * Color coding: Buy orders (green), Sell orders (red). **Display executed orders** When enabled, executed orders are shown on the chart with order type indicators: * Green `B` tag for Buy orders. * Red `S` tag for Sell orders. Clicking `B` or `S` will open details of one or more orders that were executed during the candle interval. **Market quick trade panel** When enabled, a panel is displayed on the chart for placing Market orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. **Limit quick trade panel** When enabled, a panel is displayed on the chart for placing Limit orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. ## Action Confirmation [#action-confirmation] Choose which trading actions require an additional confirmation dialog before execution. **Cancel orders** * Enable: A confirmation dialog is displayed before canceling orders. * Disable: Orders are canceled immediately without confirmation. This setting applies to single and bulk order cancellations from the **Open Orders** widget and the **Price chart**. The confirmation dialog includes a **"Don't ask again"** checkbox. To skip the confirmation for future order cancellations, check this box. **Full Close Positions** * Enable: A confirmation dialog is displayed before closing positions. * Disable: Positions are closed immediately without confirmation. This setting applies to single and bulk position closures from the **Open Positions** widget. **Limit order cross-TOB warning** * Enable: A confirmation dialog is displayed before a Limit order is submitted if its price crosses the current top-of-book — that is, when a Buy price is at or above the best ask, or a Sell price is at or below the best bid. The dialog shows the entered price and the current best bid/ask, and includes a **Do not show this warning again** checkbox. * Disable: Crossing Limit orders are submitted immediately without the warning. The warning is enabled by default. The dialog checkbox and this toggle share the same global setting and stay in sync. The warning is informational only — it does not block the order. If you confirm, the order is submitted with the original price. The warning applies only to standard Limit orders; Stop-limit, Take-profit-limit, IOC, FOK, and other order types are not affected. If best bid or best ask data is unavailable (empty book or disconnected feed), the order is submitted without the warning. ## Account margin [#account-margin] Control which assets can be used as collateral for margin trading. ### Asset list [#asset-list] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance available for trading, calculated as *Total – Halted*, where *Halted* represents funds locked for pending Limit orders. *** **Total** The complete asset balance including locked funds. *** **Margin ratio** The percentage of asset value that can be used as collateral for margin trading. *** **Use as margin** Enable this toggle to use the asset as collateral for margin trading. Configure which assets can be used as collateral for margin trading by toggling the **Use as margin** setting for each asset. Only assets with **Margin ratio** greater than 0 (zero) can be enabled. The platform root asset is enabled by default and can't be disabled. ### Filtering options [#filtering-options] Click the **funnel icon** to configure the asset list display: * **Show/Hide zero balances**: Control visibility of assets with zero balance. By default, hidden. * **Show/Hide assets unused as margin**: Control visibility of assets with disabled margin usage. * **Show/Hide assets with zero margin ratio**: Control visibility of assets that can't be used as collateral. By default, hidden. ## Trading report [#trading-report] Generate comprehensive reports containing: * **Trade history** * Closed positions * Executed orders * Individual trades * **Transfers history** * All account transfers * **Account statistics** * Total balance * Realized PnL * Position swaps * Position funding * Commissions To generate a report: 1. Select a custom period of time (UTC time), or generate a report for your entire account history using the **All data** range. The following timeframe presets have been implemented for your convenience: * **Today** * **Current**: week, month, quarter * **Previous**: week, month, quarter * **All data**. 2. Click **Download**. Once generated, the report will be automatically downloaded to your computer as a zipped CSV file. ## API token management [#api-token-management] Generate tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/): * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time To generate a token: 1. Click **+ Create new**. 2. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 3. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ## TradingView Webhooks [#tradingview-webhooks] Use TradingView Webhooks to automatically execute orders on your trading account based on alerts from TradingView. When a TradingView alert triggers, it sends a webhook request to B2TRADER, which places an order according to the parameters specified in the alert message. This feature supports all market types: Spot, CFD, and Perpetual Futures. ### Set up the webhook [#set-up-the-webhook] #### Step 1: Create a webhook API key [#step-1-create-a-webhook-api-key] To create a webhook API key in the Trading terminal: 1. Click the **gear icon** in the topbar to open Settings. 2. Navigate to the **TradingView Webhooks** tab. 3. Click **+ Create new**. 4. In the popup, fill in a **Name** for the key. 5. Click **Create**. The popup displays the generated API key and the webhook URL. Copy both values and store them securely. The API key is shown only once at creation. It can't be retrieved after closing the popup. The following limits apply: * Maximum 10 active keys per user * Each key is valid for 1 year from creation * Keys can be revoked at any time #### Step 2: Configure the alert in TradingView [#step-2-configure-the-alert-in-tradingview] 1. In TradingView, create a new alert or edit an existing one. 2. In the **Notifications** section, enable **Webhook URL**. 3. Paste the webhook URL copied from the terminal. 4. In the **Message** field, enter the alert body in JSON format (see [Alert message format](#alert-message-format)). 5. Save the alert. When the alert triggers, TradingView sends the message to B2TRADER, and the order is placed automatically. ### Alert message format [#alert-message-format] The alert message is a JSON object with the following fields: | Field | Required | Description | | ----------------- | ----------- | -------------------------------------------------------------------------- | | `apiKey` | Yes | Webhook API key generated in the terminal | | `accountId` | Yes | Trading account ID | | `symbol` | Yes | Market symbol with type prefix (see [Symbol format](#symbol-format)) | | `side` | Yes | Order side: `buy` or `sell` | | `quantity` | Yes | Order quantity in base asset | | `orderType` | No | `market` (default), `limit`, `stop`, or `stop_limit` | | `price` | Conditional | Limit price. Required for `limit` and `stop_limit` orders | | `stopPrice` | Conditional | Stop price. Required for `stop` and `stop_limit` orders | | `leverage` | No | Leverage ratio. Applicable to CFD and Perpetual Futures markets only | | `takeProfit` | No | Take profit trigger price | | `stopLoss` | No | Stop loss trigger price | | `timeInForce` | No | `gtc` (default), `ioc`, `fok`, or `day` | | `comment` | No | Custom comment, up to 256 characters | | `deduplicationId` | No | UUID for idempotency. Duplicates within 5 minutes return a cached response | #### Symbol format [#symbol-format] The symbol must include a market type prefix: | Market type | Prefix | Example | | ----------------- | ------- | --------------- | | Spot | `spot.` | `spot.btc_usdt` | | CFD | `cfd.` | `cfd.eur_usd` | | Perpetual Futures | `perp.` | `perp.btc_usdt` | #### Examples [#examples] **Market buy order (Spot):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01" } ``` **Limit sell order with TP/SL (CFD):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "cfd.eur_usd", "side": "sell", "orderType": "limit", "price": "1.0900", "quantity": "1000", "leverage": "10", "takeProfit": "1.0800", "stopLoss": "1.0950", "timeInForce": "gtc" } ``` ### Manage webhook API keys [#manage-webhook-api-keys] To view or manage your webhook API keys, navigate to **Settings** > **TradingView Webhooks**. The following information is provided about each key: | Column | Description | | ----------- | ----------------------------------------------- | | **Name** | The name assigned to the key at creation | | **Status** | Current key status: Active, Revoked, or Expired | | **Created** | The date and time the key was generated | | **Expires** | The date and time the key expires | To revoke a key, click the **Revoke** button next to the key entry. ### Rate limits [#rate-limits] Webhook requests are limited to 5 requests per second per user. If this limit is exceeded, the request returns a `429` error code and the order isn't placed. ### Troubleshooting [#troubleshooting] The following table describes common error scenarios and their solutions: | Issue | Cause | Solution | | -------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | | `Invalid API key` | The API key is incorrect or wasn't copied in full | Generate a new key and update the TradingView alert | | `API key expired` | The key has passed its 1-year validity period | Generate a new key | | `API key revoked` | The key was manually revoked | Generate a new key | | `Invalid symbol format` | The symbol is missing a market type prefix | Add the prefix: `spot.`, `cfd.`, or `perp.` | | `Price required for limit order` | A `limit` or `stop_limit` order is missing the `price` field | Add the `price` field to the alert message | | `Rate limit exceeded` | More than 5 requests were sent within 1 second | Reduce the alert frequency in TradingView | | `Account not found` | The `accountId` doesn't exist or isn't accessible | Verify the account ID in the terminal | A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to limit and stop limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to limit and stop limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the BP, without taking into account the time settings of the devices from which the BP is accessed. ## iOS v1.35 [#ios-v135] This version includes: * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. Select a time period and granularity level to filter performance data, and switch between accounts using the built-in account selector. * **AI Assistant** A new **AI Assistant** widget provides AI-powered market analysis for each instrument, including trade recommendations, market sentiment, signal drivers, suggested actions, and key metrics. * **Quick order from the chart** You can now place orders directly from the **Price chart** by tapping a price pin. The **Quick Order** panel opens pre-filled at the selected price level for faster order placement. * **Customizable workspace** You can now reorder and show or hide bottom tabs in **Settings**, allowing you to tailor the terminal layout to your trading preferences. * **Adaptive interface by market type** Tabs, **Margin Level**, and perpetual funding indicators are now automatically hidden for accounts that do not have access to the corresponding market types, providing a cleaner and more focused interface. * **Landscape mode for the chart** Tapping the **Expand** button on the **Price chart** now automatically rotates the chart to landscape mode for a wider view. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.34 [#ios-v134] This version includes: * **Drag Take Profit and Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be adjusted by dragging their lines directly on the **Price chart**. Changes are applied to the order immediately, with automatic rollback if an error occurs. * **Demo accounts** Demo trading accounts are now supported, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets appear as chips in the market list and are indicated with an icon in the terminal. * **Credit in margin details** A dedicated **Credit** row has been added to the margin details section, providing visibility into credit amounts allocated to your trading account. * **Comments for orders, positions, and trades** You can now add a comment when placing an order or managing a position. The comment is visible throughout the trading lifecycle — on open orders, open positions, and in trade history. * **Margin Level display** When **Margin Level** data is unavailable, the field now displays "–" instead of 0% for clearer data visibility. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.33 [#ios-v133] This version includes: * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Hide zero balances settings relocated** The **Hide zero balances** toggle has been moved to the **Assets** tab for more intuitive access. * **Improved backend error messages** Backend error messages are now mapped to user-friendly descriptions, providing clearer feedback when issues occur. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.32 [#ios-v132] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Quick cancel button for open orders** The **Open orders** widget now features a quick **Cancel** button on each order card, enabling faster order cancellation directly from the list view. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Redesigned account selection header** The account selection section in the terminal header has been redesigned for improved navigation and a cleaner appearance. * **Updated closed positions design** The **Closed positions** widget has been updated with a refreshed layout for better readability and consistency with other trading widgets. * **Confirmation bottom sheet** Order and position actions now display a confirmation bottom sheet, helping to prevent accidental trades and providing a clearer review step before execution. * **Settings button relocated** The **Settings** button has been moved from the **Price chart** widget to the terminal header for easier access across all views. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.31 [#ios-v131] This version includes: Experience an advanced trading workflow with the introduction of our new **tiered leverage system**, offering dynamic leverage based on position size and enhanced margin visibility. This update also brings improved commission transparency with a dedicated Fees tab, enhanced market info, a new deposit shortcut, and updated screens for tiered commissions. We've also refined formatters to respect your selected app language for a more consistent experience. *** ## iOS v1.30 [#ios-v130] This version includes: * **Notifications widget** A new **Notifications** widget has been implemented providing quick access to system notifications related to price changes, Margin calls, Stop outs, Take profit and Stop loss triggers. * **Closing open positions from the Price chart** Open positions can now be closed directly on the **Price chart** screen ensuring quick reaction to volatile market conditions and efficient trade management. This feature is available if the **Display positions** setting is activated for the Price chart. * **Closing all open positions** The **Open positions** tab now features the **Close all** button that liquidates all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Canceling all active orders** The **Open orders** tab now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * **Trading session status** The **Trading session status** in the **Position details** is now accompanied by an info icon and an explanatory tooltip. * **Automatic horizontal scrolling for tabs** The horizontal auto scroll has been added to tabs. Active tabs are now automatically centered for optimal visibility and better accessibility to all available tabs. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.29 [#ios-v129] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding**/**Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Updated account creation process** When creating a trading account in the app, the **account type** can now be selected: **Hedging** or **Netting**, enabling traders to plan and adjust their trading strategies to maximize profit or reduce risk. Depending on the platform settings, the option may be prefilled or require manual selection. The account type can’t be changed after the account is created. * **Support for Take Profit, Stop Loss, and Trailing Stop** The **Take Profit**, **Stop Loss**, and **Trailing Stop** triggers are now supported in the app for CFD and PF trading. They can be applied to Market, Limit, and Stop orders, as well as to currently open positions. * **Support for price alerts** Price alerts are now fully supported in the app: * Multiple alerts can be added to monitor different price levels for any instrument. * Configure alerts based on a fixed price or a percentage change. * View a list of all configured alerts for each instrument. * Adjust or delete existing alerts as needed. * Triggered alerts are automatically removed to keep the list up to date. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order history widget. * **Admin-managed orders and positions** On the **Open positions**, **Closed positions**, and **Order history** widgets, if BP Admins have managed positions or orders, this is now indicated in the **Reason** field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, mitigate risks, or resolve outstanding positions before account termination. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.28 [#ios-v128] This version includes: * **Performance upgrade** Streamlined top-of-the-book ask and bid prices in the Place Order widget are now received through a dedicated socket for faster obtaining and display. * **Mobile and Web Consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** Placeholders are now displayed for empty fields and widgets for improved UX clarity. * **Internal improvements** Enhanced system logs for better diagnostics. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## Android v2.12.0 [#android-v2120] This version includes: * **AI Assistant** A new **AI Assistant** provides AI-powered market analysis for each market, including trade recommendations, a 12-month price forecast, market sentiment, signal drivers, suggested actions, and key metrics. * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. * **Account status indicators** Account statuses such as **Halted** and **Frozen** are now shown with badges and a warning banner, and the related trading actions are restricted accordingly. * **Quick order from the chart** You can now place orders directly from the **Price chart**, enabling faster reaction to market movements. * **Take Profit / Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be set by dragging their lines directly on the **Price chart**, with support for trailing Stop Loss. * **Cross-price limit order warning** A warning is now displayed before you place a **Limit** order whose price crosses the top of the **Order book**. This warning can be enabled or disabled in **Settings**. * **Customizable trading terminal** You can now customize the trading terminal layout and tab order from the new **Workspace** settings. * **Adaptive interface by market type** Margin- and perpetual-related tabs and indicators are now hidden for accounts with access to **Spot** markets only, providing a cleaner interface tailored to the account type. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.11.0 [#android-v2110] This version includes: * **Comment field in Place Order** An optional **Comment** field has been added to the **Place order** form in **Advanced Mode**. The field supports up to 100 characters and is available for all order types across Spot, CFD, and Perpetual markets. * **Full-screen chart mode** The **Price chart** widget now supports full-screen mode. Tap the **Expand** button to switch to a landscape view for a more detailed chart analysis. * **Credit information in margin details** A **Credit** row has been added to the margin section, providing visibility into credit amounts allocated to trading accounts. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.10.0 [#android-v2100] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Demo accounts** Demo trading accounts are now supported in the app, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets are synchronized between the web and mobile terminals. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Improved market status display** The **Market Closed** label is now automatically removed once live data starts updating, providing a more accurate representation of market availability. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.9.0 [#android-v290] This version includes: This update introduces the new **tiered leverage system**, enhanced fee transparency and fully redesigned Fees tab, quick Deposit/Trade shortcuts on account cards for faster navigation and various UI improvements across the app. *** ## Android v2.8.0 [#android-v280] This version includes: * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.7.0 [#android-v270] This version includes: * **Key position parameters on the TP/SL editing** Key position parameters, such as **Name**, **Side**, **Amount**, **Open price**, **Current price**, and **Leverage** are displayed at the top of the Take Profit/Stop Loss configuration screen to give you immediate, accurate context and reduce input errors. Values are updated in real time. * **Closing positions on the Price chart** You can now close positions directly on the **Price chart** widget, by tapping a position indicator. * **Canceling all active orders** The **Open orders** widget now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Closing all open positions** The **Open positions** widget now features the **Close all** button allowing to liquidate all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Closed position details** The **Order type** and **Time in force** values are now displayed for every closed position to improve trade execution transparency. * **Price chart settings saved** The **Price chart** widget now remembers your preferred timeframe and chart type settings. Each time you open the terminal, it displays the chart with your last selected settings. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.6.0 [#android-v260] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding/Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order History widget. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * Expanded capabilities for account administration and risk management for Brokers have been added. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.5.0 [#android-v250] This version includes: * **Stop Loss and Take Profit on the Price chart widget** * Introduction of Stop-Loss (SL) and Take-Profit (TP) lines on the Price chart for enhanced trading insights. * TP and SL are displayed as color-coded lines with only abbreviations visible. * Tap to view prices on the Y-axis and access deletion options. * **Full support for price alerts in the app** * Alerts can be set for specific price levels. * Alerts can be configured based on either a set price or a percentage change. * A list of configured alerts is available for each instrument. * Options to delete or adjust alerts are provided. * Triggered alerts are automatically removed from the list. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.4.0 [#android-v240] This version includes: * **New mobile features** * Introduction of Take Profit, Stop Loss, and Trailing Stop functionalities in the Mobile app. * Support for Netting accounts in the Mobile app. * **Mobile and Web consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** For order lists, the All/Spot/CFD filter is only displayed when there are both Spot and CFD orders, for improved UX clarity. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## June 10, 2026 [#june-10-2026] ### New features [#new-features] #### Guest mode [#guest-mode] A new **Guest mode** lets you explore the Trading terminal without signing in. As a guest you can browse markets and market categories, follow live price streams and interactive charts, and open the **AI Assistant** widget for market analysis. A dedicated guest workspace is provided, and the [Place order](../widgets/place-order) panel opens in the advanced view by default. A **Sign in** action is always available so you can switch to a full trading session at any time. ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Full account history in Trading reports [#full-account-history-in-trading-reports] You can now generate [Trading reports](../get-started/settings) for your entire account history. The previous **92-day** limit has been removed, and a new **All data** range has been added to the report period selector alongside the existing presets. #### Stop orders during closed market sessions [#stop-orders-during-closed-market-sessions] You can now place **Stop** orders while a market is closed according to its trading schedule. The order is accepted and activates automatically once the market reopens, instead of being rejected at placement. #### More accurate unrealized PnL [#more-accurate-unrealized-pnl] Unrealized PnL is now calculated using the correct order book side for each position direction, improving the accuracy of the PnL shown across your widgets. #### Limit price crossing warning [#limit-price-crossing-warning] When you place a limit order at a price that crosses the current top of book, the terminal now shows a warning, helping you avoid an unintended immediate execution. ## April 9, 2026 [#april-9-2026] ### New features [#new-features-1] #### Trading credit [#trading-credit] Your broker can now grant you **trading credit** — a promotional bonus balance you can use for trading. Credit appears as a separate **Credit Balance** alongside your own funds and becomes available for placing trades immediately upon issuance. You are notified when credit is granted or revoked. Trading credit is a trading-only bonus and cannot be withdrawn as cash, so it is excluded from your withdrawable balance. *** ### Improvements [#improvements-1] #### Fee-aware 100% allocation [#fee-aware-100-allocation] The **100%** button in the [Place order](../widgets/place-order) widget now accounts for commissions and margin requirements when allocating funds, so the calculated amount reflects what is actually available for the trade. #### Faster price updates [#faster-price-updates] The price update frequency in terminal widgets has been increased, providing more responsive market data across your workspace. ## March 18, 2026 [#march-18-2026] ### New features [#new-features-2] #### Webhook API for TradingView alerts [#webhook-api-for-tradingview-alerts] A new **Webhook API** has been added, enabling you to connect **TradingView** alerts to your trading workflow. You can generate and copy authentication tokens directly from the Trading terminal to configure webhook-based alerts in **TradingView**. *** ### Resolved issues [#resolved-issues] There have been no customer-facing issues reported in this release. ## March 3, 2026 [#march-3-2026] ### New features [#new-features-3] #### Long-term trading data history [#long-term-trading-data-history] The three-month limit on trading data history has been removed. You can now access the full history of your orders, positions, and trades without time restrictions, enabling deeper analysis of past trading activity. #### AI Assistant widget [#ai-assistant-widget] A new **AI Assistant** widget is now available in the Trading terminal. The widget provides AI-powered market analysis for the selected instrument, including: * A recommendation gauge displaying a score from **Strong Sell** to **Strong Buy** * A 12-month price forecast with target price and percentage change * A market sentiment bar showing the bullish/bearish ratio * Signal drivers section with technical, on-chain, and sentiment factors * Suggested trading actions and key market metrics The widget can be added to any workspace like other terminal widgets. *** ### Improvements [#improvements-2] #### Updated order cancellation confirmation [#updated-order-cancellation-confirmation] The order cancellation confirmation dialog now includes a **Don't ask again** checkbox when canceling triggers from the **TradingView** chart. This allows you to skip the confirmation step for future trigger cancellations, streamlining the trading workflow. *** ### Resolved issues [#resolved-issues-1] There have been no customer-facing issues reported in this release. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-4] #### Redesigned Market Depth widget [#redesigned-market-depth-widget] The [Market Depth](../widgets/market-depth) widget has been completely redesigned with an updated visual layout. Bid and ask labels are now displayed when hovering over a price level, providing better visibility into the order book at a glance. #### Redesigned widget adding experience [#redesigned-widget-adding-experience] The process of adding widgets to workspaces has been redesigned with a more intuitive and streamlined flow. The new interface makes it easier to customize your trading workspace layout by providing a clearer visual selection of available widgets. #### Order and position comments [#order-and-position-comments] A new **Comment** field has been added to orders, positions, and trades throughout the Trading terminal. You can now attach notes directly to your trading activities, making it easier to annotate trading decisions and keep records of your reasoning. #### Favorites [#favorites] You can now mark instruments as favorites for quick access across the Trading terminal. The [Favorite markets](../get-started/customizing-your-terminal#favorite-markets) feature integrates with the instrument selection panel, making it faster to locate and trade your preferred instruments. #### Multi-language support [#multi-language-support] The Trading terminal now supports additional languages: **Chinese (Simplified)**, **Spanish**, **Portuguese**, **French**, **Turkish**, and **Farsi**. Existing translations have also been updated to reflect the latest interface changes. *** ### Improvements [#improvements-3] #### Updated order calculations [#updated-order-calculations] The **Value** and **Amount** calculation logic has been improved for more accurate order handling: * For **Stop Market** orders, the estimated values are now calculated using updated formulas that align with the actual execution logic. * For **Spot** market orders, the **Slippage Rate** is now correctly applied only to buy orders and has been removed from sell order calculations. * The **Slippage Rate** attribute has been removed from **CFD** and **PF** market forms and information displays, as it is not applicable to these market types. #### Improved TP/SL trigger management [#improved-tpsl-trigger-management] Removing Take Profit and Stop Loss triggers is now easier in the TradingView charting widget. Instead of opening a dialog and unchecking the trigger, you can now click the close button directly on the trigger to remove it immediately. #### Updated default columns [#updated-default-columns] The default columns displayed in the [Open positions](../widgets/open-positions) and [Open orders](../widgets/open-orders) widgets have been updated to show the most relevant information by default, reducing the need for manual customization. #### Account margin value formatting [#account-margin-value-formatting] Account margin values such as **Balance**, **Equity**, **Margin**, and **Free margin** in the [Margin](../widgets/margin) widget are now formatted according to the **Root Asset Scale**. This ensures that numerical precision matches the asset's defined scale, eliminating misleading decimal places. #### Updated Settings experience [#updated-settings-experience] The [Settings](../get-started/settings) experience has been improved: * The **Action Confirmation** section text has been rewritten for clarity. The description now reads: "Choose which actions will require additional confirmation," making the toggle behavior immediately clear. * The **One-click trading** configuration has been updated with improved toggle controls and clearer options for enabling or disabling confirmation dialogs on trading actions. #### Improved order validation [#improved-order-validation] Order validation logic has been updated across the Trading terminal, providing clearer feedback on invalid inputs and reducing errors during order placement and management. #### Workspace tab styling [#workspace-tab-styling] Visual improvements have been applied to workspace tabs: gaps have been added between tabs for better visual separation, tab padding has been corrected, and hovered tabs now display a proper card-style fill matching the updated design system. ## December 19, 2025 [#december-19-2025] ### New features [#new-features-5] #### Volume-based tiered commissions [#volume-based-tiered-commissions] You can now benefit from **volume-based commission tiers** that automatically reduce your trading fees as your monthly volume grows. **Key points**: * **Trade more, pay less**: For markets with tiered fees, your 30‑day trading volume (in the root asset, for example USD) is tracked across all markets included in the same group. As you move into higher tiers, your commission percentage decreases. * **Clear fee overview**: Open [Market info](../get-started/customizing-your-terminal#market-info-panel) and switch to the **Fees** tab to see your **Current volume** for the month, the configured **Min. fee**, and the full **Commission tiers** table with volume ranges and fee %. A check mark highlights the tier you are currently in. * **Grouped volume**: Your traded volume is aggregated across markets to which the dynamic commission is applied. * **No surprises**: Orders on markets without tiered fees continue to use the existing flat commission model. Tiered markets simply adjust your fee according to the tier that matches your current trading volume. #### New settings [#new-settings] The [Settings](../get-started/settings) menu has been enriched with the following configuration options: * **Widgets**: This updated section now provides access to multiple widgets’ display settings. Along with existing [Price chart](../widgets/price-chart), you can now configure: * One-click trading for [Open positions](../widgets/open-positions): When enabled, single and bulk position closing are executed immediately, without going through additional confirmation dialogs. * One-click trading for [Open orders](../widgets/open-orders): When enabled, single and bulk order cancellations are executed immediately, without going through additional confirmation dialogs. * **API token management**: This new section allows you to generate and manage tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/). Up to 10 tokens can be generated per account. The validity period for each token is one year. The tokens can be revoked or deleted anytime. *** ### Improvements [#improvements-4] #### Responsive widget layout [#responsive-widget-layout] Widget content now adapts dynamically to the available space, ensuring that key information such as primary values, titles, and critical actions remains visible even when widgets are resized or minimized. Layouts have been refined to avoid unnecessary empty areas while preventing clipping of important elements, delivering a more readable and informative experience across all widget sizes. #### Clearer margin level display [#clearer-margin-level-display] The [Margin](../widgets/margin) widget has been updated to provide a clearer signal. Now, whenever no margin is used (for example, when you have no open positions), the **used margin** value displays **–** instead of 0%. This aligns with common brokerage practices and helps you better understand the current risk state at a glance. #### Smarter default filters for Assets and Account margin [#smarter-default-filters-for-assets-and-account-margin] Certain default filters are now applied automatically when the Trading terminal is opened for the first time. In the [Assets](../widgets/assets) widget, **Hide zero balances** is enabled by default, so assets with zero balance are not shown. In the [Account margin](../get-started/settings#account-margin) settings, **Hide zero balances** and **Hide assets with zero margin ratio** are enabled by default, hiding assets that carry no margin or balance. If you change any of these filters, the platform remembers their states. #### Improved quick trade panels [#improved-quick-trade-panels] The **Market quick trade panel** has been moved not to cover the important controls of the [Price chart](../widgets/price-chart). Additionally, it now displays the **cross icon** to quickly close the panel if needed. *** ### Resolved issues [#resolved-issues-2] There have been no customer-facing issues reported in this release. ## November 7, 2025 [#november-7-2025] ### New features [#new-features-6] #### Tiered leverage system [#tiered-leverage-system] With this release, we're excited to introduce the **tiered leverage system** that provides more sophisticated leverage options based on your position sizes, offering better risk management. **Key points:** * **Dynamic leverage tiers**: Markets can now offer tiered leverage where your maximum available leverage decreases as your position size increases. This allows you to access higher leverage on smaller positions while maintaining appropriate risk controls on larger trades. * **Enhanced market information**: Markets with tiered leverage now display comprehensive leverage information in the **Market info** panel. A new **Leverage** tab shows all available tiers, including the notional value ranges and maximum leverage for each tier. * **Improved position tracking**: Your open positions now display both the leverage you selected when opening the position (**Requested leverage**) and the actual leverage being applied (**Leverage**). Detailed tooltips explain how these values are calculated, giving you better visibility into your margin usage. * **Smart leverage selection**: When placing orders on markets with tiered leverage, the system automatically calculates your margin requirements across all applicable tiers. You can see the exact margin required before placing your order. **How it works** For markets with dynamic leverage, your position is allocated across different tiers based on its notional value. Each tier has its own maximum leverage limit, typically starting with higher leverage for smaller positions and decreasing as position size grows. This allows you to maintain appropriate risk management. **Order placement** When trading on tiered markets, you can still select your preferred leverage (up to the maximum allowed for the first tier), and the system will automatically apply the appropriate leverage limits. The margin calculator shows you the exact requirements before you place your order. All existing positions continue to operate normally with no changes to your current trading experience. Markets without tiered leverage continue to work exactly as before. *** ### Improvements [#improvements-5] #### Improved documentation experience [#improved-documentation-experience] The documentation window is now fully resizable, allowing traders to adjust both vertical and horizontal dimensions independently. All screenshots can now be zoomed, making detailed interface elements clearly visible. #### Streamlined market selection [#streamlined-market-selection] The market selection control is now displayed as the **chevron icon** directly next to the market name in widgets. The magnifying glass icon has been removed. Both the market name and chevron are now clickable and open the market selector. #### Reorganized market information access [#reorganized-market-information-access] The market info popover has been relocated under the **info icon** in the widget header to maintain accessibility while keeping the market name area focused solely on selection functionality, creating a cleaner and more consistent user interface. #### Enhanced workspace tab design [#enhanced-workspace-tab-design] A clear distinction between active and inactive workspace tabs has been achieved due to intuitive styling. Workspace option buttons are now hidden by default to reduce visual clutter and only appear when tabs are active or being hovered over. This applies to both default and custom workspace tabs, creating a cleaner interface while maintaining full functionality when needed. *** ### Resolved issues [#resolved-issues-3] There have been no customer-facing issues reported in this release. ## October 9, 2025 [#october-9-2025] ### New features [#new-features-7] #### Placing orders from the Price chart [#placing-orders-from-the-price-chart] The [Price chart](../widgets/price-chart) widget now supports direct order placement with two new quick trading panels. The **Market quick trade panel** provides a persistent interface for instant buy/sell orders, while the **Limit quick trade panel** allows hover-based order placement at specific price levels. When enabled through **Price chart settings**, both panels offer configurable amount presets and leverage ratio selection for margin trading (when applicable), creating a seamless trading experience without leaving the chart view. #### Bulk order canceling [#bulk-order-canceling] The [Open orders](../widgets/open-orders) widget introduces a **Cancel all** button that closes all active orders simultaneously. This feature provides better risk management capabilities during volatile market conditions. #### In-platform documentation [#in-platform-documentation] User documentation is now integrated directly within the Trading terminal interface. This eliminates the need to switch between applications when accessing help materials or reference guides, keeping essential information readily available during trading sessions. #### New market subtype [#new-market-subtype] The new **Commodities** subtype has been added for CFD markets, enhancing the market categorization system. *** ### Improvements [#improvements-6] #### Enhanced position tracking [#enhanced-position-tracking] A new **Direction** column has been added to **Trades** info in the [Open positions](../widgets/open-positions) and [Closed positions](../widgets/closed-positions) widgets. It indicates whether a position size increased (In) or decreased (Out) as a result of each trade. This enhancement provides clearer visibility into position movement patterns. #### Cross rates calculation precision [#cross-rates-calculation-precision] Accuracy for cross-rate calculations has been improved by introducing a new cross-rate scale parameter. It has a default value of 8 and can be adjusted in configuration files. This addresses the previous limitation where cross rates were rounded to the root asset type scale (typically 2 decimal places), causing incorrect zero values in certain scenarios. The improvement ensures accurate cross-rate calculations across all currency and cryptocurrency pairs, regardless of their relative values. #### Redesigned Settings interface [#redesigned-settings-interface] The **Settings** menu has been restructured with a new tabbed popup interface. Related configuration options are now logically grouped, making settings easier to navigate and manage. #### Pre-filled Limit order price [#pre-filled-limit-order-price] Limit order placement now includes automatic price pre-population using the best bid or ask price from the order book. This static pre-fill reduces manual entry requirements and helps prevent pricing errors during order submission. #### Updated sorting of open positions [#updated-sorting-of-open-positions] [Open positions](../widgets/open-positions) are now sorted chronologically with the newest positions displayed at the top, improving visibility of recent trading activity. #### Improved messages [#improved-messages] User communications have been updated throughout the platform, including improved Introduction tour messaging for better onboarding and clearer system notifications. #### UI enhancements [#ui-enhancements] UI improvements for this release include: * **Support for dynamic resizing of the trading interface layout**: The trading interface now features a responsive layout system that dynamically adjusts to browser window resizing. Widgets automatically scale and reposition to maintain optimal viewing regardless of screen size changes. * **Loader**: [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now display loading indicators when fetching additional data. * **Improved PnL representation**: When displayed on charts, the PnL values are now accompanied by "+" or "–" signs for immediate profit/loss recognition. * **Improved scrollbars**: Scrollbar positioning has been refined to prevent overlay of table content, ensuring all data remains visible and accessible. *** ### Resolved issues [#resolved-issues-4] There have been no customer-facing issues reported in this release. ## July 2, 2025 [#july-2-2025] ### New features [#new-features-8] #### Trading reports [#trading-reports] We've implemented a new feature enabling you to generate trading reports for a specific period of time and download them as zipped CSV files to your computer. The report includes a detailed information on: * **Trade history** * Closed positions * Executed orders * Trades * **Transfers history** * **Account statistics** * Total balance * Realized PnL * Swaps * Funding * Commissions The data is available for any period within the last **92 days** (UTC time). The following timeframe presets have been implemented for your convenience: * Today * Current: week, month, quarter * Previous: week, month, quarter Access the new **Trading report** menu under the **Settings** icon on the topbar of the Trading terminal. *** ### Improvements [#improvements-7] #### Admin-managed orders and positions [#admin-managed-orders-and-positions] In the [Open positions](../widgets/open-positions), [Closed positions](../widgets/closed-positions), and [Order history](../widgets/order-history) widgets, if BP Admins have managed positions or orders, this is now indicated in the Reason field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, and mitigate risks. *** ### Resolved issues [#resolved-issues-5] There have been no customer-facing issues reported in this release. ## May 30, 2025 [#may-30-2025] ### New features [#new-features-9] #### PF trading [#pf-trading] We are excited to introduce **Perpetual Futures (PF) trading** on our platform. These contracts feature a funding fee mechanism based on the Mark price and Funding rate. A positive rate means Long positions pay Shorts, and a negative rate means the reverse. You can see the countdown to the next funding fee settlement in the [Market summary](../widgets/market-summary) widget. This update also includes a new market type — Perpetual — enhancing your trading opportunities. *** ### Improvements [#improvements-8] #### Price chart setting [#price-chart-setting] The [Price chart](../widgets/price-chart) widget now supports displaying of open positions, as well as open and executed orders. Click the **gear icon** in the topbar to access Price chart settings and enable desired options. #### Close all positions [#close-all-positions] The [Open positions](../widgets/open-positions) widget now features a new **Close all** option, offering enhanced management capabilities. This update provides a more efficient way to handle multiple positions by allowing you to simultaneously close: * All open positions * All open positions with positive PnL * All open positions with negative PnL #### Enhanced price control [#enhanced-price-control] The following enhancements have been implemented for the [Price control](../widgets/price-control) widget: * **Editable price alerts**: You can now adjust existing price alerts by clicking a price. * **Enhanced market additions**: Price and percentage fields now automatically open for editing when a new market is added to the widget. * **Visual indicators**: Arrows near price triggers aren’t shown if the price feed is unavailable, reducing clutter and potential confusion. #### Historical data limits [#historical-data-limits] The [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now provide historical data with a limit of **92 days**. *** ### Resolved issues [#resolved-issues-6] There have been no customer-facing issues reported in this release. ## April 17, 2025 [#april-17-2025] ### New features [#new-features-10] #### Netting account type [#netting-account-type] With this release, a new **Netting** account type has been enabled. It intelligently consolidates all orders placed on the same market into a single position. Previously, the system supported only Hedging, where each order opens a separate position. **Key points of netting** * **Reduced margin requirements**: Instead of calculating margin requirements separately for each position, netting combines them, lowering overall capital needs. * **Lower trading costs**: By holding opposing positions, traders often incur double position swaps. Netting treats these positions as one, reducing unnecessary costs. * **Streamlined position management**: Managing multiple positions manually can become complicated, especially when balancing between different trade sizes, directions, leverages and margin requirements. Netting helps with it by combining positions into a single one. **Netting VS Hedging** Netting may sometimes lack the flexibility required for complex hedging strategies. In contrast, hedging excels by allowing traders to hold both long and short positions simultaneously without offsetting them. This enhances the ability to track and adjust individual trades easily while permitting precise margin management for separate positions. The Hedging type is perfectly suited for traders seeking detailed control over their positions. On the other hand, the Netting type ensures simplicity and reduced margin requirements, making it the perfect choice for straightforward trading strategies. **Workflow changes** When opening a new trading account, you must now choose its type: either Hedging or Netting. This choice is permanent and influences all future trades in the account. In the account selection interface, each account displays its type: `H` for Hedging or `N` for Netting. All existing accounts are automatically assigned to the Hedging type. *** ### Improvements [#improvements-9] #### Improved widget control [#improved-widget-control] With this release, you now have enhanced control over the viewing experience: * **Configuring widget columns**: Certain widgets allow you to configure widget columns in a way that best suits your needs, offering you the flexibility to select which columns you wish to display or hide. Additionally, you can arrange the order of these columns for your convenience, ensuring that the information you prioritize is always at your fingertips. * **Rearranging widget tabs**: All widgets now feature drag-and-drop functionality for rearranging tabs effortlessly. This user-friendly feature offers a more customized and organized interface, making it easier than ever to personalize your widget experience. #### Enhanced Order book [#enhanced-order-book] The Order book widget has been upgraded with new customizable settings. This update introduces intuitive controls, empowering you to adjust the widget view according to your preference: * **Full view**: Shows both buy and sell orders along with the market spread. * **Buy only view**: Displays only buy orders and the market spread. * **Sell only view**: Displays only sell orders and the market spread. *** ### Resolved issues [#resolved-issues-7] There have been no customer-facing issues reported in this release. ## January 15, 2025 [#january-15-2025] ### New features [#new-features-11] #### Take profit, Stop loss, Trailing stop [#take-profit-stop-loss-trailing-stop] With this release, the following new triggers for open positions have been implemented on the platform: * **Take profit**: A take-profit trigger is used to close a position automatically once the market hits a predefined price, ensuring the trader locks in profits. * **Stop loss**: A stop-loss order is a trigger to limit potential losses. It automatically closes a position when its price changes to a predetermined level. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified value. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. These settings can be used when trading on CFD markets and can be applied to Market, Limit, and Stop orders, as well as for currently open positions. The new settings can be enabled when placing an order via the [Place order](../widgets/place-order) widget (Advanced mode). Until a position is fully closed, they can also be adjusted or canceled via the [Open positions](../widgets/open-positions) widget. The information about applied settings is also available in the corresponding widgets: [Closed positions](../widgets/closed-positions), [Open orders](../widgets/open-orders), and [Order history](../widgets/order-history). *** ### Resolved issues [#resolved-issues-8] There have been no customer-facing issues reported in this release. *** ## Past releases [#past-releases] ### December, 2024 [#december-2024] #### New features [#new-features-12] ##### CFD trading [#cfd-trading] With this release, we're excited to announce the support for CFD (Contract for Difference) trading on our brokerage platform. This empowers you to trade with dynamic leverage, using your funds as collateral to secure positions confidently. Enjoy the flexibility to go both long and short, capitalizing on both bullish and bearish markets. Our CFD trading support boasts an intuitive interface, robust risk management tools, and real-time data. ##### Innovative market approach and instrument picker [#innovative-market-approach-and-instrument-picker] * **Market type**: Markets are now classified into Spot and CFD, reflecting their differing parameters. A panel indicating CFD or Spot is now included in all widgets. * **Market parameters and trading schedule**: Click a market name to access its key parameters and scheduled trading sessions. * **Market categories**: Now accessible via the top bar, offering a hierarchical view for easier selection and switching between markets. ##### Account margin settings [#account-margin-settings] Access the new [Account margin settings](../get-started/settings) to monitor your balances and configure assets to be used as collateral for CFD trading. ##### Reworked Place order widget [#reworked-place-order-widget] Place any order with a [single widget](../widgets/place-order) now. Choose Quick IOC Market or Stop with adjusted leverage — all conveniently in one place, along with an order summary. ##### Positions [#positions] Discover two new widgets for position monitoring: * [Open positions](../widgets/open-positions): Offers real-time monitoring of currently open positions with price changes, PnL, used margin, and other parameters. * [Closed positions](../widgets/closed-positions): Provides historical data on position details, prices, and realized PnL. ##### Risk management [#risk-management] You now have three essential widgets to maintain control: * [Margin](../widgets/margin): Monitor your margin account parameters in real time and respond swiftly to changes. * [Price control](../widgets/price-control): Set price alerts tailored to your specific needs and parameters. * [Messages](../widgets/messages): Receive system notifications and price alerts directly. ##### Market data [#market-data] Two new widgets have been introduced to enhance market monitoring: * [Market summary](../widgets/market-summary): Provides detailed information and updates on price changes for a specific market. * [All markets](../widgets/all-markets): Displays price change statistics across all markets simultaneously. #### Improvements [#improvements-10] * Performance has increased significantly, allowing each trader to hold up to 1,000 CFD positions open. * Limits have been increased to 3,000 requests per second. #### Resolved issues [#resolved-issues-9] There have been no customer-facing issues reported in this release. *** ### June 20, 2024 [#june-20-2024] #### Improvements [#improvements-11] * Account selection is now available from the topbar of the Trading terminal. Once you change your account, all the widgets will automatically adjust to show relevant information for the selected account. * Tabs are now available in the Trading terminal. You can place up to 10 tabs to open multiple workspaces simultaneously for better information organization. You can utilize pre-configured layouts for your workspaces or create custom ones. *** ### June 13, 2024 [#june-13-2024] #### New features [#new-features-13] ##### iOS mobile application [#ios-mobile-application] With this release, our team is thrilled to announce the launch of the brand-new iOS mobile app. The mobile app is closely integrated with B2CORE mobile. Along with single sign-on implemented, it allows you to seamlessly navigate between the apps, without re-entering credentials. In the mobile app, just like in the web version of the Trading terminal, you can access all of your BP accounts, place orders, monitor market data, and so on. For your convenience, it all can be done in a very similar way as in the web version. A consistent and user-friendly interface makes using the app easy and intuitive. Among the key features and services that the new BP mobile offers: * The account list with detailed balances, to always keep your funds under control. Creation and renaming of accounts, to keep your funds well organized. * Asset balances screen, with the amounts of free and frozen funds specified and with the possibility to hide assets with zero balances. * The Order book and price chart, to monitor and analyze trading data and make buy or sell decisions, with a quick and easy jump to the order placing screen. * Candles and line charts, with easy switching and the possibility to scroll the data for historical values. * Limit & Market order placing, with all time in force options supported in the Web version (Market: IOC, FOK; Limit: IOC, FOK, GTC, GTD, Day). * Open and history orders lists, with easy access to order parameters and details, quick canceling or repeating an order. * Light and dark themes and many more. ### October 18, 2023 [#october-18-2023] #### New features [#new-features-14] With this initial release, our team is happy to announce the launch of our new Trading terminal. ##### Placing orders [#placing-orders] The platform currently supports placing Market, Limit, Stop Market, and Stop Limit orders (refer to [Order types](../knowledge-base/order-types)). You can also choose from various [Time in force](../knowledge-base/time-in-force) options such as FOK, IOC, GTC, GTD, and DAY. ##### Widgets [#widgets] The platform provides you with enhanced widgets that are specifically designed for convenient trading. These widgets allow you to easily place orders, access the Order book, monitor open orders and order history, and much more. Refer to [Place order](../widgets/place-order) and the other pages of the Widgets section for more information. ##### Dashboard [#dashboard] The customizable dashboard allows you to personalize the layout to suit your needs and keep you focused on what's important. Refer to [Interface overview](../get-started/customizing-your-terminal) to learn more about workspace customization. ## Summary [#summary] This widget provides AI-powered market analysis and trading recommendations for the selected market. AI Assistant The widget is organized into the following sections: * [AI Recommendation](#ai-recommendation): Overall recommendation score. * [Forecast](#forecast): Price target and market sentiment. * [Signal Drivers](#signal-drivers): Technical, on-chain, and sentiment signals. * [Suggested Actions](#suggested-actions): AI-generated trading suggestions. * [Key Metrics](#key-metrics): Market data overview. ## AI Recommendation [#ai-recommendation] Displays a numeric score from 0 to 100 representing the overall AI assessment of the market, along with a label such as **Strong Buy**, **Buy**, **Neutral**, **Sell**, or **Strong Sell**. A higher score indicates a more favorable outlook. ## Forecast [#forecast] **1Y Price Target** The forecasted price in one year and the expected percentage change from the current price. *** **Market Sentiment** A visual bar showing the ratio between bullish and bearish sentiment among market participants. ## Signal Drivers [#signal-drivers] Signals that influence the AI recommendation, categorized into three types: * **Technical**: Signals based on technical analysis indicators such as RSI and Moving Averages. * **On-Chain**: Signals based on blockchain data such as ETF inflows, active addresses, and total value locked (TVL). * **Sentiment**: Signals based on community and analyst opinions. Each signal includes a description and an impact assessment: **Bullish**, **Bearish**, or **Neutral**. ## Suggested Actions [#suggested-actions] A list of AI-generated trading suggestions based on the current market conditions. These are informational recommendations, not automated trading signals. ## Key Metrics [#key-metrics] The following market data is displayed: **All-Time High** The highest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **All-Time Low** The lowest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **24h Volume** The total trading volume over the last 24 hours in USD. *** **Market Cap** The total market capitalization of the asset in USD. AI-generated insights are for informational purposes only. The AI Assistant widget can be enabled or disabled by the platform administrator. If the widget isn't available in the **Add Widget** menu, contact your broker. ## Summary [#summary] Use this widget to monitor price data on all markets available on the platform. The widget is dynamic and is continuously updated in real time. All markets ## Fields [#fields] The following information is provided about each market: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current market price, in the quote asset and in the platform root asset. This value is green if the price is rising and red if it's falling. *** **24h change** The price change over the last 24 hours, in absolute and percentage values. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. ## Summary [#summary] This widget displays the list of all asset balances on your account. Assets ## Settings [#settings] ### Hide zero balances [#hide-zero-balances] Use this option to hide all assets with zero balances from the list. It's enabled by default. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance at your disposal, meaning the difference between your total assets and a sum of all limit orders placed by this time. This value is calculated as *Total – Halted*, where *Halted* is the asset amount frozen on the account for execution of placed Limit orders. *** **Available, \{RAT}** The available balance, in conversion to the platform root asset. *** **Total** The overall amount of the asset available in your wallet, including locked funds. *** **Total, \{RAT}** The total balance, in conversion to the platform root asset. ## Summary [#summary] This widget displays a list of your closed positions on the selected account. The entire history of your closed positions is available. Closed positions The widget lists only closed positions. For a list of currently open positions, use the [Open positions](open-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists closed positions for the last three months. To display positions closed during a specific time period, use the **Select date range** field. The most recently closed positions appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related orders [#view-related-orders] Click the **chevron icon** in a position row to expand a list of position-closing orders. As positions can be partially closed, there may be more than one line. For each executed position-closing order, a separate line is added. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Pos. closed size** The closed volume, in lots, which is equivalent to the corresponding filled order volume. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Close price** The volume-weighted average price (VWAP) of trades related to a position-closing order. *** **Close order ID** The identifier of an order closing the position. *** **Realized PnL, \{RAT}** The actual profit or loss earned, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). *** **\{RAT} notional** The equivalent of the closed volume in the platform root asset. *** **History rate to \{RAT}** The rate to the platform root asset at the moment of position closing. *** **Reason** The reason for closing a position. Possible values: * **Trader**: The position was closed by you. * **Admin**: The position was closed by an Admin. * **Stop-out**: The position was automatically closed by the system, as a result of Stop out. * **Stop loss**: The position was closed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The position was closed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The position was closed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. *** **Open date, time** The date and time when a position was opened. *** **Closed date, time** The date and time when a position-closing order was last updated (fully executed). ## Summary [#summary] This widget helps you monitor margin parameters and statistics. Margin ## Fields [#fields] All values are in displayed in conversion to the platform root asset: **Your margin level** The ratio of your funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. Possible values: * **Empty**: No open positions. * **Low risk**: Everything is ok. * **Margin call**: Your margin level fell below the set Margin call value. You received a notification urging you to increase the margin level to avoid a Stop out. Remember that if you ignore this warning, the margin level may continue to decrease. During the Margin call, you can only close existing positions; opening new positions isn’t possible. * **Stop out level**: Your margin level fell below the set Stop out value; the platform started a process of liquidating your positions. This process continues until the margin level exceeds this required value. **ANY** currently open position can be closed regardless of its side and volume. *** **Margin balance** The total amount of your funds that can be used as a collateral for CFD trading. It’s calculated as Σ(*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*), where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the platform root asset. The Margin balance is continually recalculated based on price fluctuations. An increase in the prices of assets boosts available Balance & Free margin. Conversely, a decrease in asset prices may reduce the available Balance and Free margin. Additionally, a decline in the prices of assets with open positions may trigger Margin calls and Stop outs. *** **Credit** A promotional bonus granted by your broker for margin (CFD and Perpetual) trading, shown in the platform root asset (RAT). When you have no credit, this row shows 0. Credit increases your Equity and Free margin and can be used as collateral to open positions. It becomes available immediately when granted and never expires. However, credit cannot be withdrawn as cash, so it is excluded from your withdrawable balance. Your broker can revoke credit at any time, and the row updates in real time when this happens. The row includes an info tooltip that reads: *Promotional credit for margin trading only. Cannot be withdrawn.* *** **Equity** The potential balance of your account if all your positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. *** **Used margin** The amount of funds that is used for maintaining all your open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **Example** **Step 1: Initial balance** * Margin balance: $10,000 * Opened positions: 0 * Free margin: $10,000 * Used margin: $0 **Step 2: Open a long position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 100 = $1,001 * After opening: * Free margin: $8,999 * Used margin: $1,001 **Step 3: Open a long position (Leverage 1:20)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 20 = $5,005 * After opening: * Free margin: $3,994 * Used margin: $6,006 **Step 4: Open a short position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 9 lots (900,000 units) * Current price: $1 * Required margin: $(900,000 × 1.001) / 100 = $9,009. The system verifies that upon opening this position, the MarketUsedMargin remains valid by satisfying the condition: **MarketUsedMargin** = MAX(*MarketPositionLong*, *MarketPositionShort*) = MAX(6,006, 9,009) = 9,009. Since the condition is met, the position opens. * After opening: * Free margin: $991 * Used margin: $9,009 As a result, you can open multiple opposite positions without significantly increasing the Used margin. Furthermore, closing positions never increases the Used margin. *** **Free margin** The amount of funds that can be used for opening new positions. *** **Unrealized PnL** The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) ## Summary [#summary] Use this widget to assess the current market depth indicating the actual liquidity of an asset, which is evaluated based on the number of currently open orders to buy and sell it as well asset prices and volumes at various price levels. Market depth The widget is dynamic and is continuously updated in real time. The widget displays a chart indicating the overall volume of buy (green) and sell (red) orders at various price levels awaiting execution at the moment. You can hover the mouse pointer over the chart to learn the exact price and volume of an asset traded at a specific price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ## Summary [#summary] Use this widget to monitor statistics on a specific instrument. The widget is dynamic and is continuously updated in real time. Market summary To monitor multiple instruments at a time, use the [Watch list](watch-list) widget. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the first column. To change the market, click the market symbol and select a different one from the list. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current top-of-the-book price, in the quote asset. *** **Current price, \{RAT}** The current top-of-the-book price, in conversion to the platform root asset. *** **24h change** The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h high** The highest trade price over the last 24 hours. This value is always green. *** **24h low** The lowest trade price over the last 24 hours. This value is always red. *** **Info icon** Click this icon to view market details and trading sessions schedule. ## Summary [#summary] This widget displays a list of received notifications, both system and configured via the [Price control](price-control) widget. Messages ## Settings [#settings] ### Mark as read [#mark-as-read] Unread alerts are marked with a red dot in the list: * Click the dot to mark the notification as read. * Click **Mark all as read** to mark all new notifications as read at once. * Click the **three dots** icon in the upper right corner of the widget to access the **Hide read notifications option**. The counter of unread alerts is also displayed on the **bell icon** in the topbar. ## Summary [#summary] This widget displays a list of Limit orders that have been placed from this specific account and are currently open and assigned one of the following [statuses](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. Open orders The widget lists only open orders, that are currently not filled or partially filled. For a list of orders in the final statuses, use the [Order history](order-history) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders for all the time. To display orders for a specific time period, use the **Select date range** field. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled so far. *** **Fee** The total commission paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that hasn’t yet been filled. *** **Limit price** For Limit orders, the Limit price set when placing the order. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set. *** **Used leverage** For margin trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Valid until** The date and time when an order expires. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Admin**: The order was placed by an Admin. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Cancel orders [#cancel-orders] To cancel an order, click the **×** in the corresponding row. To cancel all active orders at once, click the **Cancel all** button in the widget header. ## Summary [#summary] This widget displays a list of your positions currently open on the selected account. Open positions The widget lists only open positions. For a list of closed positions, use the [Closed positions](closed-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists open positions for all the time. To display positions opened during a specific time period, use the **Select date range** field. The most recent position appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related trades [#view-related-trades] Click the **chevron icon** in a position row to expand a list of related trades. ### Close positions [#close-positions] To close a position, hover over it and click the **CLOSE** button that appears. To close all/multiple positions at once, click **Close all** and select the desired option: close all positions or close positions with positive/negative PnL. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Position size** The current position volume, in lots. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Current price** The current market price of the base asset: bid for Long positions and ask for Short positions. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Unrealized PnL, DAY, \{RAT}** The potential profit or loss earned for a current day, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. *** **Unrealized PnL, DAY, %** The potential profit or loss earned for a current day, in percents. *** **Unrealized PnL, Total, \{RAT}** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). *** **Unrealized PnL, Total, %** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset, in percents. *** **Used margin, \{RAT}** The amount of your funds used for maintaining a position, in conversion to the platform root asset. *** **Leverage** The actual leverage ratio used for opening a position. *** **Req. leverage** The leverage ratio you requested when opening a position. *** **\{RAT} notional** The current position size equivalent in the platform root asset. *** **Rate to \{RAT}** The current exchange rate of a quote asset to the platform root asset. *** **Open date, time** The date and time when a position was opened. *** **Updated date, time** The date and time of the latest position-related trade. *** **Reason** The reason for opening a position: * **Trader**: The position was opened by you. * **Admin**: The position was opened by an Admin. * **Webhook alert**: The position was opened via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. ## Summary [#summary] This widget displays a list of currently open buy and sell limit orders for a selected asset along with the current bid-ask spread. Order book The widget is dynamic and is continuously updated in real time. It provides three different sections displaying the following information: * Open sell orders are highlighted in red and listed in the top section. The best ask, which is the sell order with the lowest price, is displayed at the bottom of this list. * Open buy orders are highlighted in green and listed in the bottom section. The best bid, which is the buy order with the highest price, is displayed at the top of this list. * The middle section displays the current bid-ask spread indicating the gap between the best ask and bid prices declared for an asset. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Display only asks/bids [#display-only-asksbids] In the upper part of the widget, you can choose how to display the Order book: * Full view. * Buy orders only + spread. * Sell orders only + spread. ## Fields [#fields] Each row of the Order book provides the following information about a selected market: **Price, \{QUOTE}** The price, in the quote asset. *** **Amount, \{BASE}** The total amount of the base asset available at a corresponding price level. *** **Total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. In addition, you can use the [Market depth](market-depth) widget to evaluate the liquidity of a specific asset based on the overall volume of orders traded at various price levels. For Spot markets, hover over Order book rows to view additional information and buy or sell assets in click: **Average price** The average price, in the quote asset. *** **Total volume** The total amount of the base asset available at a corresponding price level. *** **Grand total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. *** **Buy** / **Sell** Click the button to instantly place a Market order to buy or sell the asset at the selected price level. ## Summary [#summary] This widget provides up-to-date information about the orders executed on a selected market partially or in full, as well as the orders that were canceled, rejected, and expired. The entire order history of your account is available. Order history The widget lists only the orders to which final statuses are assigned. For a list of orders that are still being executed, use the [Open orders](open-orders) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders with the *Completed* status for the last three months. To display orders for a specific time period, use the **Select date range** field. To display orders with specific statuses, select one or more from the dropdown above the list. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled. *** **Fee** The total commissions paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that wasn't filled. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Completed*, *Cancelled*, *Rejected*, or *Expired*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Stop loss**: The order was placed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The order was placed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Summary [#summary] Use this widget to place new orders. Place order The widget has two states: ### The PRO toggle is disabled [#the-pro-toggle-is-disabled] In this state, you can quickly place **IOC Market** and **GTC Limit** orders by selecting the order side (Buy/Sell) and type (Market/Limit), and specifying the order size (in lots) and price (for Limit orders). You can also place orders on CFD markets with the maximum leverage automatically applied. ### The PRO toggle is enabled [#the-pro-toggle-is-enabled] In this state, you get access to more precise order settings, such as: * **Stop orders** * **Time in force** * **Leverage** * **Take profit, Stop loss, Trailing stop** * **Comment** * **Complete order information** The **Comment** field allows you to attach a text note to the order (up to 100 characters). The comment is inherited by the resulting position and can't be edited after the order is placed. ## Settings [#settings] ### Select a market [#select-a-market] The market on which the order will be placed is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Place an order [#place-an-order] To place an order, fill in the parameters, review order details and preliminary calculated values, and then confirm the order by clicking the **Place** button. For a Limit order whose price crosses the current top-of-book — Buy at or above the best ask, or Sell at or below the best bid — the platform shows a confirmation dialog before submission. The dialog shows the entered price and the current best bid/ask, and lets you confirm or cancel the order. This warning is enabled by default; you can disable it from the dialog (**Do not show this warning again**) or from the **Limit order cross-TOB warning** toggle in [Settings](../get-started/settings#action-confirmation). ### Set price triggers [#set-price-triggers] If using **Take profit, Stop loss, Trailing stop**, set the prices in consideration of the current highest market bid/ask or a specified Limit price: These values can be adjusted any time until the position is fully closed via the [Open positions](open-positions) widget. You can't place orders during non-trading hours, according to the trading calendar schedule. The order controls are disabled when the selected account is Halted or Frozen. For more information, see [Account status](../get-started/customizing-your-terminal#account-status). You will not be able to place an order if the execution of the order causes your margin level to fall below the *Margin call* level. The same conditions apply to withdrawal operations. ## Summary [#summary] This widget displays a price chart showing fluctuation of prices for a selected market over a certain time period. Price chart The horizontal axis (X-axis) represents the time scale, and the vertical axis (Y-axis) indicates the price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Customization [#customization] Multiple customization options are provided, allowing you to configure the chart according to your preferences. You can switch between bar, candle, Heikin Ashi, line, area and baseline views, as well as specify the time period for which data should be displayed. The chart supports numerous financial indicators, such as moving averages and regressions, and can feature a variety of custom shapes, including arrows and lines, pitchforks, and various ranges, allowing you to perform an in-depth market analysis. ### Display options [#display-options] The widget supports displaying of open positions, price triggers, open and executed orders. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart) to enable desired options. ## Placing orders [#placing-orders] ### Enable placing orders [#enable-placing-orders] To enable placing orders directly from the Price chart, you need to activate the corresponding settings: 1. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart). 2. Activate the **Market quick trade panel** or **Limit quick trade panel** toggle, or both. 3. If needed, adjust the amount presets. These amounts will be available for quick selection when placing an order. ### Market quick trade panel [#market-quick-trade-panel] If the corresponding setting is activated, the draggable **Market quick trade panel** is constantly displayed on the Price chart. ### Limit quick trade panel [#limit-quick-trade-panel] If the corresponding setting is activated, the **+** will appear when hovering over price levels on the chart. Clicking it will open the **Limit quick trade panel**: * in the upper half of the chart — to sell; * in the lower half of the chart — to buy. ### Place a new order [#place-a-new-order] To place a new Market or Limit order from the Price chart, when a corresponding panel is displayed: 1. Select the **amount** from configured presets. 2. Select a **leverage** ratio, if trading on CFD or PF markets. 3. Click **Buy** or **Sell**. The order will be placed according to the selected type. ## Summary [#summary] Use this widget to configure alerts that will be delivered to the [Messages](messages) widget when an instrument price reaches the specified level. Price control ## Settings [#settings] ### Configure a new alert [#configure-a-new-alert] To configure a new alert: 1. Click the **Add market** button to select a required market from the list. 2. Click the **+** icon below the instrument name to add a new alert trigger. 3. In the displayed fields, specify the exact price or the price change in percents (positive or negative). The other value will be calculated automatically. 4. Click the **check mark icon** to add the trigger. Now you will receive a notification in the [Messages](messages) widget, once the instrument price hits the specified level. You can configure multiple triggers for each instrument. ### Edit alerts [#edit-alerts] Click the price to edit the existing alert. ### Remove alerts [#remove-alerts] Click the **×** button on the trigger panel to remove it and stop receiving corresponding notifications. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ## Summary [#summary] This widget displays a list of untriggered Stop orders created on the selected account. Once a market price reaches your predetermined Stop price, the Stop order is activated and submitted as either a Market or Limit order. It's then removed from this widget. You can now find it in either the [Open orders](open-orders) or [Order history](order-history) widget, depending on its current status. Stop orders ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the Stop Market and Stop Limit orders for all the time. The most recent order appears at the top of the list. To display orders for a specific time period, use the **Select date range** field. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types): Stop Market or Stop Limit. *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Stop price** The stop price specified when creating an order. When the market reaches this price, the Stop order will be placed (as a Market or Limit order. *** **Limit price** The price of a Limit order that will be placed when the Stop price is triggered. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Order ID** The system identifier of an order. ## Summary [#summary] Use this widget to monitor statistics on multiple instruments at a time. The widget is dynamic and is continuously updated in real time. Watch list ## Settings [#settings] ### Add/remove instruments [#addremove-instruments] Click the **Add market** button to select a required market from the list. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Last price** The price of the last trade. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h low** The lowest trade price over the last 24 hours. *** **24h high** The highest trade price over the last 24 hours. Understand the basics and learn everything you need to start using the B2TRADER API Understand the basics and learn everything you need to start using the B2TRADER API Consult an in-depth reference describing REST API requests and responses Consult an in-depth reference describing REST API requests and responses Explore the supported WebSocket API methods and streams Explore the supported WebSocket API methods and streams Connect to the FIX 4.4 API for market data streaming and order execution Connect to the FIX 4.4 API for market data streaming and order execution ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Trading API: Stop orders for closed markets [#trading-api-stop-orders-for-closed-markets] The **Trading API** now accepts **Stop** orders for markets that are closed according to their trading calendar. The order is stored and activates automatically when the market reopens, instead of being rejected at submission. #### Reports API: full account history [#reports-api-full-account-history] Trading reports can now be generated for the entire account history. The previous **92-day** limit has been removed, and an **All data** range is now available for report generation. #### Trading API: market asset identifiers [#trading-api-market-asset-identifiers] The `baseAssetId` and `quoteAssetId` fields have been added to the v6 `/markets` responses, allowing clients to resolve the base and quote assets of each market without additional lookups. #### Accurate unrealized PnL [#accurate-unrealized-pnl] Unrealized PnL returned by the API is now calculated using the correct order book side for each position direction, improving the accuracy of PnL values in position and margin responses. *** ### Resolved issues [#resolved-issues] * Resolved an issue where `WebhookAlert` order reason and position modifier values were returned as numeric codes instead of API enum strings in History API `/v2/orders` responses. ## April 9, 2026 [#april-9-2026] ### New features [#new-features] #### Trading credit in API responses [#trading-credit-in-api-responses] Broker-issued **trading credit** is now exposed through the API. The account margin data response and the real-time margin stream include the current credit amount in the Reference Asset (`creditInRAT`). Credit is included in the account equity and excluded from the withdrawable amount. *** ### Improvements [#improvements-1] #### Webhook Trading API: webhook URL in key listing [#webhook-trading-api-webhook-url-in-key-listing] The list webhook API keys response now includes the `webhookUrl` field, so the configured webhook endpoint can be retrieved for each key. ## March 16, 2026 [#march-16-2026] ### New features [#new-features-1] #### Webhook Trading API [#webhook-trading-api] A new **Webhook Trading API** has been added, enabling automated order creation via webhook alerts with API key authentication. **Key points:** * Create and manage webhook API keys for secure authentication * Receive trading alerts and create orders automatically * Idempotency supported via deduplication ID * Market type routing by symbol prefix (spot, CFD, perpetual) #### Public Account ID [#public-account-id] A new `publicAccountId` field has been added across all API endpoints, providing a human-readable account identifier as an alternative to internal UUIDs. **Affected APIs:** * Trading API — account-related responses and filters * Settings API — account configuration endpoints * History API — all REST endpoints and WebSocket streams * Reports API — report responses and filters #### Long-term trading data history [#long-term-trading-data-history] Date range restrictions have been removed from **Order History** and **Closed Positions** endpoints, allowing access to full trading history without time-based limitations. *** ### Improvements [#improvements-2] #### Transfer subtype field [#transfer-subtype-field] A new `subtype` field has been added to transfer responses in the History API to distinguish **Negative Balance Protection** transfers from manual ones. #### Rounded position prices [#rounded-position-prices] The `positionPriceInRAT` values are now properly rounded in closed position API responses according to the Reference Asset (RAT) scale. *** ### Resolved issues [#resolved-issues-1] * Resolved an issue where `/total-swaps` requests returned HTTP 504 timeout errors. ## March 11, 2026 [#march-11-2026] ### Added FIX API documentation [#added-fix-api-documentation] Added new FIX API section covering Market Data and Trading sessions via the FIX 4.4 protocol. ## March 11, 2026 [#march-11-2026-1] ### Initial version [#initial-version] ## March 2, 2026 [#march-2-2026] ### New features [#new-features-2] #### Trading Terminal AI assistant [#trading-terminal-ai-assistant] A new **AI assistant** has been added to the Trading Terminal, providing traders with an intelligent widget for market analysis and trading support. *** ### Improvements [#improvements-3] #### Public Account ID (preview) [#public-account-id-preview] The `publicAccountId` field has been added to account-related API responses as a preview, ahead of the full rollout across all endpoints. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-3] #### Funding Rates API [#funding-rates-api] New API endpoints have been added for retrieving funding rate data synchronized from **B2CONNECT**, including funding rates, mark price, and funding interval for Perpetual Futures markets. **Key points:** * Funding rate values streamed in real time * Mark price used for position valuation when available from LP * Funding interval synchronized per market configuration * FIX API contract extended with funding data fields #### OHLC Candlestick API [#ohlc-candlestick-api] A new API endpoint has been added for retrieving OHLC (candlestick) data, supporting both **Spot** and **Perpetual Futures** markets. Minute-level candle data is now stored for up to 5 years. OHLC candle data streaming is also available via the WebSocket API using gRPC transport, providing real-time candlestick updates. #### Favorite markets [#favorite-markets] A new **Favorite markets** feature has been added, allowing traders to manage personalized market lists via the Trading API. #### Comment field for orders and positions [#comment-field-for-orders-and-positions] A new `comment` field has been added to order and position responses across REST, WebSocket, and History APIs. The comment can be set when placing an order and is propagated to the associated position and execution records. #### B2COPY Integration API [#b2copy-integration-api] New API endpoints have been added for **B2COPY** and IB (Introducing Broker) integrations, including special account types for copy trading. The `isCopyTradingAccount` field has been added to the `/api/v1/total-fundings` endpoint. *** ### Improvements [#improvements-4] #### FIX API: enhanced request throughput [#fix-api-enhanced-request-throughput] The FIX API trading request processing has been optimized to support up to 100 requests per second per connection. All `TimeInForce` types are now supported, including **GTD** (Good Till Date). #### Multilingual support [#multilingual-support] Trading API, Settings API, and Reports API endpoints now support multilingual content with full Unicode character support, enabling localized responses for configurable fields, report names, and templates. #### Stop Market order calculation [#stop-market-order-calculation] The **Value** and **Amount** calculation for **Stop Market** orders has been corrected for **Spot** markets. **Slippage Rate** has been removed from **CFD** and **Perpetual Futures** order calculations. #### Trading API: empty categories hidden [#trading-api-empty-categories-hidden] Empty market categories are now automatically excluded from Trading API responses, reducing unnecessary data in category listings. #### Balance API: zero balance for all assets [#balance-api-zero-balance-for-all-assets] Assets without prior balance operations now return a zero balance in API responses instead of being omitted. #### Cross-rate market configuration [#cross-rate-market-configuration] Markets used exclusively for cross-rate calculations can now be disabled for trading while remaining active for rate conversion. #### History API: extended contracts [#history-api-extended-contracts] Positions and Events API responses have been extended with additional fields. The `updatedAt` field is now available as a sorting and filtering parameter in History Server API endpoints. #### Settings API: market update endpoint [#settings-api-market-update-endpoint] The market update endpoint has been changed from `PATCH` to `PUT` semantics, requiring the full market object in the request body. #### Settings API: legacy endpoints removed [#settings-api-legacy-endpoints-removed] Legacy commission and routing rule endpoints have been removed following the tier commission update. Use the current endpoints as documented in the API reference. *** ### Resolved issues [#resolved-issues-2] * Resolved an issue where `takeProfitPrice` and `stopLossPrice` values were missing from the History Server `/v2/orders` endpoint responses. * Resolved an issue where bulk order cancellation returned a successful result for non-existing orders. * Resolved an issue where bulk order cancellation returned a successful result for orders that could not be cancelled. * Resolved incorrect error codes returned when `closePositionLotAmount` was set to `0`, a negative value, or an empty string. * Resolved an issue where the WebSocket Book stream continued sending prices with an outdated tick size after market parameter changes. * Resolved an issue where negative spreads in the **Market Data API** were not handled correctly. * Resolved an issue where orders could not be created when using the default 24/7 calendar. * Resolved an issue where the `/external-orders` API returned `null` for `rejectReason` although the Trading Server received a reason from the LP. Customize your Trading Terminal and configure settings Customize your Trading Terminal and configure settings Explore and manage all available trading widgets Explore and manage all available trading widgets Learn basic terms and values used across the platform Learn basic terms and values used across the platform The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](trading) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `V` — Market Data Request (Client → B2TRADER) * `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER) * `X` — Market Data — Incremental Refresh (Client ← B2TRADER) * `Y` — Market Data Request Reject (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Market Data session, use the following parameters provided by B2TRADER: * **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint) * **SenderCompID**: Your client identifier for the Market Data session * **TargetCompID**: The server identifier for the Market Data session * **Protocol**: FIX 4.4 The Market Data connection does not require SSL. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request. ```text title="Example" 8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Optional. ```text title="Example" 8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^ ``` *** ## Market Data Request (V) [#market-data-request-v] This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol. After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update. To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout. **`262 MDReqID`** `String` The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard. **`263 SubscriptionRequestType`** `int` The type of response expected from the server. Required. Possible values: * `1` — Subscribe: receive updates as the market status changes * `2` — Unsubscribe: stop streaming market data for the specified symbol **`264 MarketDepth`** `int` The market depth for an order book snapshot. Required. Possible values: * `0` — Full order book * `1` — Top-of-the-book prices **`265 MDUpdateType`** `int` The update type. Required. Must be `1` (incremental updates for changed price levels only). **`267 NoMDEntryTypes`** `int` The number of `<269>` MDEntryType entries requested. Required. > Repeating group: **`269 MDEntryType`** `int` The side of the quote. Required. Possible values: * `0` — Bid * `1` — Ask **`146 NoRelatedSym`** `int` The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each. > Repeating group: **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```text title="Example (Client → B2TRADER)" 8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^ ``` ## Market Data — Snapshot/Full Refresh (W) [#market-data--snapshotfull-refresh-w] This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^ ``` ## Market Data — Incremental Refresh (X) [#market-data--incremental-refresh-x] This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`262 MDReqID`** `String` The identifier of the originating Market Data Request. **`268 NoMDEntries`** `int` The number of market data entries following. The value is `0` if the order book is empty. > Repeating group (present when `<268>` NoMDEntries > 0): **`269 MDEntryType`** `int` The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — Bid * `1` — Ask **`270 MDEntryPx`** `Price` The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`271 MDEntrySize`** `Qty` The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`. **`278 MDEntryID`** `String` A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`. * Must be unique among active entries when `<279>` MDUpdateAction is `0` (New) * Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete) **`279 MDUpdateAction`** `int` The update type. Conditional — required if `<268>` NoMDEntries is not `0`. Possible values: * `0` — New * `1` — Change * `2` — Delete **`58 Text`** `String` Additional context. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^ ``` ## Market Data Request Reject (Y) [#market-data-request-reject-y] This message is sent by the server to reject a Market Data Request due to business or technical reasons. **`262 MDReqID`** `String` The identifier of the rejected Market Data Request. Required. **`281 MDReqRejReason`** `int` The reason why the request is rejected. Optional. Possible values: * `0` — Unknown symbol * `1` — Duplicate MDReqID * `2` — Insufficient bandwidth * `3` — Insufficient permissions * `4` — Unsupported SubscriptionRequestType * `5` — Unsupported MarketDepth * `6` — Unsupported MDUpdateType * `8` — Unsupported MDEntryType **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^ ``` The Trading session enables order placement and execution management via the FIX 4.4 protocol. Use this session to submit orders and receive real-time execution reports for your trading activity. For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker. This page covers the **Trading** session only. For real-time order book streaming, use the [Market Data](market-data) session. ## Supported message types [#supported-message-types] The following values can be assigned to the `<35>` MsgType field: * `A` — Logon (Client → B2TRADER) * `0` — Heartbeat (Client ↔ B2TRADER) * `1` — Test Request (Client ↔ B2TRADER) * `3` — Reject (Client ← B2TRADER) * `4` — Sequence Reset (Client ↔ B2TRADER) * `5` — Logout (Client ↔ B2TRADER) * `D` — New Order Single (Client → B2TRADER) * `8` — Execution Report (Client ← B2TRADER) * `j` — Business Reject (Client ← B2TRADER) ## Getting started [#getting-started] ### Connection [#connection] To connect to the Trading session, use the following parameters provided by B2TRADER: * **Host and port**: The Trading endpoint (provided separately from the Market Data endpoint) * **SenderCompID**: Your client identifier for the Trading session * **TargetCompID**: The server identifier for the Trading session * **Protocol**: FIX 4.4 The Trading connection requires SSL with a self-signed certificate. ### Message structure [#message-structure] **Standard Header** All FIX messages must begin with a Standard Header containing the following fields: **`8 BeginString`** `String` Identifies the FIX version (`FIX.4.4`). Always the first field in a message. **`9 BodyLength`** `int` The automatically computed message length, in bytes. Always the second field. **`35 MsgType`** `String` The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field. **`34 MsgSeqNum`** `int` The message sequence number, incremented by 1 for each consecutive message. **`49 SenderCompID`** `String` The identifier of the message sender. Provided by B2TRADER. **`52 SendingTime`** `Timestamp` The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`. **`56 TargetCompID`** `String` The identifier of the message recipient. Provided by B2TRADER. *** **Standard Trailer** All FIX messages must end with a Standard Trailer: **`10 CheckSum`** `int` A three-digit checksum. Always the last field in a message. ### Logon (A) [#logon-a] This message is sent by the client to initiate a FIX session. It must be the first message in each connection. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`98 EncryptMethod`** `int` The encryption method. Required. Must be `0` (no encryption). **`108 HeartBtInt`** `int` The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check. **`141 ResetSeqNumFlag`** `Boolean` Indicates whether both parties should reset the currently used sequence numbers. Optional. **`553 Username`** `String` The client username. Required. Provided by B2TRADER. **`554 Password`** `String` The client password. Required. Provided by B2TRADER. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=117^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=117^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=93^35=A^1=68a4446ac84827ff5cd35c74^34=225^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=054^ ``` ### Session maintenance [#session-maintenance] #### Heartbeat (0) [#heartbeat-0] This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages. **`112 TestReqID`** `String` The identifier of a Test Request in response to which this Heartbeat is sent. Conditional — required when sent in response to a Test Request. ```text title="Example" 8=FIX.4.4^9=79^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=156^ ``` #### Test Request (1) [#test-request-1] This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID. **`112 TestReqID`** `String` The identifier of a Test Request. Required. ```text title="Example" 8=FIX.4.4^9=87^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=250^ ``` #### Sequence Reset (4) [#sequence-reset-4] This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable. **`123 GapFillFlag`** `Boolean` Indicates that this message replaces missing messages that won't be resent. Optional. Possible values: * `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range * `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations **`36 NewSeqNo`** `int` The new sequence number. Required. ```text title="Example" 8=FIX.4.4^9=90^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=176^ ``` #### Logout (5) [#logout-5] This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field. **`58 Text`** `String` The detailed information about the reason for logging out. Optional. ```text title="Request (Client → B2TRADER)" 8=FIX.4.4^9=105^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=Session terminated by client^10=183^ ``` ```text title="Response (B2TRADER → Client)" 8=FIX.4.4^9=81^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=009^ ``` ### Reject (3) [#reject-3] This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field. This message is unrelated to application-level rejections (Execution Report with rejected status and Business Reject). **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`371 RefTagID`** `int` The tag number of the field that caused message rejection. Optional. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`373 SessionRejectReason`** `int` The reason why the message is rejected. Optional. Possible values: * `0` — Invalid tag number * `1` — Required tag missing * `2` — Tag not defined for this message type * `3` — Undefined tag * `4` — Tag has no value assigned * `5` — Value is incorrect (out of range) for this tag * `6` — Incorrect value data format * `7` — Decryption issue * `8` — Signature problem * `9` — CompID issue * `10` — SendingTime accuracy issue * `11` — Invalid MsgType * `12` — XML validation error * `13` — Same tag appears more than once * `14` — Tag specified not in required order * `15` — Wrong order of repeating group fields * `16` — Incorrect NumInGroup count for repeating group * `17` — Non-"Data" value includes field delimiter (SOH character) * `99` — Other **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=128^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=11^372=D^373=1^58=Required tag missing: ClOrdID^10=126^ ``` *** ## New Order Single (D) [#new-order-single-d] This message is sent by the client to place a new order. The server responds with an Execution Report confirming the order status. For details on supported order types, see [Order types](../get-started/order-types). For details on time-in-force options, see [Time in force](../get-started/time-in-force). **`11 ClOrdID`** `String` The unique client-assigned order identifier. Required. **`1 Account`** `String` The account identifier. Required. Provided by B2TRADER. **`55 Symbol`** `String` The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`38 OrderQty`** `Qty` The order quantity. Required. Must be greater than zero. The decimal precision must not exceed the market's amount scale, and the value must be at least the market's minimum amount. **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`59 TimeInForce`** `char` The order's time-in-force policy. Required. Possible values: * `0` — Day * `1` — Good Till Cancel (GTC) * `3` — Immediate or Cancel (IOC) * `4` — Fill or Kill (FOK) * `6` — Good Till Date (GTD) **`44 Price`** `Price` The order price. Conditional — required when `<40>` OrdType is `2` (Limit), must not be present when `<40>` OrdType is `1` (Market). Must be greater than zero. The decimal precision must not exceed the market's price scale. **`126 ExpireTime`** `UTCTimestamp` The order expiration time. Conditional — required when `<59>` TimeInForce is `6` (GTD), must not be present otherwise. **`60 TransactTime`** `UTCTimestamp` The time of order creation. Required. ```text title="Limit order example (Client → B2TRADER)" 8=FIX.4.4^9=168^35=D^34=3^52=20231220-09:15:30.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order001^55=spot.btc_usdt^54=1^38=0.5^40=2^44=42500.00^59=1^60=20231220-09:15:30.000^10=123^ ``` ```text title="Market order example (Client → B2TRADER)" 8=FIX.4.4^9=155^35=D^34=4^52=20231220-09:16:00.000^49=sender_b2trader^56=target_b2trader^1=68a4446ac84827ff5cd35c74^11=order002^55=spot.btc_usdt^54=2^38=0.1^40=1^59=3^60=20231220-09:16:00.000^10=045^ ``` ## Execution Report (8) [#execution-report-8] This message is sent by the server to confirm order status changes, including acknowledgment of new orders, fills, partial fills, cancellations, and rejections. For details on order statuses, see [Order statuses](../get-started/order-statuses). **`37 OrderID`** `String` The server-assigned unique order identifier. Required. **`11 ClOrdID`** `String` The client-assigned order identifier from the original New Order Single. Required. **`17 ExecID`** `String` The unique execution identifier. Present for trade executions. **`150 ExecType`** `char` The type of execution being reported. Required. Possible values: * `0` — New: order has been accepted * `4` — Canceled: order has been canceled by the server (e.g., IOC order partially filled, GTD order expired, or market settings changed) * `8` — Rejected: order has been rejected * `F` — Trade: order has been partially or fully filled **`39 OrdStatus`** `char` The current order status. Required. Possible values: * `0` — New * `1` — Partially filled * `2` — Filled * `4` — Canceled * `8` — Rejected **`1 Account`** `String` The account identifier. Required. **`55 Symbol`** `String` The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`. **`54 Side`** `char` The order side. Required. Possible values: * `1` — Buy * `2` — Sell **`40 OrdType`** `char` The order type. Required. Possible values: * `1` — Market * `2` — Limit **`44 Price`** `Price` The order price. Present for Limit orders. **`6 AvgPx`** `Price` The average price of all fills on this order. Required. **`14 CumQty`** `Qty` The total filled quantity. Required. **`151 LeavesQty`** `Qty` The remaining quantity to be filled. Required. Set to `0` for Canceled or Rejected orders. **`31 LastPx`** `Price` The price of the last fill. Present when `<150>` ExecType is `F` (Trade). **`32 LastQty`** `Qty` The quantity of the last fill. Present when `<150>` ExecType is `F` (Trade). **`15 Currency`** `String` The quote asset identifier. Optional. **`60 TransactTime`** `UTCTimestamp` The transaction time. Required. **`64 SettlDate`** `String` The settlement date in `YYYYMMDD` format. Required. **`58 Text`** `String` Additional information, such as the rejection reason. Optional. ```text title="New order accepted (B2TRADER → Client)" 8=FIX.4.4^9=220^35=8^34=5^52=20231220-09:15:30.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^150=0^39=0^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=0^14=0^151=0.5^60=20231220-09:15:30.100^64=20231220^10=087^ ``` ```text title="Trade execution (B2TRADER → Client)" 8=FIX.4.4^9=245^35=8^34=6^52=20231220-09:15:30.200^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YP^11=order001^17=01HBXK5V3R8NQ7YR^150=F^39=2^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=1^40=2^44=42500.00^6=42500.00^14=0.5^151=0^31=42500.00^32=0.5^15=usdt^60=20231220-09:15:30.200^64=20231220^10=154^ ``` ```text title="Order rejected (B2TRADER → Client)" 8=FIX.4.4^9=214^35=8^34=7^52=20231220-09:16:00.100^49=target_b2trader^56=sender_b2trader^37=01HBXK5V3R8NQ7YS^11=order002^150=8^39=8^1=68a4446ac84827ff5cd35c74^55=spot.btc_usdt^54=2^40=1^6=0^14=0^151=0^58=Insufficient balance^60=20231220-09:16:00.100^64=20231220^10=201^ ``` ## Business Reject (j) [#business-reject-j] This message is sent by the server to reject a message due to a business-level issue not addressed by the standard session-level Reject or Execution Report rejection. **`45 RefSeqNum`** `int` The sequence number of the rejected message (`<34>` MsgSeqNum). Required. **`372 RefMsgType`** `String` The type of the rejected message (`<35>` MsgType). Optional. **`380 BusinessRejectReason`** `int` The reason why the request is rejected. Required. Possible values: * `0` — Other * `1` — Unknown ID * `2` — Unknown Security * `3` — Unsupported MsgType * `4` — Application not available * `5` — Conditionally required field missing * `6` — Not authorized * `7` — DeliverTo firm not available at this time **`58 Text`** `String` The detailed information about the rejection reason. Optional. ```text title="Example (B2TRADER → Client)" 8=FIX.4.4^9=100^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=006^ ``` Each trading account has an `accountStatus` field that determines which operations are permitted on the account. The field is returned on account objects by the API, such as in [Get accounts](../rest-api/settings). An account can be assigned one of the following statuses: * **Active**: All operations are permitted, including placing, modifying, and canceling orders, opening and closing positions, deposits, and withdrawals. * **Halted**: Trader-initiated trading is blocked. Requests to place, modify, or cancel orders and to open or close positions are rejected. Deposits and withdrawals remain allowed. Managed trading through the Management API (MAM, B2COPY) continues to work. * **Frozen**: All operations are blocked. Trading, deposits, and withdrawals are unavailable, and the account is view-only. Stop-out liquidation still executes as a safety mechanism. * **Archived**: The account is decommissioned and hidden from all user-facing surfaces. Real-time profit and loss, equity, margin level, and funding settlement continue for all statuses. Archived accounts are never returned in the trading API account list. They are excluded server-side, so an account that changes to *Archived* stops appearing in [Get accounts](../rest-api/settings) responses. A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. ## Introduction [#introduction] B2TRADER provides developers with three distinct methods for data delivery, each optimized for specific use cases and performance requirements: REST, WebSocket, and FIX APIs. The **REST API** provides read access to market data as well as both read and write access to trading operations. It serves as the foundation for synchronous data operations where immediate confirmation and guaranteed delivery are essential. The **WebSocket API** provides access to public market data streaming as well as private account updates. It delivers real-time updates with low latency, making it ideal for live trading environments. The **FIX API** provides direct access to market data and trading via the FIX 4.4 protocol. It is designed for institutional clients and algorithmic trading systems that require standardized, low-latency connectivity using the industry-standard Financial Information eXchange protocol. This approach provides developers with flexible options for building robust, scalable trading applications that can handle both operational requirements and real-time market dynamics. ### When to use REST API [#when-to-use-rest-api] * **Account configuration and settings**: Managing user preferences and system configurations. * **Order placement and modification**: Creating, updating, and canceling trading orders. * **Historical data retrieval**: Accessing past trading records and market data. * **One-time data requests**: Retrieving specific information that doesn't require continuous updates. * **Administrative operations**: Account management and system administration tasks. ### When to use WebSocket API [#when-to-use-websocket-api] * **Real-time price monitoring**: Live market price feeds and ticker updates. * **Live position tracking**: Continuous monitoring of open and closed positions. * **Order book visualization**: Real-time depth of market data. * **Market data feeds**: Streaming market statistics and trading activity. * **Account balance monitoring**: Live updates of account equity and margin status. ### When to use FIX API [#when-to-use-fix-api] * **Institutional connectivity**: Standardized FIX 4.4 protocol for professional trading infrastructure. * **Algorithmic trading**: Low-latency order execution and market data for automated strategies. * **Market data streaming**: Real-time order book snapshots and incremental updates via FIX protocol. * **Multi-venue integration**: Unified FIX connectivity for systems already integrated with other FIX-based venues. ## General considerations [#general-considerations] The following applies to all interface descriptions provided in this documentation: * **Endpoints**: All endpoints are relative and resolved based on a specified hostname (indicated as `{host}`). * **Authentication**: REST and WebSocket APIs require an access token (see [Authentication](#authentication)). The FIX API uses in-band authentication via the Logon message with Username, Password, and Account fields provided by B2TRADER. * **Data format**: REST and WebSocket APIs return results in JSON format. The FIX API uses the standard FIX 4.4 message format. * **Security**: All communications use secure protocols (HTTPS for REST, WSS for WebSocket, encrypted TCP for FIX). ### Authentication [#authentication] API access requires an access token for both REST and WebSocket connections. Authentication follows a two-step process: 1. Generate an offline token in the Trading terminal. 2. Exchange the offline token for an access token via API call. #### Token types [#token-types] **Offline token** * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time * **Purpose**: Generate access tokens **Access token** * **Type**: Bearer token * **Validity**: 60 minutes * **Purpose**: Authorize API requests ### Generate offline token [#generate-offline-token] To generate an offline token: 1. In the Trading terminal, open **Settings** and select **API token management**. 2. Click **+ Create new**. 3. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 4. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ### Obtain access token [#obtain-access-token] Request an access token using your offline token. **Endpoint**: `POST` `/frontoffice/api/v4/access-token` **Request body**: ```json { "token": "{YOUR_OFFLINE_TOKEN}" } ``` **Response** (Success): ```json { "accessToken": "{YOUR_ACCESS_TOKEN}", "expiresIn": 3600, "tokenType": "Bearer" } ``` **`accessToken`** `string` The access token for API authorization. **`expiresIn`** `integer` The token lifetime, in seconds. **`tokenType`** `string` The authentication type, always `"Bearer"`. ### Using access tokens [#using-access-tokens] Include the access token in API requests: ```http title="REST" Authorization: Bearer {YOUR_ACCESS_TOKEN} ``` ```http title="WebSocket" {URL}?access_token={YOUR_ACCESS_TOKEN} ``` Access tokens must be refreshed before expiration by repeating the Step 2 with your offline token. ## REST API: Synchronous data operations [#rest-api-synchronous-data-operations] The REST API serves as the foundation for synchronous data operations within the B2TRADER platform. This approach follows standard HTTP protocols and is ideal for operations requiring immediate confirmation and guaranteed delivery. ### Key characteristics [#key-characteristics] * **Request-response operations** where immediate confirmation is required. * **Account management** including settings and configuration. * **Order placement and modification** with guaranteed delivery. * **Historical data retrieval** for analysis and reporting. * **Stateless operations** that don't require persistent connections. ### HTTP response codes [#http-response-codes] B2TRADER API uses conventional HTTP response codes to indicate the success or failure of requests. **Success codes:** * `200 OK` — Request successful **Error codes:** * `400 Bad Request` — Invalid request parameters * `401 Unauthorized` — Authentication required * `403 Forbidden` — Insufficient permissions * `404 Not Found` — Resource not found * `429 Too Many Requests` — [Rate limit](#rate-limits) exceeded * `500 Internal Server Error` — Server error In case of an error, an object will be returned with the following structure: ```json { "code": "text", "message": "text", "details": { "source": "text", "message": "text", "stackTrace": "text" } } ``` ### Available endpoints [#available-endpoints] * **[Trading operations](../rest-api/trading)**: Create, modify, and cancel orders; open, close, and modify positions; control price trigger settings. * **[Trading history](../rest-api/history)**: Retrieve detailed execution records for positions and orders. * **[Settings and configurations](../rest-api/settings)**: Access account information, market specifications, trading sessions, and asset details. ### Rate limits [#rate-limits] Rate limits are applied per minute for each unique **AccountId** to ensure fair resource usage and maintain optimal API performance. All limits use the **Fixed Window** strategy. When rate limits are exceeded, the API returns a `429 Too Many Requests` HTTP status code. #### Trading methods [#trading-methods] * **Default limit**: 600 requests per minute for all methods. * **Reduced limit (200 rpm)** applies to: * Get order data methods * Bulk close positions method * Price triggers methods #### History methods [#history-methods] * **All request types**: 60 requests per minute. #### Settings methods [#settings-methods] * **GET requests**: 100 requests per minute. * **POST and DELETE requests**: 60 requests per minute. Rate limits are calculated independently for each method category. For example, you can make 100 GET requests to Settings methods and 60 requests to History methods within the same minute without hitting rate limits. ## WebSocket API: Real-time data streaming [#websocket-api-real-time-data-streaming] The WebSocket API delivers real-time updates with minimal latency, essential for modern trading applications. The implementation uses unidirectional communication from server to client, ensuring efficient data delivery. ### Key characteristics [#key-characteristics-1] * **Unidirectional communication** from server to client for optimal performance. * **Real-time market data** for live trading environments. * **Position and order updates** as they occur in real-time. * **Low-latency data delivery** for time-sensitive trading operations. * **Persistent connections** maintaining continuous data flow. ### SignalR implementation [#signalr-implementation] B2TRADER utilizes **AspNetCore SignalR** for WebSocket message organization and transmission, providing a robust and scalable real-time communication framework. **Resources:** * [Official GitHub Repository](https://github.com/dotnet/aspnetcore/tree/main/src/SignalR) * [Official Documentation](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr) SignalR provides a structured approach to real-time communication through standardized message formatting and connection management. ### Connection lifecycle [#connection-lifecycle] The data transfer process consists of two essential phases: 1. **Connection establishment** — Initial handshake, authentication, and subscription setup. 2. **Data streaming** — Continuous real-time data flow with automatic reconnection handling. ### Message types [#message-types] SignalR utilizes numerical `type` indicators for different operations: ### Available stream types [#available-stream-types] * **[Trading streams](../ws-api/trading)**: Track active orders, open and closed positions. * **[Market data streams](../ws-api/market-data)**: Get real-time order book updates, market statistics and price changes. * **[Account information streams](../ws-api/account-info)**: Get live account balance and margin updates. ## FIX API: Standardized protocol connectivity [#fix-api-standardized-protocol-connectivity] The FIX API provides direct access to B2TRADER via the FIX 4.4 protocol, the industry standard for electronic trading communication. It is designed for institutional clients and algorithmic trading systems. ### Key characteristics [#key-characteristics-2] * **FIX 4.4 protocol** for standardized, vendor-neutral connectivity. * **Dedicated sessions** for Market Data and Trading with separate endpoints. * **In-band authentication** via Logon message (Username, Password, Account). * **Real-time market data** with order book snapshots and incremental updates. * **Session management** with Heartbeat, Test Request, and Sequence Reset support. ### Authentication [#authentication-1] Unlike REST and WebSocket APIs, the FIX API does not use access tokens. Authentication is performed in-band as part of the FIX Logon message using credentials provided by B2TRADER: * **Username** (`<553>`): The client username * **Password** (`<554>`): The client password * **Account** (`<1>`): The account identifier ### Available session types [#available-session-types] * **[Market Data](../fix-api/market-data)**: Subscribe to real-time order book updates, snapshots, and incremental refreshes. * **[Trading](../fix-api/trading)**: Place orders and receive execution reports in real time. ## Integration best practices [#integration-best-practices] ### API selection strategy [#api-selection-strategy] * Use **REST API** for operational tasks requiring confirmation (order placement, account management). * Use **WebSocket API** for real-time monitoring and market data visualization. * Use **FIX API** for institutional connectivity, algorithmic trading, and integration with existing FIX-based infrastructure. * Implement multiple APIs in comprehensive trading applications for optimal functionality. ### Performance optimization [#performance-optimization] * Implement proper connection pooling for REST API requests. * Use WebSocket subscriptions efficiently by subscribing only to required data streams. * Handle reconnection logic for WebSocket connections to ensure data continuity. * Implement appropriate error handling and retry mechanisms. ### Security considerations [#security-considerations] * Store authentication tokens securely and implement token refresh mechanisms. * Use secure connections (HTTPS/WSS) for all API communications. * Implement proper input validation and sanitization. * Monitor API usage and implement rate limiting on the client side. This comprehensive API architecture enables developers to build sophisticated trading applications that can handle both real-time market dynamics and operational trading requirements efficiently. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all Limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to Limit and Stop Limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the platform, without taking into account the time settings of the devices from which the platform is accessed. ## Get full balance [#get-full-balance] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"FullBalance"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "FullBalance", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of balance objects. **`item.assetId`** `string` The asset identifier. **`item.available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`item.total`** `decimal string` The overall amount of the asset, including locked funds. **`item.locked`** `decimal string` The asset amount locked on the account for execution of all placed Limit orders. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "assetId": "eur", "available": "497838.8", "total": "497838.8", "locked": "0" } ] } ``` ## Get margin data [#get-margin-data] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v3/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"MarginData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "MarginData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.marginBalanceInRAT`** `decimal string` The total amount of funds that can be used as a collateral for trading, in RAT. This value is calculated as SUM (*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*) Where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the BP root asset. **`item.creditInRAT`** `decimal string` The promotional trading credit granted to the account by the broker, in RAT. Credit is included in the account equity but excluded from the withdrawable amount. During a rolling deployment, older payloads might omit this field. In that case, default it to `0`. **`item.unrealizedPnlInRAT`** `decimal string` The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) **`item.equityInRAT`** `decimal string` The potential balance if all open positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. **`item.usedMarginInRAT`** `decimal string` The amount of funds that is used for maintaining all open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **`item.freeMarginInRAT`** `decimal string` The amount of funds that can be used for opening new positions. **`item.marginLevel`** `decimal string` The ratio of funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "marginBalanceInRAT": "497838.8", "creditInRAT": "0", "unrealizedPnlInRAT": "-5.25", "equityInRAT": "497833.55", "usedMarginInRAT": "100.18", "freeMarginInRAT": "497733.37", "marginLevel": "4969.3905" } } ``` ## Get order book [#get-order-book] ### Connection [#connection] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Book"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eur_chf" ], "invocationId": "0", "target": "Book", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.askTotalAmount`** `string` The total ask amount. **`item.bidTotalAmount`** `string` The total bid amount. **`item.asks`** `array of objects` The array of ask price objects. **`item.asks.price`** `string` The price, in the quote asset. **`item.asks.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.asks.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.bids`** `array of objects` The array of bid price objects. **`item.bids.price`** `string` The price, in the quote asset. **`item.bids.amount`** `string` The total amount of the base asset available at a corresponding price level. **`item.bids.total`** `string` The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. **`item.version`** `string` The order book version. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eur_chf", "askTotalAmount": "18700000", "bidTotalAmount": "19100000", "asks": [ { "price": "0.93677", "amount": "5000000", "total": "4683850" }, { "price": "0.93676", "amount": "0", "total": "0" }, { "price": "0.93676", "amount": "0", "total": "0" } ], "bids": [ { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93654", "amount": "0", "total": "0" }, { "price": "0.93655", "amount": "5000000", "total": "4682750" } ], "version": "12498", "snapshot": false } } ``` ## Get trading data [#get-trading-data] ### Connection [#connection-1] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"TradingData"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.bnb_btc" ] ], "invocationId": "0", "target": "TradingData", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.markets.displayName`** `string` The market ticker. **`item.markets.fullName`** `string` The market full name or description (optional). **`item.markets.price`** `decimal string` The current top-of-the-book price, in the quote asset. **`item.markets.priceInRAT`** `decimal string` The current top-of-the-book price, in conversion to the root asset of the platform. **`item.markets.priceChange24hr`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.markets.priceChangeAbs24hr`** `decimal string` The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. **`item.markets.highPrice24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.markets.lowPrice24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.markets.markPrice`** `decimal string` *Applicable to Perpetual markets only.* The mid-spread price, in conversion to RAT. **`item.markets.fundingRate`** `decimal string` *Applicable to Perpetual markets only.* The current funding rate. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "cfd.eur_chf", "type": "Cfd", "displayName": "cfd.eur_chf", "fullName": "", "price": "0.93586", "priceInRAT": "1", "priceChange24hr": "-0.0006", "priceChangeAbs24hr": "-0.00049", "highPrice24hr": "0.93695", "lowPrice24hr": "0.93134", "markPrice": null, "fundingRate": null } ], "snapshot": false } } ``` ## Get top of the book [#get-top-of-the-book] ### Connection [#connection-2] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Tob"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "spot.eth_usdt" ] ], "invocationId": "0", "target": "Tob", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.markets`** `array of objects` The array of market objects. **`item.markets.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.markets.ask`** `decimal string` The top-of-the-book ask price. **`item.markets.bid`** `decimal string` The top-of-the-book bid price. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "markets": [ { "marketId": "spot.eth_usdt", "ask": "2483.82", "bid": "2483.81" } ], "snapshot": false } } ``` ## Get trading chart [#get-trading-chart] ### Connection [#connection-3] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide the `marketId` and `timescale` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Chart"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", "cfd.eth_eur@15m" ], "invocationId": "0", "target": "Chart", "type": 4 } ``` *** ### Message [#message-3] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.instrument`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.low`** `decimal string` The lowest base asset price within the specified time interval. **`item.high`** `decimal string` The highest base asset price within the specified time interval. **`item.open`** `decimal string` The base asset price at the beginning of the specified time interval. **`item.close`** `decimal string` The base asset price at the end of the specified time interval. **`item.start`** `dateTime` The beginning of the specified time interval, in ISO 8601 format. **`item.end`** `dateTime` The end of the specified time interval, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "instrument": "cfd.eth_eur", "low": "2240.88", "high": "2270.29", "open": "2265.63", "close": "2255.99", "start": "2025-05-21T15:30:00Z", "end": "2025-05-21T15:45:00Z" } } ``` ## Get market summary [#get-market-summary] ### Connection [#connection-4] ```text title="URL" /marketdata/v5/info?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. In the second element, provide a list of `marketIds` as an array of strings. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"Summary"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46", [ "cfd.eur_chf" ] ], "invocationId": "0", "target": "Summary", "type": 4 } ``` *** ### Message [#message-4] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.items`** `array of objects` The array of data objects. **`item.items.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.items.last`** `decimal string` The price of the last trade. **`item.items.high24hr`** `decimal string` The highest trade price over the last 24 hours. **`item.items.low24hr`** `decimal string` The lowest trade price over the last 24 hours. **`item.items.percentChange`** `decimal string` The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. **`item.snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "items": [ { "marketId": "cfd.eur_chf", "last": "0.93597", "high24hr": "0.93695", "low24hr": "0.93134", "percentChange": "-0.02" } ], "snapshot": false } } ``` ## Get open orders [#get-open-orders] ### Connection [#connection] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenOrders", "type": 4 } ``` *** ### Message [#message] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of market objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.status`** `string` The current [order status](../get-started/order-statuses). Possible values: * `Started` * `Pending` * `Working` **`item.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`item.reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`item.remainingAmount`** `decimal string` The order amount that hasn't yet been filled, in the base asset. **`item.requestedPrice`** `decimal string` The limit price for Limit orders; `null` for Market orders. **`item.executionPrice`** `decimal string` The volume-weighted average price of the order executions. **`item.createdAt`** `dateTime` The timestamp when the order was created, in ISO 8601 format. **`item.updatedAt`** `dateTime` The timestamp of the most recent update to the order, in ISO 8601 format. **`item.cancellationDate`** `dateTime` The timestamp when the order was cancelled or expired, in ISO 8601 format; `null` if not cancelled. **`item.commissionAssetId`** `string` The currency in which the commission was held. **`item.commissionAmount`** `decimal string` The total commissions put on hold for executing the order. **`item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when placing the order. **`item.fillFactor`** `decimal string` The proportion of the order amount filled so far, where `1` represents 100% fulfillment. **`item.comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.stopLoss`** `decimal string` The Stop Loss price, if set. ```json { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "orderId": "01JVQBFSTVC40VK03A0AY7K016", "timeInForce": "Gtc", "status": "Pending", "source": "Manual", "reason": "Trader", "side": "Buy", "orderType": "Limit", "requestedAmount": "10000", "remainingAmount": "10000", "requestedPrice": "0.9", "executionPrice": "0", "createdAt": "2025-05-20T17:22:31.899Z", "updatedAt": "2025-05-20T17:22:31.9001213Z", "cancellationDate": null, "commissionAssetId": "eur", "commissionAmount": "0", "leverage": 1, "fillFactor": "0", "takeProfit": null, "stopLoss": null, "comment": null } ] } ``` ## Get open positions [#get-open-positions] ### Connection [#connection-1] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"OpenPositions"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "OpenPositions", "type": 4 } ``` *** ### Message [#message-1] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `object` The dataset object. **`item.item`** `array of objects` The array of position objects. **`item.item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.item.marketDisplayName`** `string` The market ticker. **`item.item.marketFullName`** `string` The market full name or description (optional). **`item.item.createdAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. **`item.item.updatedAt`** `dateTime` The timestamp of the most recent update to the position, in ISO 8601 format. **`item.item.side`** `string` The position side. Possible values: * `Buy` * `Sell` **`item.item.status`** `string` The current position status. Always `"Open"`. **`item.item.leverage`** `int` *Applicable only to CFD markets.* The leverage ratio used when opening the position. **`item.item.positionLotAmount`** `decimal string` The position volume, in lots. **`item.item.positionPriceInRAT`** `decimal string` The current position price, in conversion to RAT. **`item.item.rateToRAT`** `decimal string` The current exchange rate of a quote asset to RAT. **`item.item.usedMarginInRAT`** `decimal string` The amount of trader’s funds used for maintaining a position, in conversion to RAT. **`item.item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.item.currentMarketPrice`** `decimal string` The current market price of the base asset: bid for Long positions and ask for Short positions. **`item.item.unrealizedPnlDayInRAT`** `decimal string` The potential profit or loss earned for a current day, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. **`item.item.unrealizedPnlDayPercent`** `decimal string` The potential profit or loss earned for a current day, in percents. **`item.item.unrealizedPnlTotalInRAT`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). **`item.item.unrealizedPnlTotalPercent`** `decimal string` The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to RAT, in percents. **`item.item.takeProfit`** `decimal string` The Take Profit price, if set. **`item.item.stopLoss`** `decimal string` The Stop Loss price, if set. **`item.item.positionModifier`** `string` The reason for the latest position update. **`item.item.comment`** `string | nullable` The text note inherited from the opening order, up to 100 characters. **`snapshot`** `boolean` The data snapshot. If `snapshot: true`, it indicates the message contains the full dataset. Subsequent messages with `snapshot: false` only include updates or changes since the initial snapshot. ```json title="Example" { "type": 2, "invocationId": "0", "item": { "item": [ { "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-03-12T06:36:31.257Z", "updatedAt": "2025-03-12T06:36:31.257Z", "side": "Buy", "status": "Open", "leverage": 1, "positionLotAmount": "0.01", "positionPriceInRAT": "1000.46", "rateToRAT": "1.07", "usedMarginInRAT": "1000.53", "openPrice": "0.96304", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "1.86", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-29.93", "unrealizedPnlTotalPercent": "-0.0291", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null }, { "positionId": "01JVQB9ZWJ6G4QV0P98X0QWNA7", "marketId": "cfd.eur_chf", "marketType": "Cfd", "marketDisplayName": "EUR/CHF", "marketFullName": "", "createdAt": "2025-05-20T17:19:21.49Z", "updatedAt": "2025-05-20T17:19:21.491321Z", "side": "Buy", "status": "Open", "leverage": 100, "positionLotAmount": "0.1", "positionPriceInRAT": "10004.6", "rateToRAT": "1.07", "usedMarginInRAT": "100.06", "openPrice": "0.93666", "currentMarketPrice": "0.93501", "unrealizedPnlDayInRAT": "18.61", "unrealizedPnlDayPercent": "0.0018", "unrealizedPnlTotalInRAT": "-17.02", "unrealizedPnlTotalPercent": "-0.0017", "takeProfit": null, "stopLoss": null, "positionModifier": "Trader", "comment": null } ], "snapshot": false } } ``` ## Get closed positions [#get-closed-positions] ### Connection [#connection-2] ```text title="URL" /frontoffice/ws/v4/account?access_token={YOUR_ACCESS_TOKEN} ``` **`arguments`** `array` The connection parameters. In the first element, provide the `accountId` as a string. **`invocationId`** `string` The invocation identifier. Must be unique and increase by 1 for each sent message. **`target`** `string` The stream name. Specify `"ClosePositionsOrders"`. **`type`** `int` The operation type. Set to `4` to indicate a subscription to the stream. ```json title="Example" { "arguments": [ "67d0456f8c7b1108e4cf5d46" ], "invocationId": "0", "target": "ClosePositionsOrders", "type": 4 } ``` *** ### Message [#message-2] **`type`** `string` The operation type. `2` indicates the streaming is in progress. **`invocationId`** `string` The invocation identifier. Same as in the request. **`item`** `array of objects` The array of position objects. **`item.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`item.marketType`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`item.marketDisplayName`** `string` The market ticker. **`item.marketFullName`** `string` The market full name or description (optional). **`item.orderId`** `string` The unique identifier of the order assigned by the system. **`item.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`item.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`item.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`item.positionCloseLotAmount`** `decimal string` The closed volume, in lots, which is equivalent to the corresponding filled order volume. **`item.reason`** `string` The reason for position closing. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`item.realizedPnlInRAT`** `decimal string` The actual profit or loss earned, in conversion to RAT. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). **`item.closedAt`** `dateTime` The timestamp when the position was closed, in ISO 8601 format. **`item.positionId`** `string` The unique identifier of the position assigned by the system. **`item.openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`item.closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`item.positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`item.rateToRAT`** `decimal string` The conversion rate to RAT. **`item.openedAt`** `dateTime` The timestamp when the position was opened, in ISO 8601 format. ```json title="Example" { "type": 2, "invocationId": "0", "item": [ { "marketId": "cfd.eur_chf", "marketFullName": "", "marketDisplayName": "EUR/CHF", "marketType": "Cfd", "orderId": "01JVSQ8WFA3QZ6AQTKYPXVXDWA", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.01", "reason": "Trader", "realizedPnlInRAT": "-29.25", "closedAt": "2025-05-21T15:26:57.0027785Z", "positionId": "01JP4H3AMS7Q1H6Y6H3XJ52JTA", "openPrice": "0.96304", "closePrice": "0.93571", "positionPriceInRAT": "1001.2", "rateToRAT": "1.07", "openedAt": "2025-03-12T06:36:31.257Z" } ] } ``` ## Open positions [#open-positions] ### Get executions for an open position [#get-executions-for-an-open-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/executions/list` #### Summary [#summary] Use this method to retrieve execution details for a specific open position using its position identifier. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`positionId`** `required` The position identifier. ##### Body [#body] **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`offset`** `integer · int32 | nullable` The number of items to skip before starting to collect the result set. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PMT0VMJG5B8XBDNZ7FNM1F/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "offset": 0 } ``` #### Response [#response] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VNWB23GSRN2XQAJD6Q", "baseAmount": "0.314", "executionPrice": "4603.5", "commissionAmountInRAT": "0", "commissions": [], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.293Z", "executionId": "01K2PMT0VN1F2JPM14AEV6V8YJ", "baseAmount": "0.045", "executionPrice": "4603.49", "commissionAmountInRAT": "0", "commissions": [], "comment": null } ] } ``` ### Get executions for open positions [#get-executions-for-open-positions] `POST` `/frontoffice/api/v4/positions/executions/list` #### Summary [#summary-1] Use this method to retrieve execution details for multiple open positions by providing an array of position identifiers. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`positionIds`** `array · string[]` The array of position identifiers. **`limit`** `integer · int32 | nullable` The maximum number of items to return. ```http title="Request example" POST /frontoffice/api/v4/positions/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "positionIds": [ "01K2PMT0VMJG5B8XBDNZ7FNM1F", "01K2PMXY63HESK110WT1CHMAFA" ], "limit": 5 } ``` #### Response [#response-1] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "01K2PMXY63HESK110WT1CHMAFA", "orderId": "01K2PMXY1894RC6E2BYFR00T87", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:38:10.627Z", "executionId": "01K2PMXY63NXM30VNWPDECSFJR", "baseAmount": "15", "executionPrice": "4333.69288", "commissionAmountInRAT": "32.27", "commissions": [ { "assetId": "eur", "amount": "32.27" } ], "comment": null }, { "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "orderId": "01K2PMT0KRRMTTXGPDJCXZ99NZ", "side": "Buy", "reason": "Trader", "createdAt": "2025-08-15T10:36:02.292Z", "executionId": "01K2PMT0VMPCZW0JB2C9J6B405", "baseAmount": "0.141", "executionPrice": "4602.3", "commissionAmountInRAT": "5", "commissions": [ { "assetId": "eur", "amount": "5" } ], "comment": null } ] } ``` ## Closed positions [#closed-positions] ### Get orders for closed positions [#get-orders-for-closed-positions] `POST` `/frontoffice/api/v4/orders/closed-positions` #### Summary [#summary-2] Use this method to retrieve orders associated with closed positions within specified date ranges and market filters. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`createdAtFrom`** `string · date-time | nullable` The start date of the period when the positions were opened. **`createdAtTo`** `string · date-time | nullable` The end date of the period when the positions were opened. **`closedAtFrom`** `string · date-time | nullable` The start date of the period when the positions were closed. **`closedAtTo`** `string · date-time | nullable` The end date of the period when the positions were closed. **`marketId`** `string | nullable` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`marketType`** `string | nullable` The market type. Possible values: * `Cfd` * `Perp` **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastOrderId`** `string | nullable` The identifier of the final order to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/closed-positions HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 2, "createdAtFrom": "2025-08-01T12:00:32.886Z", "createdAtTo": "2025-08-15T12:00:32.886Z" } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier. **`marketFullName`** `string | nullable` The market full name or description (optional). **`marketDisplayName`** `string | nullable` The market ticker. **`marketType`** `string` The market type. Possible values: * `Cfd` * `Perp` **`orderId`** `string` The order identifier. **`orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`timeInForce`** `string` The [time-in-force setting](../get-started/time-in-force) of the order. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`side`** `string` The order side. Possible values: * `Buy` * `Sell` **`positionCloseLotAmount`** `decimal string` The position amount closed by the order, in lots. **`reason`** `string` The reason for placing the order. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`closedAt`** `string · date-time | nullable` The date and time when the position was closed. **`positionId`** `string` The position identifier. **`openPrice`** `decimal string` The volume-weighted average price (VWAP) at which the position was opened. **`closePrice`** `decimal string` The volume-weighted average price (VWAP) of trades related to a position-closing order. **`positionPriceInRAT`** `decimal string` The position price, in conversion to RAT. **`rateToRAT`** `decimal string` The conversion rate to RAT. **`openedAt`** `string · date-time` The date and time when the position was opened. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "data": [ { "marketId": "cfd.eth_eur", "marketFullName": null, "marketDisplayName": "CFD ETH/EUR", "marketType": "Cfd", "orderId": "01K2PNGX50SR1FRE6P14PJC17E", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "15", "reason": "Trader", "realizedPnlInRAT": "-144.64", "closedAt": "2025-08-15T10:48:32.393Z", "positionId": "01K2PMXY63HESK110WT1CHMAFA", "openPrice": "4333.69288", "closePrice": "3370.58389", "positionPriceInRAT": "50558.75", "rateToRAT": "1", "openedAt": "2025-08-15T10:38:10.628Z", "comment": null }, { "marketId": "perp.eth_usdt", "marketFullName": "ETH/USDT_4s8hKqiPXmXOEhsO1J6W", "marketDisplayName": "ETH/USDT_jC6Im5PxwgZLrwyccRcI", "marketType": "Perpetual", "orderId": "01K2PNG3N6NKAJVV4RV5E2V0HK", "orderType": "Market", "timeInForce": "Ioc", "side": "Sell", "positionCloseLotAmount": "0.5", "reason": "Trader", "realizedPnlInRAT": "13.42", "closedAt": "2025-08-15T10:48:06.234Z", "positionId": "01K2PMT0VMJG5B8XBDNZ7FNM1F", "openPrice": "4603.1607", "closePrice": "4634.3915", "positionPriceInRAT": "1992.78", "rateToRAT": "0.86", "openedAt": "2025-08-15T10:36:02.293Z", "comment": null } ], "isExceeded": true } ``` ### Get executions for a closing order [#get-executions-for-a-closing-order] `POST` `/frontoffice/api/v5/orders/``{orderId}``/executions/list` #### Summary [#summary-3] Use this method to retrieve execution details for a specific position-closing order using its identifier. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The order identifier. ##### Body [#body-3] **`positionId`** `string | nullable` The position identifier. **`limit`** `integer · int32 | nullable` The maximum number of items to return. **`lastExecutionId`** `string | nullable` The identifier of the final execution to be returned. ```http title="Request example" POST /frontoffice/api/v4/orders/01K2PNG3N6NKAJVV4RV5E2V0HK/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "limit": 5 } ``` #### Response [#response-3] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed amount of the base asset. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T19:02:22.196Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true } ], "isExceeded": true } ``` ### Get executions for closing orders [#get-executions-for-closing-orders] `POST` `/frontoffice/api/v5/orders/executions/list` #### Summary [#summary-4] Use this method to retrieve execution details for multiple position-closing orders by providing an array of order identifiers. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`orderId`** `string` The order identifier. **`positionId`** `string` The order identifier. ```http title="Request example" POST /frontoffice/api/v4/orders/executions/list HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "orderPositionPairs": [ { "orderId": "01K31APDKZCVGWZA3XTF5JPAMD", "positionId": "01K31APDWF2EBHRKHH15VGB1ST" } ], "limit": 0 } ``` #### Response [#response-4] In case of success, an object containing an array of executions will be returned. Each execution object contains the following information: **`positionId`** `string` The position identifier. **`orderId`** `string` The order identifier. **`side`** `string` The execution side. Possible values: * `Buy` * `Sell` **`reason`** `string` The reason for the execution. Possible values: * `Trader` * `StopOut` * `MarketHalted` * `MarketDisabled` * `TakeProfit` * `StopLoss` * `Admin` **`createdAt`** `string` The date and time when the execution occurred, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`executionId`** `string` The execution identifier. **`baseAmount`** `decimal string` The executed base asset amount. **`executionPrice`** `decimal string` The price at which the execution was settled. **`realizedPnlInRAT`** `decimal string` The realized PnL, in conversion to RAT. **`commissionAmountInRAT`** `decimal string` The total commissions charged for the execution, in conversion to RAT. **`commissions`** `array` The breakdown of commissions charged per asset. Structure: * **`assetId`** `string` * **`amount`** `decimal string` **`positionSizeIncreased`** `boolean` Indicates if a position size was increased (`true`) or decreased (`false`) as a result of the execution. **`comment`** `string | nullable` The text note attached to the order, up to 100 characters. **`isExceeded`** `boolean` Indicates whether the number of returned items reached the response `limit` and more data is available. ```json title="Response example — 200: OK" { "executions": [ { "positionId": "string", "orderId": "string", "side": "Buy", "reason": "Trader", "createdAt": "2025-12-18T18:53:15.657Z", "executionId": "string", "baseAmount": "string", "executionPrice": "string", "realizedPnlInRAT": "string", "commissionAmountInRAT": "string", "commissions": [ { "assetId": "string", "amount": "string" } ], "positionSizeIncreased": true, "comment": null } ], "isExceeded": true } ``` ## Accounts [#accounts] ### Get accounts [#get-accounts] `GET` `/frontoffice/api/v3/accounts` #### Summary [#summary] Use this method to retrieve a list of all trading accounts with their basic information including account type and total balance. #### Request [#request] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/accounts HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response] In case of success, an array of objects will be returned. Each object contains the following information: **`accountId`** `string` The trading account identifier. **`publicAccountId`** `integer` The public account identifier for display purposes. **`accountName`** `string` The account name. **`accountType`** `string` The account type. Possible values: * `Hedging` * `Netting` **`accountStatus`** `string` The account status, which determines the permitted operations. For a description of each value, see [Account statuses](../get-started/account-statuses). Possible values: * `Active` * `Halted` * `Frozen` **`totalBalanceInRAT`** `decimal string` The total balance, in RAT. **`isCopyTradingAccount`** `boolean` Indicates if the account is `Copy`. ```json title="Response example — 200: OK" [ { "accountId": "685a7eaa360f9e7416221a61", "publicAccountId": 1234567, "accountName": "B2TRADER Hedging account", "accountType": "Hedging", "accountStatus": "Active", "totalBalanceInRAT": "6020.12", "isCopyTradingAccount": false }, { "accountId": "6891e70db552ff9c6fbbccf5", "publicAccountId": 1234568, "accountName": "B2TRADER Netting account", "accountType": "Netting", "accountStatus": "Halted", "totalBalanceInRAT": "10987.39", "isCopyTradingAccount": false } ] ``` ## Assets [#assets] ### Get assets [#get-assets] `GET` `/frontoffice/api/v3/assets` #### Summary [#summary-1] Use this method to retrieve a list of available assets on the platform. #### Request [#request-1] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-1] In case of success, an array of objects will be returned. Each object contains the following information: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`isRootAsset`** `boolean` Indicates whether this is a root asset. ```json title="Response example — 200: OK" [ { "assetId": "usdt", "assetName": "Tether", "isRootAsset": true }, { "assetId": "xrp", "assetName": "Ripple", "isRootAsset": false } ] ``` ## Markets [#markets] ### Get markets [#get-markets] `GET` `/frontoffice/api/v6/markets` #### Summary [#summary-2] Use this method to retrieve a list of available markets with their type, subtype, and favorite status. #### Request [#request-2] ##### Query parameters [#query-parameters] **`categoryId`** The market category identifier. **`dynamicCommissionGroupId`** The dynamic commission group identifier. **`isFavorite`** `boolean` Filter by favorite status. If set to `true`, only markets marked as favorites are returned. ```http title="Request example" GET /frontoffice/api/v6/markets?isFavorite=true HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} ``` #### Response [#response-2] In case of success, an array of market objects is returned. Each market object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description. **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" [ { "marketId": "spot.btc_usdt", "displayName": "BTC/USDT", "fullName": null, "type": "Spot", "subtype": null, "isFavorite": true }, { "marketId": "cfd.eth_btc", "displayName": "ETH/BTC", "fullName": "Ethereum to Bitcoin", "type": "Cfd", "subtype": "Crypto", "isFavorite": false }, { "marketId": "perp.trx_usdt", "displayName": "TRX/USDT", "fullName": "TRX to Tether Perpetual", "type": "Perpetual", "subtype": null, "isFavorite": false } ] ``` ### Get market [#get-market] `GET` `/frontoffice/api/v6/markets/``{marketId}` #### Summary [#summary-3] Use this method to retrieve detailed information about a specific market using its market identifier. #### Request [#request-3] ##### Path parameters [#path-parameters] **`marketId`** `required` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. ```http title="Request example" GET /frontoffice/api/v6/markets/{marketId} HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. **`displayName`** `string` The market ticker. **`fullName`** `string | nullable` The market full name or description (optional). **`baseAssetId`** `string` The base asset identifier. **`quoteAssetId`** `string` The quote asset identifier. **`minAmount`** `decimal string | nullable` *Applicable to Spot markets only.* The minimum tradable amount of the base asset. **`maxBaseAmount`** `decimal string | nullable` The maximum tradable amount of the base asset. **`priceDeviation`** `decimal string` The allowed price deviation for Limit orders placed on the market. Supports decimal values in the range `[0, 1]`, with up to 4 decimal places, for example: * `0.1` = 10% * `0.01` = 1% * `0.001` = 0.1% * `0.0001` = 0.01% If set to `0`, no restriction is applied, the price deviation is ignored. **`priceScale`** `integer` The price precision, which is the number of digits after a decimal separator. Also determines the minimum allowed trade price. Supports only integer values in the range `[2, 8]`. For example, `2` means the following price format: `0.01`, and `8`: `0.00000001`. **`amountScale`** `integer | nullable` *Applicable to Spot markets only.* The amount precision, which is the number of digits after a decimal separator. Also determines the minimum trade amount. Supports only integer values in the range `[0, 8]`. For example: * `0` means `1` (no digits after the decimal separator) * `5` means `0.00001` (five digits after the decimal separator) * `8` means `0.00000001` (eight digits after the decimal separator) **`type`** `string` The market type. Possible values: * `Spot` * `Cfd` * `Perp` **`subtype`** `string | nullable` *Applicable to CFD markets only.* The market subtype. Possible values: * `Crypto` * `Fx` * `Metals` * `Indices` * `Energies` * `Ndf` * `Shares` * `Etf` **`swapSettings`** `object | nullable` *Applicable to CFD markets only.* The fee type charged for holding open positions overnight. The amount can be negative for rebates. Possible values: * `FixPerLot`: The fixed amount per lot. * `Percent`: The fixed amount in points which is applied to the position size, in the range `[-1, 1]`, with up to 5 decimal places. * `Points`: The fixed amount of percents which is applied to the position size, with up to 3 decimal places. Structure: * **`type`** `string` — Swap calculation type. Possible values: `FixPerLot`, `Percent`, `Points`. * **`shortPositionSettings`** `object` — Settings for Short positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` * **`longPositionSettings`** `object` — Settings for Long positions: * **`size`** `decimal string` * **`assetId`** `string | nullable` **`lotSize`** `integer | nullable` *Not applicable to Spot markets.* The standardized quantity of the base asset per lot. Supports only integer values in the range `[1, 1000000]`. **`minLotAmount`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum order amount, in lots, that can be placed and executed. Supports values in the range `[0.00000001, 1]`. **`maxLotAmount`** `integer | nullable` *Not applicable to Spot markets.* The maximum order amount, in lots, that can be placed and executed. Supports only integer values in the range `[1, 10000]`. **`tickSize`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum price increment. **`lotStep`** `decimal string | nullable` *Not applicable to Spot markets.* The minimum lot amount increment. Supports values in the range `[0.00000001, 1]`. By default, equals to the `minLotAmount`. **`slippageRate`** `decimal string` The expected slippage, that is, the difference between the expected execution price and the actual one. This value is used as a multiplier to calculate the funds to be put on hold for a market order execution. Supports values in the range `[1, 10]`, including decimal values with up to 4 decimal places. The default value is `1` which means that only the current bid/ask price is put on hold. For example, `1.1` means that the current bid or ask price + 10% is put on hold for each order, to cover the 10% slippage. **Mind that** the total amount funds to be held depends on the order parameters and takes into account many conditions, the slippage rate is only one of them. **`calendar`** `object` The trading calendar defining market trading hours. Structure: * **`timeZoneId`** `string` — IANA time zone identifier. * **`tradingSessions`** `array` — Weekly trading sessions: * **`dayOfWeek`** `string` — One of: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. * **`timeIntervals`** `array` — List of intervals with: * **`start`** `string` (time) — Start time in `calendar.timeZoneId`. * **`end`** `string` (time) — End time in `calendar.timeZoneId`. * **`sessionOverrides`** `array` — Optional specific-date overrides: * **`date`** `string` (date) — In `YYYY-MM-DD` format. * **`timeIntervals`** `array | nullable` — Intervals for that date. **`fundingStartTime`** `string | nullable` *Applicable to Perpetual markets only.* The time of the first funding settlement, in the following format: `HH:MM:SS`. **`fundingIntervalInHours`** `integer | nullable` *Applicable to Perpetual markets only.* The funding settlement interval, in hours. Possible values: 1, 2, 3, 4, 6, 8, 12, 24. **`leverageProfile`** `object` *Not applicable to Spot markets.* The leverage profile. Structure: * **`leverageType`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`leverage`** `object` * **`useOnlyMaxLeverage`** `boolean` * **`maxLeverage`** `integer` — For `Fixed` leverage type only. * **`tiers`** `array` — For `Dynamic` leverage type only. * **`maxLeverage`** `integer` — The maximum allowed leverage for this tier. * **`maxNotionalValueInRAT`** `string | nullable` — The maximum position notional for this tier. **`commissionSettings`** `object` The commission settings. Structure: * **`type`** `string` — Leverage type. Possible values: `Fixed`, `Dynamic`. * **`charge`** `object` * **`type`** `string` — Possible values: `Percent`, `FixPerLot`. * **`assetId`** `string | nullable` — For `Fixed` commission type only. * **`size`** `decimal string` — For `Fixed` commission type only. * **`tiers`** `array` — For `Dynamic` commission type only. * **`size`** `string` — The commission amount for this tier. * **`minTradingVolumeInRAT`** `string` — The minimum required trading volume for this tier. * **`minCommissionInRAT`** `decimal string | nullable` * **`dynamicCommissionGroupId`** **`isFavorite`** `boolean` Indicates whether the market is marked as a favorite by the current user. ```json title="Response example — 200: OK" { "marketId": "string", "displayName": "string", "fullName": "string", "baseAssetId": "string", "quoteAssetId": "string", "minAmount": "string", "maxBaseAmount": "string", "minQuoteAmount": "string", "priceDeviation": "string", "priceScale": 0, "amountScale": 0, "type": "Spot", "subtype": "Cash", "swapSettings": { "type": "FixPerLot", "shortPositionSettings": { "size": "string", "assetId": "string" }, "longPositionSettings": { "size": "string", "assetId": "string" } }, "lotSize": 0, "minLotAmount": "string", "maxLotAmount": 0, "tickSize": "string", "lotStep": "string", "slippageRate": "string", "calendar": { "timeZoneId": "string", "tradingSessions": [ { "dayOfWeek": "Monday", "timeIntervals": [ { "start": "string", "end": "string" } ] } ], "sessionOverrides": [ { "date": "2025-12-18", "timeIntervals": [ { "start": "string", "end": "string" } ] } ] }, "fundingStartTime": "string", "fundingIntervalInHours": 0, "leverageProfile": { "leverageType": "Fixed", "leverage": { "useOnlyMaxLeverage": true, "maxLeverage": 0 } }, "commissionSettings": { "type": "Dynamic", "сharge": { "type": "Percent", "tiers": [ { "size": "string", "minTradingVolumeInRAT": "string" }, { "size": "string", "minTradingVolumeInRAT": "string" } ], "minCommissionInRAT": "string" }, "dynamicCommissionGroupId": "string" }, "isFavorite": true } ``` *** ### Add favorite market [#add-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/add` #### Summary [#summary-4] Add a market to the current user's favorites list. #### Request [#request-4] ##### Body [#body] **`marketId`** `string` `required` The market identifier to add to favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/add HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-4] In case of success (`200`), an empty object is returned. *** ### Remove favorite market [#remove-favorite-market] `POST` `/frontoffice/api/v6/markets/favorites/delete` #### Summary [#summary-5] Remove a market from the current user's favorites list. #### Request [#request-5] ##### Body [#body-1] **`marketId`** `string` `required` The market identifier to remove from favorites. ```http title="Request example" POST /frontoffice/api/v6/markets/favorites/delete HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "marketId": "spot.btc_usdt" } ``` #### Response [#response-5] In case of success (`200`), an empty object is returned. ## Account margin settings [#account-margin-settings] ### Get margin assets [#get-margin-assets] `GET` `/frontoffice/api/v4/account-margin-settings/assets` #### Summary [#summary-6] Use this method to retrieve a list of assets that can be used as collateral for margin trading. #### Request [#request-6] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v4/account-margin-settings/assets HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`assets`** `array` A list of assets that can be used as a collateral for margin trading. Each array item contains: **`assetId`** `string` The asset identifier. **`assetName`** `string` The asset display name. **`available`** `decimal string` The available asset balance. This value is calculated as *Total balance* – *Locked balance*. **`total`** `decimal string` The overall amount of the asset, including locked funds. **`marginRatio`** `decimal string` The percentage of the asset value used as a collateral. Supports values in the range `[0, 1]`, where `1` represents 100.00%. **`isSelected`** `boolean` Indicates whether the asset is selected to be used as collateral. Can be `true` only for assets with the `marginRatio` more than `0`. ```json title="Response example — 200: OK" { "assets": [ { "assetId": "btc", "assetName": "btc", "available": "0.031", "total": "0.031", "marginRatio": "1", "isSelected": true }, { "assetId": "eth", "assetName": "eth", "available": "0", "total": "0", "marginRatio": "1", "isSelected": false } ] } ``` ### Select margin asset [#select-margin-asset] `POST` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-7] Use this method to enable a particular asset to be used as collateral for margin trading. Only assets with the `marginRatio` more than `0` can be selected. #### Request [#request-7] ##### Path parameters [#path-parameters-1] **`assetId`** `required` The asset identifier. ```http title="Request example" POST /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json Accept: */* {} ``` #### Response [#response-7] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ### Disable margin asset [#disable-margin-asset] `DELETE` `/frontoffice/api/v4/account-margin-settings/assets/``{assetId}` #### Summary [#summary-8] Use this method to prohibit a specific asset from being used as collateral for margin trading. #### Request [#request-8] ##### Path parameters [#path-parameters-2] **`assetId`** `required` The asset identifier. ```http title="Request example" DELETE /frontoffice/api/v4/account-margin-settings/assets/usdt HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-8] In case of success, an empty object will be returned. ```json title="Response example — 200: OK" {} ``` ## Info [#info] ### Get server info [#get-server-info] `GET` `/frontoffice/api/v3/info` #### Summary [#summary-9] Use this method to retrieve current server time and timezone information. #### Request [#request-9] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`serverTime`** `string` The server time, in the Unix timestamp format. **`serverTimeZone`** `string` The server time zone. ```json title="Response example — 200: OK" { "serverTime": "1755190380", "serverTimeZone": "+00:00" } ``` ### Get server time zones [#get-server-time-zones] `GET` `/frontoffice/api/v3/info/time-zones` #### Summary [#summary-10] Use this method to retrieve available server time zones. #### Request [#request-10] *No request parameters.* ```http title="Request example" GET /frontoffice/api/v3/info/time-zones HTTP/1.1 Host: {host} Authorization: Bearer JWT Accept: */* ``` #### Response [#response-10] In case of success, an array of objects will be returned. Each object contains the following information: **`id`** `string` The time zone identifier. **`offset`** `string` The UTC offset, in the following format: `HH:MM:SS`. **`offsetInMinutes`** `integer · int32` The UTC offset in minutes. **`shortLabel`** `string` The short label for the time zone. **`label`** `string` The display label for the time zone. ```json title="Response example — 200: OK" [ { "id": "Africa/Abidjan", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Abidjan", "label": "(UTC+00:00) Côte d’Ivoire Time" }, { "id": "Africa/Algiers", "offset": "01:00:00", "offsetInMinutes": 60, "shortLabel": "Africa/Algiers", "label": "(UTC+01:00) Central European Time (Algiers)" }, { "id": "Africa/Bissau", "offset": "00:00:00", "offsetInMinutes": 0, "shortLabel": "Africa/Bissau", "label": "(UTC+00:00) Guinea-Bissau Time" }, ... ] ``` ## Webhooks [#webhooks] ### Create webhook API key [#create-webhook-api-key] `POST` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-11] Create a new webhook API key for receiving TradingView alerts. #### Request [#request-11] ##### Header parameters [#header-parameters] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Body [#body-2] **`name`** `string` `required` A descriptive name for the API key, up to 100 characters. ```http title="Request example" POST /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json { "name": "My TradingView Key" } ``` #### Response [#response-11] In case of success (`201`), the created API key object is returned. **`id`** `string` The unique identifier of the API key. **`apiKey`** `string` The full API key value. The key is shown only once at creation. **`name`** `string` The name assigned to the key. **`userId`** `string` The user identifier the key is bound to. **`status`** `string` The key status: `Active`. **`createdAt`** `string` The timestamp when the key was created. **`expiresAt`** `string` The timestamp when the key expires (one year from creation). ```json title="Response example" { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "apiKey": "wh_key_abc123def456...", "name": "My TradingView Key", "userId": "01JZ3CVZKN20410JPYYH1YZJSK", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ``` The API key is shown only once in the creation response. It can't be retrieved again after this call. *** ### List webhook API keys [#list-webhook-api-keys] `GET` `/frontoffice/api/v3/webhook/api-keys` #### Summary [#summary-12] Retrieve all webhook API keys for the authenticated user along with the webhook URL. #### Request [#request-12] ##### Header parameters [#header-parameters-1] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ```http title="Request example" GET /frontoffice/api/v3/webhook/api-keys HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-12] In case of success (`200`), the webhook URL and a list of API keys are returned. **`webhookUrl`** `string` The webhook URL to configure in TradingView alerts. **`apiKeys`** `array of objects` The list of API keys. **`apiKeys[].id`** `string` The unique identifier of the API key. **`apiKeys[].name`** `string` The name assigned to the key. **`apiKeys[].status`** `string` The key status. Possible values: * `Active` * `Revoked` * `Expired` **`apiKeys[].createdAt`** `string` The timestamp when the key was created. **`apiKeys[].expiresAt`** `string` The timestamp when the key expires. ```json title="Response example" { "webhookUrl": "https://trading.example.com/frontoffice/api/v3/webhook/alerts/01JZ3...", "apiKeys": [ { "id": "01JZ3CVZKN20410JPYYH1YZJSK", "name": "My TradingView Key", "status": "Active", "createdAt": "2026-02-02T12:00:00Z", "expiresAt": "2027-02-02T00:00:00Z" } ] } ``` *** ### Revoke webhook API key [#revoke-webhook-api-key] `DELETE` `/frontoffice/api/v3/webhook/api-keys/{id}` #### Summary [#summary-13] Revoke an active webhook API key. After revocation, the key can no longer be used to authenticate webhook requests. #### Request [#request-13] ##### Header parameters [#header-parameters-2] **`Authorization`** `required` Bearer JWT token with `trading-ui` permission. ##### Path parameters [#path-parameters-3] **`id`** `string` `required` The unique identifier of the API key to revoke. ```http title="Request example" DELETE /frontoffice/api/v3/webhook/api-keys/01JZ3CVZKN20410JPYYH1YZJSK HTTP/1.1 Host: {host} Authorization: Bearer JWT ``` #### Response [#response-13] In case of success (`200`), a confirmation object is returned. **`success`** `boolean` Indicates whether the key was revoked successfully. **`message`** `string` A description of the result. ```json title="Response example" { "success": true, "message": "API key revoked successfully" } ``` *** ### Receive TradingView alert [#receive-tradingview-alert] `POST` `/frontoffice/api/v3/webhook/alerts/{userId}` #### Summary [#summary-14] Accept a webhook alert from TradingView and place an order on the specified trading account. TradingView calls this endpoint when an alert triggers. #### Request [#request-14] ##### Path parameters [#path-parameters-4] **`userId`** `string` `required` The B2TRADER user identifier (ULID format). ##### Body [#body-3] **`apiKey`** `string` `required` The webhook API key for authentication. **`accountId`** `string` `required` The trading account identifier. **`symbol`** `string` `required` The market symbol with a type prefix (`spot.`, `cfd.`, or `perp.`) followed by the pair name. For example: `spot.btc_usdt`, `cfd.eur_usd`, `perp.btc_usdt`. **`side`** `string` `required` The order side. Possible values: * `buy` * `sell` **`quantity`** `decimal string` `required` The order quantity in the base asset. **`orderType`** `string` The order type. Default: `market`. Possible values: * `market` * `limit` * `stop` * `stop_limit` **`price`** `decimal string` The limit price. Required for `limit` and `stop_limit` orders. **`stopPrice`** `decimal string` The stop price. Required for `stop` and `stop_limit` orders. **`leverage`** `decimal string` The leverage ratio. Applicable to CFD and Perpetual Futures markets only. **`takeProfit`** `decimal string` The take profit trigger price. **`stopLoss`** `decimal string` The stop loss trigger price. **`timeInForce`** `string` The time-in-force policy. Default: `gtc`. Possible values: * `gtc` * `ioc` * `fok` * `day` **`comment`** `string` A custom comment, up to 256 characters. **`deduplicationId`** `string` A UUID for idempotency. Duplicate requests with the same ID within five minutes return a cached response. ```http title="Request example" POST /frontoffice/api/v3/webhook/alerts/01JZ3CVZKN... HTTP/1.1 Host: {host} Content-Type: application/json { "apiKey": "wh_key_abc123def456...", "accountId": "01JZ3CVZKN20410JPYYH1YZJSK", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01", "comment": "TV Strategy Signal" } ``` #### Response [#response-14] In case of success (`200`), an order confirmation is returned. **`success`** `boolean` Indicates whether the order was placed successfully. **`orderId`** `string` The unique identifier of the created order. **`orderStatus`** `string` The initial status of the order. **`message`** `string` A description of the result. **`timestamp`** `string` The timestamp of the response. ```json title="Response example" { "success": true, "orderId": "01JZ3CVZKN20410JPYYH1YZJSK", "orderStatus": "Working", "message": "Order placed successfully", "timestamp": "2026-02-02T12:34:56.789Z" } ``` #### Rate limits [#rate-limits] Webhook requests are limited to five requests per second per user. If the limit is exceeded, the response returns a `429` status code with the following headers: * `X-RateLimit-Limit`: Maximum requests per window * `X-RateLimit-Remaining`: Remaining requests in the current window * `X-RateLimit-Reset`: Unix timestamp when the window resets ## Orders [#orders] ### Place SPOT order [#place-spot-order] `POST` `/frontoffice/api/v3/orders` #### Summary [#summary] Use this method to create and submit a new order for SPOT markets. #### Request [#request] ##### Header parameters [#header-parameters] **`accountId`** `required` The trading account identifier. ##### Body [#body] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Limit", "timeInForce": "Gtc", "requestedAmount": 0.02, "requestedPrice": 115193.35, "comment": "Strategy A" } } ``` #### Response [#response] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` — the order was created manually via UI or API. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. Right after the order is created commission is `0`. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K1ZTB4DB0S6Y2NH81S781BQX", "orderType": "Limit", "side": "Buy", "status": "Pending", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.02", "remainingAmount": "0.02", "requestedPrice": "115193.35", "executionPrice": "0", "createdAt": "2025-08-06T13:50:13.931Z", "updatedAt": "2025-08-06T13:50:13.9325008Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Place CFD order [#place-cfd-order] `POST` `/frontoffice/api/cfd/v4/orders` #### Summary [#summary-1] Use this method to create and submit a new order for CFD markets. #### Request [#request-1] ##### Header parameters [#header-parameters-1] **`accountId`** `required` The trading account identifier. ##### Body [#body-1] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "timeInForce": "Gtd", "requestedLotAmount": 1, "requestedPrice": 3280, "leverage": 75, "cancellationDate": "2025-08-10T00:00:00Z", "stopLoss": { "price": 3320, "isTrailing": false }, "takeProfit": { "price": 3200 }, "comment": "Strategy A" } } ``` #### Response [#response-1] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2253Q9X3VTJ68PNWY40JC6Q", "status": "Pending" } } ``` ### Place PF order [#place-pf-order] `POST` `/frontoffice/api/perpetual/v4/orders` #### Summary [#summary-2] Use this method to create and submit a new order for Perpetual markets. #### Request [#request-2] ##### Header parameters [#header-parameters-2] **`accountId`** `required` The trading account identifier. ##### Body [#body-2] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `perp.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json { "order": { "marketId": "perp.eth_usdt", "side": "Buy", "orderType": "Market", "timeInForce": "Ioc", "requestedLotAmount": 10, "leverage": 159, "comment": "Strategy A" } } ``` #### Response [#response-2] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K228VN55N7WFZRG70M24T9J1", "status": "Working" } } ``` ### Cancel order [#cancel-order] `DELETE` `/frontoffice/api/v3/orders/``{orderId}` #### Summary [#summary-3] Use this method to cancel an active order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-3] ##### Header parameters [#header-parameters-3] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters] **`orderId`** `required` The order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/orders/01K2PF9XS29WN4JZRHMCTTQYJB HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Accept: */* ``` #### Response [#response-3] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#market-and-limit-orders). Possible values: * `Started` * `Pending` * `Working` * `Completed` * `Cancelled` * `Expired` * `Rejected` **`order.source`** `string` The source of the order. Possible values: * `Manual` * `StopOrder` * `FixApi` * `System` **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.commission`** `decimal string` The fee charged for the execution of the order, expressed in the quote asset. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.remainingAmount`** `decimal string` The amount of the base asset that remains unfilled. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`order.executionPrice`** `decimal string` The volume-weighted average price at which the order was executed. **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.rejectDetails`** `string` The reason and details for order rejection when `status` is `Rejected`. Currently unused and not populated. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.fillFactor`** `decimal string` The ratio of the filled quantity to the originally requested quantity (`filledAmount / requestedAmount`). ```json title="Response example — 200: OK" { "order": { "marketId": "spot.eth_usdt", "marketDisplayName": "SPOT ETH/USDT", "orderId": "01K2PF9XS29WN4JZRHMCTTQYJB", "orderType": "Limit", "side": "Buy", "status": "Cancelled", "source": "Manual", "timeInForce": "Gtc", "commission": "0", "requestedAmount": "0.1", "remainingAmount": "0.1", "requestedPrice": "4450", "executionPrice": "0", "createdAt": "2025-08-15T08:59:51.97Z", "updatedAt": "2025-08-15T09:00:06.2791048Z", "rejectDetails": "", "cancellationDate": null, "fillFactor": "0" } } ``` ### Get SPOT order data [#get-spot-order-data] `POST` `/frontoffice/api/v3/order-data` #### Summary [#summary-4] Use this method to retrieve and validate order data for SPOT market orders before placing. #### Request [#request-4] ##### Header parameters [#header-parameters-4] **`accountId`** `required` The trading account identifier. ##### Body [#body-3] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.requestedBaseAmount`** `decimal string | nullable` The requested amount in base asset units. **`order.requestedQuoteAmount`** `decimal string | nullable` The requested amount in quote asset units. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. ```http title="Request example" POST /frontoffice/api/v3/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=3.0 Accept: */* { "order": { "marketId": "spot.eth_usdt", "side": "Buy", "orderType": "Limit", "requestedBaseAmount": 0.2, "requestedPrice": 4600 } } ``` #### Response [#response-4] In case of success, an object will be returned. Each object contains the following information: **`baseAmount`** `decimal string` The calculated base asset amount for the order. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmount`** `decimal string` The estimated commission amount to be charged. **`total`** `decimal string` The total quote asset amount, including the estimated commission. ```json title="Response example — 200: OK" { "order": { "baseAmount": "0.2", "quoteAmount": "920", "commissionAmount": "9.2", "total": "929.2" } } ``` ### Get CFD order data [#get-cfd-order-data] `POST` `/frontoffice/api/cfd/v4/order-data` #### Summary [#summary-5] Use this method to retrieve and validate order data for CFD market orders before placing. #### Request [#request-5] ##### Header parameters [#header-parameters-5] **`accountId`** `required` The trading account identifier. ##### Body [#body-4] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables the Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/cfd/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": 15000, "triggerType": "points" }, "stopLoss": { "triggerSize": "4020", "triggerType": "price", "isTrailing": false }, "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Market", "leverage": 135, "requestedLotAmount": 1 } } ``` #### Response [#response-5] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "34.4613643", "quoteAmount": "4004.345", "commissionAmountInRAT": "0", "marginLevel": "5.3015", "takeProfit": { "price": "3989.345", "rate": "0.0037", "points": 15000, "pnl": "17.42713545" }, "stopLoss": { "price": "4020", "rate": "-0.0039", "points": -15655, "pnl": "-18.18812036" } } } ``` ### Get PF order data [#get-pf-order-data] `POST` `/frontoffice/api/perpetual/v4/order-data` #### Summary [#summary-6] Use this method to retrieve and validate order data for Perpetual market orders before placing. #### Request [#request-6] ##### Header parameters [#header-parameters-6] **`accountId`** `required` The trading account identifier. ##### Body [#body-5] **`order`** `object` The order data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`order.stopLoss.isTrailing`** `boolean | nullable` If `true`, enables Trailing behavior for Stop loss. ```http title="Request example" POST /frontoffice/api/perpetual/v4/order-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "takeProfit": { "triggerSize": "0.01", "triggerType": "rate" }, "stopLoss": { "triggerSize": "-100", "triggerType": "pnl", "isTrailing": false }, "marketId": "perp.btc_usdt", "side": "Buy", "orderType": "Limit", "leverage": 100, "requestedLotAmount": 0.5, "requestedPrice": 118450 } } ``` #### Response [#response-6] In case of success, an object will be returned. Each object contains the following information: **`requiredMarginInRAT`** `decimal string` The required margin amount, in conversion to RAT. **`quoteAmount`** `decimal string` The calculated quote asset amount for the order. **`commissionAmountInRAT`** `decimal string` The estimated commission amount to be charged, in conversion to RAT. **`marginLevel`** `decimal string | nullable` The resulting margin level. **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "order": { "requiredMarginInRAT": "592.25", "quoteAmount": "59225", "commissionAmountInRAT": "0", "marginLevel": "0.3582", "takeProfit": { "price": "119634.5", "rate": "0.01", "points": 11845, "pnl": "592.25" }, "stopLoss": { "price": "118250", "rate": "-0.0016", "points": -2000, "pnl": "-100" } } } ``` ## Stop orders [#stop-orders] ### Place SPOT Stop order [#place-spot-stop-order] `POST` `/frontoffice/api/v3/stop-orders` #### Summary [#summary-7] Use this method to create and submit a new Stop order for SPOT markets. #### Request [#request-7] ##### Header parameters [#header-parameters-7] **`accountId`** `required` The trading account identifier. ##### Body [#body-6] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `spot.btc_usdt`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell. For Market orders, this represents the total base amount to fill; the executed amount may be lower if liquidity is insufficient. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/v3/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "spot.btc_usdt", "side": "Buy", "orderType": "Market", "activationPrice": 128000, "requestedAmount": 0.01, "timeInForce": "Ioc", "comment": "Strategy A" } } ``` #### Response [#response-7] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders, same as in the request; `null` for market orders. **`activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order, same as in the request. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. **`order.comment`** `string | nullable` The text note attached to the order, up to 100 characters. ```json title="Response example — 200: OK" { "order": { "marketId": "spot.btc_usdt", "marketDisplayName": "SPOT BTC/USDT", "orderId": "01K2MNC3BVR5WRTBEE9YWAS91K", "orderType": "Market", "side": "Buy", "requestedPrice": "0", "activationPrice": "128000", "requestedAmount": "0.01", "timeInForce": "Ioc", "status": "WaitingForActivation", "createdAt": "2025-08-14T16:07:25.8193038Z", "updatedAt": "2025-08-14T16:07:25.8193044Z", "cancellationDate": null, "comment": null } } ``` ### Place CFD Stop order [#place-cfd-stop-order] `POST` `/frontoffice/api/cfd/v4/stop-orders` #### Summary [#summary-8] Use this method to create and submit a new Stop order for CFD markets. #### Request [#request-8] ##### Header parameters [#header-parameters-8] **`accountId`** `required` The trading account identifier. ##### Body [#body-7] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/cfd/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "cfd.eth_eur", "side": "Sell", "orderType": "Limit", "activationPrice": 3200, "requestedLotAmount": 0.5, "timeInForce": "Gtd", "leverage": 76, "requestedPrice": 3500, "cancellationDate": "2025-08-18T00:00:00Z", "stopLoss": { "price": "3900", "isTrailing": false }, "takeProfit": { "price": "3100" }, "comment": "Strategy A" } } ``` #### Response [#response-8] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNRWP2J1S8T9TKTCXWYY87", "status": "WaitingForActivation" } } ``` ### Place PF Stop order [#place-pf-stop-order] `POST` `/frontoffice/api/perpetual/v4/stop-orders` #### Summary [#summary-9] Use this method to create and submit a new Stop order for Perpetual markets. #### Request [#request-9] ##### Header parameters [#header-parameters-9] **`accountId`** `required` The trading account identifier. ##### Body [#body-8] **`order`** `object` Order creation data. **`order.marketId`** `string` The market identifier, in the following format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`. Must match one of the available markets returned by the [Get markets](settings#get-markets) endpoint. **`order.side`** `string` The order side, indicating the direction of the trade. Possible values: * `Buy` * `Sell` **`order.orderType`** `string` The [order type](../get-started/order-types). Possible values: * `Market` * `Limit` **`order.timeInForce`** `string` The [time-in-force policy](../get-started/time-in-force) for the order, controlling its lifetime. Possible values: * `Gtc` * `Ioc` * `Fok` * `Gtd` * `Day` **`order.requestedLotAmount`** `decimal string` The quantity of the base asset to buy or sell, in lots. Lot size is defined per market and determines the base asset quantity represented by one lot. Upon execution, this defines the opened position size in lots. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.cancellationDate`** `string | nullable` For GTD orders: The date and time when the order will be automatically canceled if not executed, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. Required if `timeInForce` is set to `Gtd`; ignored for other time-in-force values. **`order.leverage`** `integer` The leverage factor applied to the position. Leverage determines margin required to open and maintain the position (for example, with leverage 10, only 10% of the position's notional value is required as margin). **`order.stopLoss`** `object` The Stop loss settings. **`order.stopLoss.price`** `decimal string` The Stop loss price. **`order.stopLoss.isTrailing`** `boolean` Indicates if the Stop loss is Trailing. **`order.takeProfit`** `object` The Take profit settings. **`order.takeProfit.price`** `decimal string` The take profit price. **`order.comment`** `string | nullable` A text note to attach to the order, up to 100 characters. The comment is inherited by the resulting position and can't be edited after the order is placed. ```http title="Request example" POST /frontoffice/api/perpetual/v4/stop-orders HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "order": { "marketId": "perp.btc_usdt", "side": "Sell", "orderType": "Market", "activationPrice": 115000, "requestedLotAmount": 1, "timeInForce": "Fok", "leverage": 22, "stopLoss": { "price": "118020", "isTrailing": true }, "takeProfit": { "price": "113873" }, "comment": "Strategy A" } } ``` #### Response [#response-9] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The created order. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` ```json title="Response example — 200: OK" { "order": { "orderId": "01K2MNM0S8B2R9DS7BWJ8PGYPR", "status": "WaitingForActivation" } } ``` ### Cancel Stop order [#cancel-stop-order] `DELETE` `/frontoffice/api/v3/stop-orders/``{orderId}` #### Summary [#summary-10] Use this method to cancel an active Stop order placed on SPOT, CFD, or Perpetual markets. #### Request [#request-10] ##### Header parameters [#header-parameters-10] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-1] **`orderId`** `required` The Stop order identifier to cancel. ```http title="Request example" DELETE /frontoffice/api/v3/stop-orders/01K2MNGAWPMQJ7WGATFSCAS1G4 HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-10] In case of success, an object will be returned. Each object contains the following information: **`order`** `object` The canceled order. **`order.marketId`** `string` The market identifier, same as in the request. **`order.marketDisplayName`** `string` The market ticker. **`order.orderId`** `string` The unique identifier of the order assigned by the system. **`order.orderType`** `string` The order type, same as in the request. **`order.side`** `string` The order side, same as in the request. **`order.requestedPrice`** `decimal string | nullable` The limit price for Limit orders (the maximum price for a buy or minimum price for a sell). Must be `null` or omitted for Market orders. **`order.activationPrice`** `decimal string | nullable` The trigger price that activates the Stop order. **`order.requestedAmount`** `decimal string` The quantity of the base asset to buy or sell, same as in the request. **`order.timeInForce`** `string` The time-in-force policy, same as in the request. **`order.status`** `string` The current [order status](../get-started/order-statuses#stop-orders). Possible values: * `WaitingForActivation` * `Activated` * `Rejected` **`order.createdAt`** `string` The timestamp when the order was created, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.updatedAt`** `string` The timestamp of the most recent update to the order, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`. **`order.cancellationDate`** `string | nullable` The timestamp when the order was cancelled or expired, in the following format: `YYYY-MM-DDTHH:MM:SS.sssZ`; `null` if not cancelled. ```json title="Response example — 200: OK" { "order": { "marketId": "perp.btc_usdt", "marketDisplayName": "Perpetual BTC/USDT", "orderId": "01K2MNGAWPMQJ7WGATFSCAS1G4", "orderType": "Limit", "side": "Sell", "requestedPrice": "115100", "activationPrice": "115000", "requestedAmount": "1", "timeInForce": "Gtc", "status": "Rejected", "createdAt": "2025-08-14T16:09:44.5986099Z", "updatedAt": "2025-08-14T16:09:44.5986103Z", "cancellationDate": null } } ``` ## Positions [#positions] ### Close position [#close-position] `POST` `/frontoffice/api/v4/positions/``{positionId}``/close` #### Summary [#summary-11] Use this method to close a specific position entirely or partially. #### Request [#request-11] ##### Header parameters [#header-parameters-11] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-2] **`positionId`** `required` The position identifier to close. ##### Body [#body-9] **`closePositionLotAmount`** `decimal string | nullable` The portion of the position to close, in lots. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2PFXDP1FWCJSGTX4GJ6JHM0/close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-11] In case of success, an object will be returned. Each object contains the following information: **`positionId`** `string` The position identifier. ```json title="Response example — 200: OK" { "positionId": "01K2PFXDP1FWCJSGTX4GJ6JHM0" } ``` ### Bulk close positions [#bulk-close-positions] `POST` `/frontoffice/api/v4/positions/bulk-close` #### Summary [#summary-12] Use this method to close multiple positions simultaneously based on different criteria such as all positions, positive PnL only, or negative PnL only. #### Request [#request-12] ##### Header parameters [#header-parameters-12] **`accountId`** `required` The trading account identifier. ##### Body [#body-10] **`mode`** `string` `required` The bulk close mode. Possible values: * `AllPositions` — close all positions. * `PositivePnl` — close only positions with positive PnL. * `NegativePnl` — close only positions with negative PnL. ```http title="Request example" POST /frontoffice/api/v4/positions/bulk-close HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "mode": "AllPositions" } ``` #### Response [#response-12] In case of success, an object will be returned containing identifiers of closed positions. ```json title="Response example — 200: OK" { "status": "accepted", "positionIds": [ "01K228VNC2Q7E7K9W8GABWBZ5Z", "01K22BZ2DCETJZKW6MK81N1T8Y", "01K2CXF06A3A5SK2YFJT67CMZ5", "01K2CXF2ZJ6MJYMEK663TBBY8K", "01K2PFXDP1FWCJSGTX4GJ6JHM0" ] } ``` ### Get trigger data [#get-trigger-data] `POST` `/frontoffice/api/v4/positions/``{positionId}``/trigger-data` #### Summary [#summary-13] Use this method to retrieve Stop loss and Take profit settings for an open position. #### Request [#request-13] ##### Header parameters [#header-parameters-13] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-3] **`positionId`** `required` The position identifier. ##### Body [#body-11] **`stopLoss.triggerType`** `string · enum | nullable` The trigger calculation type for Stop loss. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`stopLoss.triggerSize`** `decimal string | nullable` The trigger value in selected units. **`stopLoss.isTrailing`** `boolean | nullable` Indicates if Stop loss is Trailing. **`takeProfit.triggerType`** `string · enum | nullable` The trigger calculation type for Take profit. Possible values: * `Price` * `Rate` * `Points` * `Pnl` **`order.takeProfit.triggerSize`** `decimal string | nullable` The trigger value in selected units. ```http title="Request example" POST /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/trigger-data HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "triggerSize": "-0.01", "triggerType": "rate", "isTrailing": true }, "takeProfit": { "triggerSize": 2500, "triggerType": "points" } } ``` #### Response [#response-13] In case of success, an object will be returned. Each object contains the following information: **`takeProfit.price`** `decimal string` The calculated Take profit price, based on trigger settings. **`takeProfit.rate`** `decimal string` The calculated Take profit rate. **`takeProfit.points`** `integer · int64` The calculated take profit offset, in points. **`takeProfit.pnl`** `decimal string` The projected PnL at Take profit. **`stopLoss.price`** `decimal string` The calculated Stop loss price, based on trigger settings. **`stopLoss.rate`** `decimal string` The calculated Stop loss rate. **`stopLoss.points`** `integer · int64` The calculated Stop loss offset, in points. **`stopLoss.pnl`** `decimal string` The projected PnL at Stop loss. ```json title="Response example — 200: OK" { "takeProfit": { "price": "248.27", "rate": "0.1119", "points": 2500, "pnl": "21.5" }, "stopLoss": { "price": "221.04", "rate": "-0.01", "points": -223, "pnl": "-1.91" } } ``` ### Submit triggers [#submit-triggers] `PUT` `/frontoffice/api/v4/positions/``{positionId}``/triggers` #### Summary [#summary-14] Use this method to modify Stop loss and Take profit settings for an open position. #### Request [#request-14] ##### Header parameters [#header-parameters-14] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-4] **`positionId`** `required` The position identifier. ##### Body [#body-12] **`stopLoss.price`** `decimal string` The Stop loss trigger price. **`stopLoss.isTrailing`** `boolean` If `true`, enables the Trailing behavior for Stop loss. **`takeProfit.price`** `decimal string` The Take profit trigger price. ```http title="Request example" PUT /frontoffice/api/v4/positions/01K2HYXA7N2G9NHTFEWYVM9SEQ/triggers HTTP/1.1 Host: {host} Authorization: Bearer JWT accountId: {accountId} Content-Type: application/json; x-api-version=4.0 Accept: */* { "stopLoss": { "price": "165.13", "isTrailing": true }, "takeProfit": { "price": 250 } } ``` #### Response [#response-14] In case of success, an object will be returned containing the identifier of the updated position. ```json title="Response example — 200: OK" { "positionId": "01K2HYXA7N2G9NHTFEWYVM9SEQ" } ``` ## Commissions [#commissions] ### Get account trading volume [#get-account-trading-volume] `GET` `/frontoffice/api/v3/commission/``{dynamicCommissionGroupId}``/account-trading-volume` #### Summary [#summary-15] Use this method to obtain a cumulative account trading volume used for calculating the commission tier. #### Request [#request-15] ##### Header parameters [#header-parameters-15] **`accountId`** `required` The trading account identifier. ##### Path parameters [#path-parameters-5] **`dynamicCommissionGroupId`** `required` The dynamic commission group identifier. Use [Get market](settings#get-market) to obtain. ```http title="Request example" GET /frontoffice/api/v3/commission/{dynamicCommissionGroupId}/account-trading-volume HTTP/1.1 Host: {host} Authorization: Bearer JWT Content-Type: application/json; x-api-version=4.0 Accept: */* ``` #### Response [#response-15] In case of success, an object will be returned containing current trading volume, in RAT, for the account. ```json title="Response example — 200: OK" { "currentTradingVolumeInRAT": "string" } ``` You can connect B2Trader to **ChatGPT** as a **connector**. It uses the same B2Trader MCP URL and OAuth sign-in as every other agent. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in ChatGPT's connector directory. Connector availability depends on your ChatGPT plan. ## Connect the B2Trader connector [#connect-the-b2trader-connector] 1. In ChatGPT, open **Settings** → **Connectors**. 2. Choose to add a connector by **URL** (custom connector). 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Confirm. ChatGPT reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — no API key is pasted into ChatGPT. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. ChatGPT lists the connector as connected, and the B2Trader tools become available to it. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — ChatGPT receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and ChatGPT stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector appears as connected in ChatGPT's settings. * B2Trader tools are available to ChatGPT in your chats. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In ChatGPT, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). You can connect B2Trader to **Claude** in two places: * **claude.ai** (web and desktop app) — add B2Trader as a **custom connector**. * **Claude Desktop** — add B2Trader as an MCP server; the OAuth sign-in completes through Claude's hosted redirect (`https://claude.ai/api/mcp/auth_callback`). Both use the same B2Trader MCP URL and the same OAuth sign-in. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` Ask your broker for the exact base URL for your platform. The read-only connector may also be discoverable directly in Claude's connector directory. ## Connect on claude.ai [#connect-on-claudeai] 1. Open **Settings** → **Connectors** in claude.ai. 2. Click **Add custom connector**. 3. Paste the B2Trader MCP **URL** for the surface you want (read-only or full access). 4. Click **Add**. Claude reads the endpoint's OAuth metadata and opens the sign-in page for your platform in your browser. 5. Sign in with the credentials you normally use. Depending on how your broker set up your platform, this is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account. Authentication uses OAuth 2.1 with PKCE — you are **not** pasting an API key into Claude. 6. **Full access only:** approve the consent screen (see [The full-access consent screen](#the-full-access-consent-screen)). 7. Claude shows the connector as **Connected**, and the B2Trader tools appear in the tool list for your conversations. ## Connect in Claude Desktop [#connect-in-claude-desktop] 1. Open **Claude Desktop** → **Settings** → **Connectors**. 2. Add a new MCP server pointing at the B2Trader MCP URL for your surface. 3. Claude Desktop opens your browser for OAuth sign-in and completes the flow through Claude's **hosted** redirect (`https://claude.ai/api/mcp/auth_callback`), a pre-registered redirect URI. 4. Sign in and — for full access — approve the consent screen. 5. The B2Trader tools appear in Claude Desktop once the connector reports **Connected**. ## The full-access consent screen [#the-full-access-consent-screen] When you connect the **full-access** surface, B2Trader shows an explicit consent screen before issuing a token. It reads: Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. * **Approve** — Claude receives a token carrying the `mcp:trade` scope and can trade on your account. * **Decline** — no token is issued and Claude stays disconnected from the full-access surface. The read-only surface does **not** show this screen — it only grants the `mcp:read` scope. Before approving full access, read [Full-access safety](full-access-safety). ## What "connected" looks like [#what-connected-looks-like] * The connector is listed as **Connected** in Claude's settings. * B2Trader tools (for example `trader_get_accounts`, plus platform market-data and portfolio tools) are available to Claude in your conversations. * On read-only, no order-placing or position-closing tools appear — they are not part of that surface. ## Disconnecting [#disconnecting] * In Claude, remove the connector to stop it calling B2Trader. * To revoke B2Trader's side of the grant, use the account console — see [How to stop your agent](full-access-safety#how-to-stop-your-agent). If you are building your own agent (for example with an Agent SDK) or using an MCP client that is not Claude or ChatGPT, you connect to the same two B2Trader endpoints and the same OAuth flow. This page covers the OAuth details a custom client needs. Pick the surface you need first — see [Overview](overview): * Read-only: `https:///mcp-read-only` * Full access: `https:///mcp-full-access` `` is the domain you open your B2Trader terminal on, not a separate API address. ## OAuth discovery [#oauth-discovery] Your client needs no B2Trader-specific configuration beyond the MCP URL. B2Trader is an OAuth 2.1 protected resource and advertises everything a compliant client needs: 1. Your client calls the MCP endpoint without a token and receives `401 Unauthorized` with a `WWW-Authenticate: Bearer resource_metadata="…"` header. 2. That header points at the protected-resource metadata (RFC 9728) for the surface you called — each surface has its own document: `https:///.well-known/oauth-protected-resource/mcp-read-only` and `https:///.well-known/oauth-protected-resource/mcp-full-access`. Fetching it returns the resource identifier, the authorization server (your broker's Keycloak realm), and `scopes_supported` — one scope only, matching the surface: `[mcp:read]` for `/mcp-read-only`, `[mcp:trade]` for `/mcp-full-access`. 3. Your client runs the standard OAuth 2.1 **authorization-code flow with PKCE** against that authorization server, requesting the scope for the surface you want. 4. B2Trader validates the token's audience (`bbp-mcp`) and the required scope (`mcp:read` for read-only, `mcp:trade` for full access) before serving any tool. Use a compliant MCP client library — it performs discovery, PKCE, and token refresh for you. You only supply the MCP URL. ## Pre-registered OAuth clients [#pre-registered-oauth-clients] B2Trader ships two pre-registered public OAuth clients. Use the one matching your surface: | Surface | `client_id` | Scope | Consent | | ----------- | ----------------- | ----------- | ---------------------------- | | Read-only | `mcp-read-only` | `mcp:read` | None | | Full access | `mcp-full-access` | `mcp:trade` | Explicit trade-scope consent | Both are **public** clients (no client secret) and require **PKCE (S256)**. A custom client authenticates as one of these `client_id`s and completes the browser sign-in as any other agent does. Depending on how your broker set up your platform, the page that opens is either the B2Trader sign-in form or the sign-in page of the portal you normally use to access your account — your client behaves the same either way. ## Command-line agents (Codex CLI, Claude Code) [#command-line-agents-codex-cli-claude-code] Command-line MCP clients default to **Dynamic Client Registration (DCR)** — on first connect they try to register a brand-new OAuth client with the authorization server instead of using a fixed `client_id`. The B2Trader Keycloak realm does not permit anonymous DCR, so these tools must be told to use one of the pre-registered `client_id`s above: * **Codex CLI:** ```bash codex mcp add --url --oauth-client-id mcp-full-access codex mcp login ``` Use `mcp-read-only` in place of `mcp-full-access` for the read-only surface. * **Claude Code:** ```bash claude mcp add --transport http --client-id mcp-full-access --callback-port 8080 ``` Without an explicit `client_id`, both tools fall back to anonymous DCR, which the authorization server rejects — the connection fails before you reach the sign-in page. ## Redirect URIs [#redirect-uris] The pre-registered clients accept these redirect URIs: | Redirect URI | Use | | ------------------------------------------------------- | ----------------------------------------------------- | | `https://claude.ai/api/mcp/auth_callback` | Claude (claude.ai) | | `https://chatgpt.com/connector_platform_oauth_redirect` | ChatGPT | | `http://localhost:8080/*` | Claude Code — fixed callback port | | `http://127.0.0.1/*` | Codex CLI and other loopback clients — ephemeral port | If your custom agent runs locally, use one of the loopback redirects above. Most Agent SDKs and MCP client libraries (including Codex CLI) default to an ephemeral-port loopback callback on `127.0.0.1`, matching `http://127.0.0.1/*`, so no configuration change is needed. Claude Code is the exception: it needs a **fixed** callback port to match a registered redirect, so pass `--callback-port 8080` (matching `http://localhost:8080/*`) as shown above. ## Adding a custom redirect URI (broker step) [#adding-a-custom-redirect-uri-broker-step] If your agent runs on a hosted callback URL that is **not** one of the above (for example a server-side agent with its own public redirect), your broker must add that redirect URI to the pre-registered client in Keycloak before sign-in will succeed. A redirect URI that is not registered on the client fails at the sign-in step with an "Invalid redirect URI" error from Keycloak. Send your broker the exact callback URL your agent uses and which surface it needs (read-only or full access). Adding a redirect URI is a broker-side change to the MCP client registration. It requires no product change and is the documented path for onboarding custom, non-marketplace agents. ## Full access [#full-access] If your custom agent uses the full-access surface, the same [full-access safety](full-access-safety) rules apply: no per-action confirmation, irreversible actions, and the prompt-injection risk of an autonomous agent. Read that page before granting `mcp:trade`. The full-access surface (`/mcp-full-access`) lets a connected AI agent trade on your account **directly**. This page explains exactly what that means and how to stay in control. Read it before you approve the full-access consent screen. Connecting this AI agent lets it place, cancel and close orders and set triggers on your account directly, with no per-action confirmation. These actions are irreversible. This differs from the in-terminal AI chat, which confirms each trade. ## No per-action confirmation [#no-per-action-confirmation] The in-terminal **AI Assistant chat** asks you to confirm each trade before it executes. The full-access MCP surface does **not**. Once connected, the agent can place, cancel, and close orders and set price triggers on its own, as fast as it decides to — there is no confirmation dialog and no "are you sure?" step. ## Actions are irreversible [#actions-are-irreversible] Trades execute against the live market. A filled order, a closed position, or a cancelled order **cannot be undone**. If your agent makes a mistake — or is manipulated into one — the market result stands. ## Prompt-injection risk [#prompt-injection-risk] An autonomous agent acts on the text it reads. If your agent processes untrusted content — a web page, an email, a chat message, a document — that content can contain hidden instructions telling the agent to trade against your interest. This is called **prompt injection**. Because the full-access surface has no confirmation gate, a successful injection can move real money before you notice. To reduce the risk: * Prefer the **read-only** surface unless you specifically need the agent to trade. * Only grant full access to agents and workflows you trust and control. * Be cautious about letting a full-access agent read untrusted external content in the same session it can trade. ## How to stop your agent [#how-to-stop-your-agent] You have two independent controls. Use either — or both. 1. **Stop it in the agent (fastest).** Disconnect or remove the B2Trader connector in your agent (Claude, ChatGPT, or your custom client). The agent immediately stops making new calls. 2. **Revoke the grant in B2Trader.** Open your **account console** (your broker's Keycloak account page) → **Applications**, find the connected MCP application, and **revoke** its access. This removes your consent so the agent cannot obtain a new token. There is no broker-side "kill switch" that instantly voids a token already in the agent's hands. A token the agent already holds stays valid until it expires (see [Access tokens are short-lived](#access-tokens-are-short-lived)). Revoking in the account console stops **new** tokens; disconnecting in the agent stops it using the one it has. Do both to be certain. ## You still get execution notifications [#you-still-get-execution-notifications] Every order the agent places, cancels, or closes fires the **same account notifications** you already receive for terminal activity. Your normal notification channels keep working, so a full-access agent cannot act silently — watch them to see what your agent is doing. ## Access tokens are short-lived [#access-tokens-are-short-lived] The agent's access token has a **short lifetime**. If you revoke consent in the account console, the agent can finish using its current token but cannot get a new one once it expires — so a revoked grant fully lapses within the token's short window, without any forced server-side revocation. ## Choosing read-only instead [#choosing-read-only-instead] If you do not need the agent to trade, connect the **read-only** surface (`/mcp-read-only`) instead. Its tools cannot place or change anything — the trading tools are not part of that surface at all. See [Overview](overview) for the comparison. B2Trader can expose your trading account to external AI agents through the **Model Context Protocol (MCP)** — an open standard that lets AI applications such as Claude and ChatGPT call a defined set of tools on your behalf. Once you connect an agent, it can read your market data and portfolio, and — on the full-access surface — place and manage orders directly. This is different from the **in-terminal AI Assistant chat**, which runs inside the B2Trader terminal and confirms each trade with you before it executes. An external MCP agent runs in *its own* application (Claude, ChatGPT, or your own client) and connects to B2Trader over the internet using your account sign-in. Connecting an AI agent is optional — it's your choice whether to use it. The MCP surfaces are available by default, though your broker can restrict or disable them for your platform. The MCP endpoints live on the same domain you use to open your B2Trader terminal, so wherever these pages show `https:///…`, that means your terminal address — not a separate API address. If a connection URL below doesn't work, contact your broker. ## Two surfaces [#two-surfaces] B2Trader publishes **two** separate MCP endpoints. You choose one when you connect your agent. | | Read-only | Full access | | ------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **Endpoint path** | `/mcp-read-only` | `/mcp-full-access` | | **What the agent can do** | View market data, your portfolio, order and position history, and analytics | Everything in read-only **plus** place, cancel, and close orders and set price triggers | | **Tools exposed** | 23 | 39 | | **Trading** | None — mutating tools are not present at all | Full trading, with **no per-action confirmation** | | **OAuth scope** | `mcp:read` | `mcp:trade` | | **Consent screen** | No extra consent | Explicit trade-scope consent (see [Full-access safety](full-access-safety)) | | **Marketplace-listed** | Yes | No — connect by URL | The **read-only** surface is the one listed in AI marketplaces (for example the Claude and ChatGPT connector directories). It is safe to connect broadly: the trading tools are **structurally absent** — the agent cannot see or call them. The **full-access** surface is connected by pasting its URL directly. It grants your agent the ability to trade with no confirmation gate. Read [Full-access safety](full-access-safety) before you connect it. ## Tool categories [#tool-categories] Both surfaces expose the same read tools; the full-access surface adds the mutating ones. | Category | Read-only | Full access | | ------------------------------------------------------------------------------ | --------- | ----------- | | Market data — B2Trader platform prices (tickers, order book, market summaries) | Yes | Yes | | Portfolio & account (balances, margin, open positions) | Yes | Yes | | Order & position history | Yes | Yes | | Analytics & reference data | Yes | Yes | | Place / cancel / close orders (single) | No | Yes | | Bulk order / position actions | No | Yes | | Set & edit price triggers, other account mutations | No | Yes | | **Total tools** | **23** | **39** | The 16 tools that the full-access surface adds are the mutating actions: single trading actions, bulk trading actions, and non-trading account mutations. ## Which surface to choose [#which-surface-to-choose] * **Choose read-only** if you want an agent to analyze markets, summarize your portfolio, or answer questions about your trading history. This is the recommended default and the safest option. * **Choose full access** only if you deliberately want your agent to trade for you without confirming each action, and you understand the risks in [Full-access safety](full-access-safety). ## Prerequisites [#prerequisites] Before connecting any agent you need: * A **B2Trader account** on a platform that offers the MCP surfaces. They are available by default; a broker can restrict or disable them. * Your account must be **active** (`bbp.spot.status = Active`) — the same status required to trade in the terminal. A non-active account can sign in, but its tool calls are rejected by the platform. * An AI application that supports MCP with OAuth — for example [Claude](connect-claude), [ChatGPT](connect-chatgpt), or a [custom agent](connect-custom-agent). ## How connecting works [#how-connecting-works] You never paste an API key or password into your agent. Connection uses **OAuth 2.1 with PKCE**: 1. You add the B2Trader MCP URL to your agent. 2. The agent discovers B2Trader's authorization server automatically — it reads the endpoint's protected-resource metadata at `/.well-known/oauth-protected-resource/mcp-read-only` or `/.well-known/oauth-protected-resource/mcp-full-access`, depending on the surface. 3. Your browser opens the sign-in page for your platform, where you sign in with the credentials you normally use. 4. For the full-access surface, you approve an explicit consent screen describing what the agent may do. 5. The agent receives a short-lived access token and is connected. No long-lived secret is stored in the agent. The sign-in page you see depends on how your broker set up your platform: either the B2Trader sign-in form, or the sign-in page of the portal you normally use to access your account, which opens automatically. If you are already signed in there in the same browser, no sign-in prompt appears. The per-client steps are covered in the connection guides: * [Connect Claude](connect-claude) * [Connect ChatGPT](connect-chatgpt) * [Connect a custom agent](connect-custom-agent) * [Full-access safety](full-access-safety) ## Global interface controls [#global-interface-controls] ### Account selection [#account-selection] The **Account select** is located in the topbar and enables you to switch between your trading accounts. Each account shows its type: `H` (Hedging) or `N` (Netting). Once you switch the account, all the widgets automatically adjust to show relevant information for the selected account. Account select #### Account status [#account-status] An account can have a status that limits what you can do with it. When a status applies, a status indicator is shown on the account, and a banner explains the restriction. Account status is managed by your administrator. The following statuses are visible to you: * **Halted**: A banner reads *Account is locked for trading. Contact your administrator.* The trading controls are disabled, but you can still deposit and withdraw funds, and your balances, positions, and history stay visible. * **Frozen**: A banner reads *Account is frozen. Contact your administrator.* The account is view-only. All controls are disabled, while your balances, positions, and history stay visible. To restore trading on an account that is Halted or Frozen, contact your administrator. Archived accounts don't appear in the account list. ### Instrument selection [#instrument-selection] The **Instrument select** is located in the topbar and enables you to switch between various markets and trading pairs. Once you change the market, all the widgets automatically adjust to show relevant information for the selected instrument. Instrument select #### Favorite markets [#favorite-markets] Mark instruments as favorites for quick access. To add or remove a market from favorites, click the **star icon** next to the market name in the instrument selection list. Favorite markets can be accessed in two ways: * **Favorites tab** in the instrument selection panel — filters the list to show only your favorite markets. * **Favorites dropdown** in the topbar — provides quick access to favorite markets from anywhere in the terminal. ### Settings [#settings] Use this control to access interface and system settings. Refer to [Settings](settings) for details. Settings ### Other controls [#other-controls] * **Introduction tour**: Access the interactive platform walkthrough. Introduction tour * **Alerts**: View new system notifications. Unread alerts * **Analytics**: Open the **Account Analytics** view with the **Equity Curve** chart — your account balance and equity dynamics over time (Margin Balance, Equity, Total Equity, Unrealized PnL, Deposits / Withdrawals) for a selected period and granularity. The data updates hourly. Click **Back to Trading** to return to the terminal. Analytics * **Log out**: Log out of the system to securely terminate the session. After that you’re navigated to the Login page. Log out ## Working with widgets [#working-with-widgets] > For more information about available widgets, refer to the **Widgets** section of this guide. ### Add widgets to your workspace [#add-widgets-to-your-workspace] **To add a new widget**: 1. Click the **Add Widget** button. 2. Browse the available widgets. 3. Click any widget to add it to your workspace. Add Widget **To add widgets to existing panels**: 1. Look for the **+** button next to the tabs in a panel's header. 2. Click it to open the widget catalog. 3. Select a widget to add it as a new tab to that panel. Add widget tabs ### Move and position widgets [#move-and-position-widgets] **To move a widget**: 1. Click and hold the **move handle** in the top-right corner of the panel header. 2. Drag it to desired location on the page. 3. Drop it. Move widgets **To rearrange widget tabs within a panel**: 1. Click and hold any widget tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ### Resize widgets [#resize-widgets] **To resize a widget panel**: * **Single edge**: Hover over any edge until you see the resize cursor, then drag. * **Corner resize**: Drag a corner to adjust both width and height simultaneously. * **Precision**: Use edge dragging for fine-tuned sizing. Resize widgets ### Remove widgets and tabs [#remove-widgets-and-tabs] **To remove a tab**: 1. Click the **×** button in the top-right corner of the widget tab. 2. The tab will be removed immediately. 3. When you remove the last tab from a panel, the entire panel disappears. Remove tabs and widget panels ### Link panels to a group [#link-panels-to-a-group] Each panel header has a **Link to group** button — the circle icon **next to the move handle** in the top-right corner. Linking panels to the same colored group keeps them in sync: when you select an instrument in one linked panel, the other panels in the same group switch to it automatically. **To link a panel to a group**: 1. Click the **Link to group** button (next to the move handle) in the panel's top-right corner. 2. Select one of the color groups (Group 1–5). 3. Repeat for other panels, choosing the same group to keep them synchronized. Link to group ### Customize widget content [#customize-widget-content] Certain widgets let you customize which columns to display and their order: Look for the **column settings** button in the widget header. **To customize columns**: 1. Click the **column settings** button. 2. **Show/hide columns**: Check or uncheck boxes (grayed-out columns are required). 3. **Reorder columns**: Drag and drop items in the list. 4. **Reset**: Click *Reset to default* to restore original settings. Configure columns ## Managing workspaces [#managing-workspaces] ### Create new workspaces [#create-new-workspaces] **To create a workspace**: 1. Click the **+** tab next to your existing workspaces. 2. Choose a template: * **Pre-built templates**: Start with common widget combinations. * **Empty**: Build completely from scratch. 3. Enter a name for your workspace. 4. Start customizing. Add a new workspace ### Workspace management [#workspace-management] **To rename or delete a workspace**: 1. Click the menu icon on the workspace tab. 2. Select **Rename** or **Remove**. Workspace menu **To reorder workspaces**: 1. Click and hold any workspace tab. 2. Drag it left or right to reorder. 3. Release to set the new position. ## Market info panel [#market-info-panel] Click the **info icon** next to a market symbol in widgets to view: * Detailed market information. * Trading session schedules. * Leverage details (for CFD and PF markets). * Fee details. * Funding details (for PF markets). Market info ## Pro tips [#pro-tips] ### Efficient layout building [#efficient-layout-building] * Start with a template that is close to your needs, then customize. * Group related widgets in tabs to save screen space. * Use larger panels for charts, smaller ones for order books. ### Layout best practices [#layout-best-practices] * **Save multiple workspaces** for different trading strategies. * **Test your layout** during low-activity periods. * **Keep essential widgets visible** (account info, positions, alerts). Access settings by clicking the **gear icon** in the topbar of the Trading terminal. Settings Settings are organized into tabs: * [Interface](#interface): Configure language, time display, and visual theme. * [Widgets](#widgets): Customize widget display options. * [Action Confirmation](#action-confirmation): Choose which actions require additional confirmation. * [Account margin](#account-margin): Manage collateral assets for margin trading. * [Trading report](#trading-report): Generate comprehensive trading and account reports. * [API token management](#api-token-management): Generate and manage tokens for accessing the Trading API. * [TradingView Webhooks](#tradingview-webhooks): Configure TradingView webhook alerts for automated order execution. ## Interface [#interface] Configure global interface preferences: **Language** Select the interface language from the dropdown menu. **24 hour mode** * Enable: Display time in 24-hour format. * Disable: Display time in 12-hour format with AM/PM. **Dark theme** * Enable: Apply dark color scheme. * Disable: Apply light color scheme. ## Widgets [#widgets] Configure display options for the following widgets. ### Price chart [#price-chart] **Display positions** When enabled, open positions are shown on the chart along with: * Position size and current PnL. * Quick access to edit price triggers and close positions. * Color coding: Long positions (green), Short positions (red). **Display orders and triggers** When enabled, the following orders and triggers are displayed on the chart: * Active Limit and Stop orders with order type, price, and amount. * Stop loss, Take profit, and Trailing stop triggers. * Quick access to edit triggers and cancel orders. * Color coding: Buy orders (green), Sell orders (red). **Display executed orders** When enabled, executed orders are shown on the chart with order type indicators: * Green `B` tag for Buy orders. * Red `S` tag for Sell orders. Clicking `B` or `S` will open details of one or more orders that were executed during the candle interval. **Market quick trade panel** When enabled, a panel is displayed on the chart for placing Market orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. **Limit quick trade panel** When enabled, a panel is displayed on the chart for placing Limit orders with: * Quick amount selection from preset values. * Leverage ratio input (when applicable). Amount presets can be configured in the corresponding field displayed when the option is enabled. ## Action Confirmation [#action-confirmation] Choose which trading actions require an additional confirmation dialog before execution. **Cancel orders** * Enable: A confirmation dialog is displayed before canceling orders. * Disable: Orders are canceled immediately without confirmation. This setting applies to single and bulk order cancellations from the **Open Orders** widget and the **Price chart**. The confirmation dialog includes a **"Don't ask again"** checkbox. To skip the confirmation for future order cancellations, check this box. **Full Close Positions** * Enable: A confirmation dialog is displayed before closing positions. * Disable: Positions are closed immediately without confirmation. This setting applies to single and bulk position closures from the **Open Positions** widget. **Limit order cross-TOB warning** * Enable: A confirmation dialog is displayed before a Limit order is submitted if its price crosses the current top-of-book — that is, when a Buy price is at or above the best ask, or a Sell price is at or below the best bid. The dialog shows the entered price and the current best bid/ask, and includes a **Do not show this warning again** checkbox. * Disable: Crossing Limit orders are submitted immediately without the warning. The warning is enabled by default. The dialog checkbox and this toggle share the same global setting and stay in sync. The warning is informational only — it does not block the order. If you confirm, the order is submitted with the original price. The warning applies only to standard Limit orders; Stop-limit, Take-profit-limit, IOC, FOK, and other order types are not affected. If best bid or best ask data is unavailable (empty book or disconnected feed), the order is submitted without the warning. ## Account margin [#account-margin] Control which assets can be used as collateral for margin trading. ### Asset list [#asset-list] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance available for trading, calculated as *Total – Halted*, where *Halted* represents funds locked for pending Limit orders. *** **Total** The complete asset balance including locked funds. *** **Margin ratio** The percentage of asset value that can be used as collateral for margin trading. *** **Use as margin** Enable this toggle to use the asset as collateral for margin trading. Configure which assets can be used as collateral for margin trading by toggling the **Use as margin** setting for each asset. Only assets with **Margin ratio** greater than 0 (zero) can be enabled. The platform root asset is enabled by default and can't be disabled. ### Filtering options [#filtering-options] Click the **funnel icon** to configure the asset list display: * **Show/Hide zero balances**: Control visibility of assets with zero balance. By default, hidden. * **Show/Hide assets unused as margin**: Control visibility of assets with disabled margin usage. * **Show/Hide assets with zero margin ratio**: Control visibility of assets that can't be used as collateral. By default, hidden. ## Trading report [#trading-report] Generate comprehensive reports containing: * **Trade history** * Closed positions * Executed orders * Individual trades * **Transfers history** * All account transfers * **Account statistics** * Total balance * Realized PnL * Position swaps * Position funding * Commissions To generate a report: 1. Select a custom period of time (UTC time), or generate a report for your entire account history using the **All data** range. The following timeframe presets have been implemented for your convenience: * **Today** * **Current**: week, month, quarter * **Previous**: week, month, quarter * **All data**. 2. Click **Download**. Once generated, the report will be automatically downloaded to your computer as a zipped CSV file. ## API token management [#api-token-management] Generate tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/): * **Limit**: 10 tokens per account * **Validity**: 1 year * **Management**: Can be revoked or deleted at any time To generate a token: 1. Click **+ Create new**. 2. In the **New API token** popup, fill in a **Name** for the token, to help you identify it later. 3. Click **Create**. The newly generated token will be displayed and available for copying, along with its name and expiration date. The token only reveals once in the creation popup. Copy and store it securely before closing the popup. The token can't be retrieved again after closing. ## TradingView Webhooks [#tradingview-webhooks] Use TradingView Webhooks to automatically execute orders on your trading account based on alerts from TradingView. When a TradingView alert triggers, it sends a webhook request to B2TRADER, which places an order according to the parameters specified in the alert message. This feature supports all market types: Spot, CFD, and Perpetual Futures. ### Set up the webhook [#set-up-the-webhook] #### Step 1: Create a webhook API key [#step-1-create-a-webhook-api-key] To create a webhook API key in the Trading terminal: 1. Click the **gear icon** in the topbar to open Settings. 2. Navigate to the **TradingView Webhooks** tab. 3. Click **+ Create new**. 4. In the popup, fill in a **Name** for the key. 5. Click **Create**. The popup displays the generated API key and the webhook URL. Copy both values and store them securely. The API key is shown only once at creation. It can't be retrieved after closing the popup. The following limits apply: * Maximum 10 active keys per user * Each key is valid for 1 year from creation * Keys can be revoked at any time #### Step 2: Configure the alert in TradingView [#step-2-configure-the-alert-in-tradingview] 1. In TradingView, create a new alert or edit an existing one. 2. In the **Notifications** section, enable **Webhook URL**. 3. Paste the webhook URL copied from the terminal. 4. In the **Message** field, enter the alert body in JSON format (see [Alert message format](#alert-message-format)). 5. Save the alert. When the alert triggers, TradingView sends the message to B2TRADER, and the order is placed automatically. ### Alert message format [#alert-message-format] The alert message is a JSON object with the following fields: | Field | Required | Description | | ----------------- | ----------- | -------------------------------------------------------------------------- | | `apiKey` | Yes | Webhook API key generated in the terminal | | `accountId` | Yes | Trading account ID | | `symbol` | Yes | Market symbol with type prefix (see [Symbol format](#symbol-format)) | | `side` | Yes | Order side: `buy` or `sell` | | `quantity` | Yes | Order quantity in base asset | | `orderType` | No | `market` (default), `limit`, `stop`, or `stop_limit` | | `price` | Conditional | Limit price. Required for `limit` and `stop_limit` orders | | `stopPrice` | Conditional | Stop price. Required for `stop` and `stop_limit` orders | | `leverage` | No | Leverage ratio. Applicable to CFD and Perpetual Futures markets only | | `takeProfit` | No | Take profit trigger price | | `stopLoss` | No | Stop loss trigger price | | `timeInForce` | No | `gtc` (default), `ioc`, `fok`, or `day` | | `comment` | No | Custom comment, up to 256 characters | | `deduplicationId` | No | UUID for idempotency. Duplicates within 5 minutes return a cached response | #### Symbol format [#symbol-format] The symbol must include a market type prefix: | Market type | Prefix | Example | | ----------------- | ------- | --------------- | | Spot | `spot.` | `spot.btc_usdt` | | CFD | `cfd.` | `cfd.eur_usd` | | Perpetual Futures | `perp.` | `perp.btc_usdt` | #### Examples [#examples] **Market buy order (Spot):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "spot.btc_usdt", "side": "buy", "quantity": "0.01" } ``` **Limit sell order with TP/SL (CFD):** ```json { "apiKey": "wh_key_your_api_key_here", "accountId": "your_account_id", "symbol": "cfd.eur_usd", "side": "sell", "orderType": "limit", "price": "1.0900", "quantity": "1000", "leverage": "10", "takeProfit": "1.0800", "stopLoss": "1.0950", "timeInForce": "gtc" } ``` ### Manage webhook API keys [#manage-webhook-api-keys] To view or manage your webhook API keys, navigate to **Settings** > **TradingView Webhooks**. The following information is provided about each key: | Column | Description | | ----------- | ----------------------------------------------- | | **Name** | The name assigned to the key at creation | | **Status** | Current key status: Active, Revoked, or Expired | | **Created** | The date and time the key was generated | | **Expires** | The date and time the key expires | To revoke a key, click the **Revoke** button next to the key entry. ### Rate limits [#rate-limits] Webhook requests are limited to 5 requests per second per user. If this limit is exceeded, the request returns a `429` error code and the order isn't placed. ### Troubleshooting [#troubleshooting] The following table describes common error scenarios and their solutions: | Issue | Cause | Solution | | -------------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | | `Invalid API key` | The API key is incorrect or wasn't copied in full | Generate a new key and update the TradingView alert | | `API key expired` | The key has passed its 1-year validity period | Generate a new key | | `API key revoked` | The key was manually revoked | Generate a new key | | `Invalid symbol format` | The symbol is missing a market type prefix | Add the prefix: `spot.`, `cfd.`, or `perp.` | | `Price required for limit order` | A `limit` or `stop_limit` order is missing the `price` field | Add the `price` field to the alert message | | `Rate limit exceeded` | More than 5 requests were sent within 1 second | Reduce the alert frequency in TradingView | | `Account not found` | The `accountId` doesn't exist or isn't accessible | Verify the account ID in the terminal | A market can be assigned one of the following statuses: * **Open**: The market is operating properly and accepts orders via Trading terminal and API. Market data for charts is persisted. * **Paused**: The market stops accepting incoming orders via Trading terminal and API (previously placed Limit orders still await execution). Market data for charts is persisted. * **Halted**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is persisted. * **Disabled**: The market stops accepting incoming orders via Trading terminal and API. All open Limit orders will be cancelled. Market data for charts is not persisted. * **Archived**: The market is retired from regular operations. It doesn't accept trading activity, isn't included in market synchronization responses, and its historical chart data is deleted. ## Market and Limit orders [#market-and-limit-orders] Orders can be assigned one of the following statuses: * **Started**: The order has passed preliminary checks. * **Pending**: For Limit orders: the order is waiting for a price trigger. * **Working**: The order is being executed. * **Completed**: The order has been executed in its full amount. * **Cancelled**: The order has been cancelled by a trader. * **Rejected**: The order has been rejected by the system and has never been assigned the *Working* status. * **Expired**: The order has been cancelled due to [Time in force](time-in-force) settings. Some part of it may have already been executed. The status is applicable for GTD and Day orders only. ## Stop orders [#stop-orders] Orders can be assigned one of the following statuses: * **Waiting for activation**: The order awaits the Activation price trigger. * **Activated**: The Activation price has been reached, a new Market or Limit order has been placed. * **Rejected**: The Activation price has been reached, but an issue occurred with placing of a new Market or Limit order. The following order types are supported: * **Market**: An instruction to instantly buy or sell a certain asset amount at a currently best price on the market. Such orders are not listed in the order book. * **Limit**: An instruction to buy or sell a certain asset amount at a specified price. Limit orders are placed in the order book and executed only after the market price reaches the specified limit price (or at a better price). * **Stop Market**: Such an order is not placed unless the current market price meets a specified stop (or trigger) price, after which the order is placed as a regular Market order due to be executed or cancelled, depending on its Time in force. * **Stop Limit**: The order is similar to the Stop Market order in the sense that you need to indicate the stop price at which the order must be placed, after which it becomes a regular Limit order awaiting execution at a specified limit price. For Stop buy orders, the stop price should be above the best ask price; for Stop sell orders, the stop price should be below the best bid price (otherwise, the orders will be activated instantly). Refer to [Time in force](time-in-force) to learn about execution parameters that can be specified for different order types. When trading on CFD or Perpetual markets, the following triggers can be enabled to manage investments and mitigate risks: * **Take profit**: A take-profit order is used to sell or buy an asset automatically once it hits a predefined price, ensuring the trader locks in profits. For example, if a trader buys ETH at $2,000 and sets the Take profit at $2,100, the platform will sell the ETH automatically when the market price reaches $2100, securing the trader's profit. * **Stop loss**: A stop-loss order is a tool to limit potential losses. It automatically sells an asset when its price falls to a predetermined level. For example, if a trader buys ETH at $2,000 and sets the Stop loss at $1,900, the asset will be sold if the price drops to $1,900, capping the loss to $100 per ETH. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified percentage. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. For example, a trader buys ETH at $2,000 and sets the Trailing stop at $1900 with a 10% adjustment. If ETH rises to $2,200, the Trailing stop increases to $2,090. A drop to $2,090 triggers the sale, locking in gains. The triggers are applicable to all order types: Market, Limit, Stop Market, and Stop Limit. Multiple triggers can be applied simultaneously. The triggers can be adjusted anytime until a position is fully closed. The Take profit, Stop loss, and Trailing stop always operate with the current position volume. For **buy** orders, the triggers are activated by the top-of-the-book **bid** price. For **sell** orders, the triggers are activated by the top-of-the-book **ask** price. Triggers do not activate if a position is in the *Stop out* state. However, if the position persists after the *Stop out*, triggers can then be activated. The following time-in-force settings can be specified for orders: * **FOK** (fill-or-kill): Such orders are either filled instantly or killed (cancelled). In other words, a fill-or-kill order must be fulfilled instantly or not executed at all. FOK orders are used when partial delivery of assets isn't acceptable for any reason. * **IOC** (immediate-or-cancel): This setting implies that any part of an order that can't be filled instantly must be cancelled. Upon placing an IOC order, an attempt will be made to instantly execute it (in full or in part) at the best possible price, after which any remaining, unfilled part will be cancelled. If no amount is available at a specified price upon placing such order, it's cancelled instantly. * **GTC** (good-‘til-cancelled): The default setting applied to all limit orders. Open GTC orders are awaiting execution until they are cancelled explicitly by a trader or filled. * **GTD** (good-‘til-date): Can be applied to limit and stop limit orders. Such orders remain listed in the order book until a specified date or until they are cancelled by a trader. By that time the order can be partially executed. * **DAY**: Can be applied to limit and stop limit orders. Such orders remain listed in the order book until 23:59 of the current day or until they are cancelled by a trader. By that time the order can be partially executed. The order expiration time is defined by the time settings specified for the BP, without taking into account the time settings of the devices from which the BP is accessed. ## iOS v1.35 [#ios-v135] This version includes: * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. Select a time period and granularity level to filter performance data, and switch between accounts using the built-in account selector. * **AI Assistant** A new **AI Assistant** widget provides AI-powered market analysis for each instrument, including trade recommendations, market sentiment, signal drivers, suggested actions, and key metrics. * **Quick order from the chart** You can now place orders directly from the **Price chart** by tapping a price pin. The **Quick Order** panel opens pre-filled at the selected price level for faster order placement. * **Customizable workspace** You can now reorder and show or hide bottom tabs in **Settings**, allowing you to tailor the terminal layout to your trading preferences. * **Adaptive interface by market type** Tabs, **Margin Level**, and perpetual funding indicators are now automatically hidden for accounts that do not have access to the corresponding market types, providing a cleaner and more focused interface. * **Landscape mode for the chart** Tapping the **Expand** button on the **Price chart** now automatically rotates the chart to landscape mode for a wider view. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.34 [#ios-v134] This version includes: * **Drag Take Profit and Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be adjusted by dragging their lines directly on the **Price chart**. Changes are applied to the order immediately, with automatic rollback if an error occurs. * **Demo accounts** Demo trading accounts are now supported, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets appear as chips in the market list and are indicated with an icon in the terminal. * **Credit in margin details** A dedicated **Credit** row has been added to the margin details section, providing visibility into credit amounts allocated to your trading account. * **Comments for orders, positions, and trades** You can now add a comment when placing an order or managing a position. The comment is visible throughout the trading lifecycle — on open orders, open positions, and in trade history. * **Margin Level display** When **Margin Level** data is unavailable, the field now displays "–" instead of 0% for clearer data visibility. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.33 [#ios-v133] This version includes: * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Hide zero balances settings relocated** The **Hide zero balances** toggle has been moved to the **Assets** tab for more intuitive access. * **Improved backend error messages** Backend error messages are now mapped to user-friendly descriptions, providing clearer feedback when issues occur. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.32 [#ios-v132] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Quick cancel button for open orders** The **Open orders** widget now features a quick **Cancel** button on each order card, enabling faster order cancellation directly from the list view. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Redesigned account selection header** The account selection section in the terminal header has been redesigned for improved navigation and a cleaner appearance. * **Updated closed positions design** The **Closed positions** widget has been updated with a refreshed layout for better readability and consistency with other trading widgets. * **Confirmation bottom sheet** Order and position actions now display a confirmation bottom sheet, helping to prevent accidental trades and providing a clearer review step before execution. * **Settings button relocated** The **Settings** button has been moved from the **Price chart** widget to the terminal header for easier access across all views. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.31 [#ios-v131] This version includes: Experience an advanced trading workflow with the introduction of our new **tiered leverage system**, offering dynamic leverage based on position size and enhanced margin visibility. This update also brings improved commission transparency with a dedicated Fees tab, enhanced market info, a new deposit shortcut, and updated screens for tiered commissions. We've also refined formatters to respect your selected app language for a more consistent experience. *** ## iOS v1.30 [#ios-v130] This version includes: * **Notifications widget** A new **Notifications** widget has been implemented providing quick access to system notifications related to price changes, Margin calls, Stop outs, Take profit and Stop loss triggers. * **Closing open positions from the Price chart** Open positions can now be closed directly on the **Price chart** screen ensuring quick reaction to volatile market conditions and efficient trade management. This feature is available if the **Display positions** setting is activated for the Price chart. * **Closing all open positions** The **Open positions** tab now features the **Close all** button that liquidates all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Canceling all active orders** The **Open orders** tab now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * **Trading session status** The **Trading session status** in the **Position details** is now accompanied by an info icon and an explanatory tooltip. * **Automatic horizontal scrolling for tabs** The horizontal auto scroll has been added to tabs. Active tabs are now automatically centered for optimal visibility and better accessibility to all available tabs. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.29 [#ios-v129] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding**/**Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Updated account creation process** When creating a trading account in the app, the **account type** can now be selected: **Hedging** or **Netting**, enabling traders to plan and adjust their trading strategies to maximize profit or reduce risk. Depending on the platform settings, the option may be prefilled or require manual selection. The account type can’t be changed after the account is created. * **Support for Take Profit, Stop Loss, and Trailing Stop** The **Take Profit**, **Stop Loss**, and **Trailing Stop** triggers are now supported in the app for CFD and PF trading. They can be applied to Market, Limit, and Stop orders, as well as to currently open positions. * **Support for price alerts** Price alerts are now fully supported in the app: * Multiple alerts can be added to monitor different price levels for any instrument. * Configure alerts based on a fixed price or a percentage change. * View a list of all configured alerts for each instrument. * Adjust or delete existing alerts as needed. * Triggered alerts are automatically removed to keep the list up to date. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order history widget. * **Admin-managed orders and positions** On the **Open positions**, **Closed positions**, and **Order history** widgets, if BP Admins have managed positions or orders, this is now indicated in the **Reason** field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, mitigate risks, or resolve outstanding positions before account termination. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## iOS v1.28 [#ios-v128] This version includes: * **Performance upgrade** Streamlined top-of-the-book ask and bid prices in the Place Order widget are now received through a dedicated socket for faster obtaining and display. * **Mobile and Web Consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** Placeholders are now displayed for empty fields and widgets for improved UX clarity. * **Internal improvements** Enhanced system logs for better diagnostics. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## Android v2.12.0 [#android-v2120] This version includes: * **AI Assistant** A new **AI Assistant** provides AI-powered market analysis for each market, including trade recommendations, a 12-month price forecast, market sentiment, signal drivers, suggested actions, and key metrics. * **Account Analytics** A new **Account Analytics** screen displays an equity curve and detailed trading statistics for your account. * **Account status indicators** Account statuses such as **Halted** and **Frozen** are now shown with badges and a warning banner, and the related trading actions are restricted accordingly. * **Quick order from the chart** You can now place orders directly from the **Price chart**, enabling faster reaction to market movements. * **Take Profit / Stop Loss on the chart** **Take Profit** and **Stop Loss** levels can now be set by dragging their lines directly on the **Price chart**, with support for trailing Stop Loss. * **Cross-price limit order warning** A warning is now displayed before you place a **Limit** order whose price crosses the top of the **Order book**. This warning can be enabled or disabled in **Settings**. * **Customizable trading terminal** You can now customize the trading terminal layout and tab order from the new **Workspace** settings. * **Adaptive interface by market type** Margin- and perpetual-related tabs and indicators are now hidden for accounts with access to **Spot** markets only, providing a cleaner interface tailored to the account type. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.11.0 [#android-v2110] This version includes: * **Comment field in Place Order** An optional **Comment** field has been added to the **Place order** form in **Advanced Mode**. The field supports up to 100 characters and is available for all order types across Spot, CFD, and Perpetual markets. * **Full-screen chart mode** The **Price chart** widget now supports full-screen mode. Tap the **Expand** button to switch to a landscape view for a more detailed chart analysis. * **Credit information in margin details** A **Credit** row has been added to the margin section, providing visibility into credit amounts allocated to trading accounts. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.10.0 [#android-v2100] This version includes: * **Quick close button for open positions** The **Open positions** widget now features a quick **Close** button on each position card, allowing you to close individual positions with a single tap without opening position details. * **Demo accounts** Demo trading accounts are now supported in the app, allowing you to practice trading strategies and explore the platform without risking real funds. * **Favourite markets** You can now mark markets as favourites for quick access. Favourite markets are synchronized between the web and mobile terminals. * **Click-to-fill price from Order book** Tapping a price level in the **Order book** widget now automatically fills the selected price into the **Place order** form, streamlining the order placement process. * **Hide zero balances** A new **Hide zero balances** toggle has been added to the **Assets** widget, allowing you to filter out assets with zero balance for a cleaner portfolio overview. * **Deposit and transfer options** A new **Deposit** button has been added to the account screen, providing quick access to deposit and transfer options. The available actions depend on your platform configuration. * **Navigate to market from alerts** You can now open the market chart directly from the **All Alerts** screen, providing faster access to price data for monitored instruments. * **Quick market navigation from trading widgets** Tapping a market name in **Open orders**, **Stop orders**, **Order history**, **Open positions**, or **Closed positions** now switches to that market directly, enabling faster navigation between instruments. * **Improved RAT rounding** All Rate to RAT and margin-related values now display according to the root asset scale rules, ensuring consistent and accurate financial data across the app. * **Improved market status display** The **Market Closed** label is now automatically removed once live data starts updating, providing a more accurate representation of market availability. * **Corrected Stop Market order calculations** **Value** and **Amount** calculations for **Stop Market** orders have been updated for improved accuracy. * Bug fixes and improvements to ensure a more seamless and efficient user experience. *** ## Android v2.9.0 [#android-v290] This version includes: This update introduces the new **tiered leverage system**, enhanced fee transparency and fully redesigned Fees tab, quick Deposit/Trade shortcuts on account cards for faster navigation and various UI improvements across the app. *** ## Android v2.8.0 [#android-v280] This version includes: * **Asset balance in RAT** The **Assets** list now displays **Available** and **Total** balance equivalents in RAT for better portfolio overview and value tracking. * **Simplified Markets list** The market full names have been removed from the **Markets** list for cleaner appearance. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.7.0 [#android-v270] This version includes: * **Key position parameters on the TP/SL editing** Key position parameters, such as **Name**, **Side**, **Amount**, **Open price**, **Current price**, and **Leverage** are displayed at the top of the Take Profit/Stop Loss configuration screen to give you immediate, accurate context and reduce input errors. Values are updated in real time. * **Closing positions on the Price chart** You can now close positions directly on the **Price chart** widget, by tapping a position indicator. * **Canceling all active orders** The **Open orders** widget now features the **Cancel all** button allowing to close all *Pending* and *Working* orders at once. This reduces reaction time in volatile markets and removes the necessity to close orders individually. * **Closing all open positions** The **Open positions** widget now features the **Close all** button allowing to liquidate all open positions at once. This allows you to react immediately to sharp price moves, limiting losses, and removes the necessity to close positions individually. * **Closed position details** The **Order type** and **Time in force** values are now displayed for every closed position to improve trade execution transparency. * **Price chart settings saved** The **Price chart** widget now remembers your preferred timeframe and chart type settings. Each time you open the terminal, it displays the chart with your last selected settings. * **Market details in Place order** The market name and last price values have been added to the **Advanced** mode of the **Place order** widget. The price is updated in real time. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.6.0 [#android-v260] This version includes: * **Perpetual Futures (PF) trading now available in the app** PF trading is now supported in the app, introducing a new market type and expanding trading opportunities. To support this, the following features have been added for perpetual markets: * The **Funding/Countdown** information, including a countdown timer and current funding rate, helping traders stay informed about upcoming settlements. * A new **Funding** tab that displays the current funding rate, a historical chart, and detailed rate and settlement information. * **Improved filtering** To help traders quickly find the necessary data, advanced filtering options have been added to the following widgets: **Open positions**, **Closed positions**, **Open orders**, **Stop orders**, and **Order history**. New filters include: * **Market options**, such as All Markets, Current Market, Spot, CFD, and Perpetual. * **Time period** selectors specific to each widget. * **Status** filters for the Order History widget. * **Enhanced Price chart widget** Several visual enhancements have been added to the Price chart widget to provide greater clarity and deeper trading insights: * Active **Limit** and **Stop orders** that aren’t yet in final status are now visually represented using horizontal lines – green for buy orders and red for sell orders. This enables traders to view active orders in real time on the chart, relative to current market price movements. This feature can be turned on or off in the Price chart settings. * **Executed orders** are now visually represented using arrow icons – green for buy orders and red for sell orders. This feature is available for the **Line** and **Candles** chart display options and can also be turned on or off in the Price chart settings. * **Stop Loss** (SL) and **Take Profit** (TP) levels are now visually displayed as color-coded horizontal lines, labeled with their abbreviations. Tap on a line to reveal the exact price on the Y-axis and access the option to delete the level. * Expanded capabilities for account administration and risk management for Brokers have been added. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.5.0 [#android-v250] This version includes: * **Stop Loss and Take Profit on the Price chart widget** * Introduction of Stop-Loss (SL) and Take-Profit (TP) lines on the Price chart for enhanced trading insights. * TP and SL are displayed as color-coded lines with only abbreviations visible. * Tap to view prices on the Y-axis and access deletion options. * **Full support for price alerts in the app** * Alerts can be set for specific price levels. * Alerts can be configured based on either a set price or a percentage change. * A list of configured alerts is available for each instrument. * Options to delete or adjust alerts are provided. * Triggered alerts are automatically removed from the list. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. *** ## Android v2.4.0 [#android-v240] This version includes: * **New mobile features** * Introduction of Take Profit, Stop Loss, and Trailing Stop functionalities in the Mobile app. * Support for Netting accounts in the Mobile app. * **Mobile and Web consistency** Unified colors and naming for a consistent experience across platforms. * **User experience enhancements** For order lists, the All/Spot/CFD filter is only displayed when there are both Spot and CFD orders, for improved UX clarity. * Bug fixes and improvements affecting the display and usability of the app's interface for a more seamless user experience. ## June 10, 2026 [#june-10-2026] ### New features [#new-features] #### Guest mode [#guest-mode] A new **Guest mode** lets you explore the Trading terminal without signing in. As a guest you can browse markets and market categories, follow live price streams and interactive charts, and open the **AI Assistant** widget for market analysis. A dedicated guest workspace is provided, and the [Place order](../widgets/place-order) panel opens in the advanced view by default. A **Sign in** action is always available so you can switch to a full trading session at any time. ## June 2, 2026 [#june-2-2026] ### Improvements [#improvements] #### Full account history in Trading reports [#full-account-history-in-trading-reports] You can now generate [Trading reports](../get-started/settings) for your entire account history. The previous **92-day** limit has been removed, and a new **All data** range has been added to the report period selector alongside the existing presets. #### Stop orders during closed market sessions [#stop-orders-during-closed-market-sessions] You can now place **Stop** orders while a market is closed according to its trading schedule. The order is accepted and activates automatically once the market reopens, instead of being rejected at placement. #### More accurate unrealized PnL [#more-accurate-unrealized-pnl] Unrealized PnL is now calculated using the correct order book side for each position direction, improving the accuracy of the PnL shown across your widgets. #### Limit price crossing warning [#limit-price-crossing-warning] When you place a limit order at a price that crosses the current top of book, the terminal now shows a warning, helping you avoid an unintended immediate execution. ## April 9, 2026 [#april-9-2026] ### New features [#new-features-1] #### Trading credit [#trading-credit] Your broker can now grant you **trading credit** — a promotional bonus balance you can use for trading. Credit appears as a separate **Credit Balance** alongside your own funds and becomes available for placing trades immediately upon issuance. You are notified when credit is granted or revoked. Trading credit is a trading-only bonus and cannot be withdrawn as cash, so it is excluded from your withdrawable balance. *** ### Improvements [#improvements-1] #### Fee-aware 100% allocation [#fee-aware-100-allocation] The **100%** button in the [Place order](../widgets/place-order) widget now accounts for commissions and margin requirements when allocating funds, so the calculated amount reflects what is actually available for the trade. #### Faster price updates [#faster-price-updates] The price update frequency in terminal widgets has been increased, providing more responsive market data across your workspace. ## March 18, 2026 [#march-18-2026] ### New features [#new-features-2] #### Webhook API for TradingView alerts [#webhook-api-for-tradingview-alerts] A new **Webhook API** has been added, enabling you to connect **TradingView** alerts to your trading workflow. You can generate and copy authentication tokens directly from the Trading terminal to configure webhook-based alerts in **TradingView**. *** ### Resolved issues [#resolved-issues] There have been no customer-facing issues reported in this release. ## March 3, 2026 [#march-3-2026] ### New features [#new-features-3] #### Long-term trading data history [#long-term-trading-data-history] The three-month limit on trading data history has been removed. You can now access the full history of your orders, positions, and trades without time restrictions, enabling deeper analysis of past trading activity. #### AI Assistant widget [#ai-assistant-widget] A new **AI Assistant** widget is now available in the Trading terminal. The widget provides AI-powered market analysis for the selected instrument, including: * A recommendation gauge displaying a score from **Strong Sell** to **Strong Buy** * A 12-month price forecast with target price and percentage change * A market sentiment bar showing the bullish/bearish ratio * Signal drivers section with technical, on-chain, and sentiment factors * Suggested trading actions and key market metrics The widget can be added to any workspace like other terminal widgets. *** ### Improvements [#improvements-2] #### Updated order cancellation confirmation [#updated-order-cancellation-confirmation] The order cancellation confirmation dialog now includes a **Don't ask again** checkbox when canceling triggers from the **TradingView** chart. This allows you to skip the confirmation step for future trigger cancellations, streamlining the trading workflow. *** ### Resolved issues [#resolved-issues-1] There have been no customer-facing issues reported in this release. ## February 25, 2026 [#february-25-2026] ### New features [#new-features-4] #### Redesigned Market Depth widget [#redesigned-market-depth-widget] The [Market Depth](../widgets/market-depth) widget has been completely redesigned with an updated visual layout. Bid and ask labels are now displayed when hovering over a price level, providing better visibility into the order book at a glance. #### Redesigned widget adding experience [#redesigned-widget-adding-experience] The process of adding widgets to workspaces has been redesigned with a more intuitive and streamlined flow. The new interface makes it easier to customize your trading workspace layout by providing a clearer visual selection of available widgets. #### Order and position comments [#order-and-position-comments] A new **Comment** field has been added to orders, positions, and trades throughout the Trading terminal. You can now attach notes directly to your trading activities, making it easier to annotate trading decisions and keep records of your reasoning. #### Favorites [#favorites] You can now mark instruments as favorites for quick access across the Trading terminal. The [Favorite markets](../get-started/customizing-your-terminal#favorite-markets) feature integrates with the instrument selection panel, making it faster to locate and trade your preferred instruments. #### Multi-language support [#multi-language-support] The Trading terminal now supports additional languages: **Chinese (Simplified)**, **Spanish**, **Portuguese**, **French**, **Turkish**, and **Farsi**. Existing translations have also been updated to reflect the latest interface changes. *** ### Improvements [#improvements-3] #### Updated order calculations [#updated-order-calculations] The **Value** and **Amount** calculation logic has been improved for more accurate order handling: * For **Stop Market** orders, the estimated values are now calculated using updated formulas that align with the actual execution logic. * For **Spot** market orders, the **Slippage Rate** is now correctly applied only to buy orders and has been removed from sell order calculations. * The **Slippage Rate** attribute has been removed from **CFD** and **PF** market forms and information displays, as it is not applicable to these market types. #### Improved TP/SL trigger management [#improved-tpsl-trigger-management] Removing Take Profit and Stop Loss triggers is now easier in the TradingView charting widget. Instead of opening a dialog and unchecking the trigger, you can now click the close button directly on the trigger to remove it immediately. #### Updated default columns [#updated-default-columns] The default columns displayed in the [Open positions](../widgets/open-positions) and [Open orders](../widgets/open-orders) widgets have been updated to show the most relevant information by default, reducing the need for manual customization. #### Account margin value formatting [#account-margin-value-formatting] Account margin values such as **Balance**, **Equity**, **Margin**, and **Free margin** in the [Margin](../widgets/margin) widget are now formatted according to the **Root Asset Scale**. This ensures that numerical precision matches the asset's defined scale, eliminating misleading decimal places. #### Updated Settings experience [#updated-settings-experience] The [Settings](../get-started/settings) experience has been improved: * The **Action Confirmation** section text has been rewritten for clarity. The description now reads: "Choose which actions will require additional confirmation," making the toggle behavior immediately clear. * The **One-click trading** configuration has been updated with improved toggle controls and clearer options for enabling or disabling confirmation dialogs on trading actions. #### Improved order validation [#improved-order-validation] Order validation logic has been updated across the Trading terminal, providing clearer feedback on invalid inputs and reducing errors during order placement and management. #### Workspace tab styling [#workspace-tab-styling] Visual improvements have been applied to workspace tabs: gaps have been added between tabs for better visual separation, tab padding has been corrected, and hovered tabs now display a proper card-style fill matching the updated design system. ## December 19, 2025 [#december-19-2025] ### New features [#new-features-5] #### Volume-based tiered commissions [#volume-based-tiered-commissions] You can now benefit from **volume-based commission tiers** that automatically reduce your trading fees as your monthly volume grows. **Key points**: * **Trade more, pay less**: For markets with tiered fees, your 30‑day trading volume (in the root asset, for example USD) is tracked across all markets included in the same group. As you move into higher tiers, your commission percentage decreases. * **Clear fee overview**: Open [Market info](../get-started/customizing-your-terminal#market-info-panel) and switch to the **Fees** tab to see your **Current volume** for the month, the configured **Min. fee**, and the full **Commission tiers** table with volume ranges and fee %. A check mark highlights the tier you are currently in. * **Grouped volume**: Your traded volume is aggregated across markets to which the dynamic commission is applied. * **No surprises**: Orders on markets without tiered fees continue to use the existing flat commission model. Tiered markets simply adjust your fee according to the tier that matches your current trading volume. #### New settings [#new-settings] The [Settings](../get-started/settings) menu has been enriched with the following configuration options: * **Widgets**: This updated section now provides access to multiple widgets’ display settings. Along with existing [Price chart](../widgets/price-chart), you can now configure: * One-click trading for [Open positions](../widgets/open-positions): When enabled, single and bulk position closing are executed immediately, without going through additional confirmation dialogs. * One-click trading for [Open orders](../widgets/open-orders): When enabled, single and bulk order cancellations are executed immediately, without going through additional confirmation dialogs. * **API token management**: This new section allows you to generate and manage tokens for accessing the [Trading API](https://api-docs.b2trader.b2broker.com/). Up to 10 tokens can be generated per account. The validity period for each token is one year. The tokens can be revoked or deleted anytime. *** ### Improvements [#improvements-4] #### Responsive widget layout [#responsive-widget-layout] Widget content now adapts dynamically to the available space, ensuring that key information such as primary values, titles, and critical actions remains visible even when widgets are resized or minimized. Layouts have been refined to avoid unnecessary empty areas while preventing clipping of important elements, delivering a more readable and informative experience across all widget sizes. #### Clearer margin level display [#clearer-margin-level-display] The [Margin](../widgets/margin) widget has been updated to provide a clearer signal. Now, whenever no margin is used (for example, when you have no open positions), the **used margin** value displays **–** instead of 0%. This aligns with common brokerage practices and helps you better understand the current risk state at a glance. #### Smarter default filters for Assets and Account margin [#smarter-default-filters-for-assets-and-account-margin] Certain default filters are now applied automatically when the Trading terminal is opened for the first time. In the [Assets](../widgets/assets) widget, **Hide zero balances** is enabled by default, so assets with zero balance are not shown. In the [Account margin](../get-started/settings#account-margin) settings, **Hide zero balances** and **Hide assets with zero margin ratio** are enabled by default, hiding assets that carry no margin or balance. If you change any of these filters, the platform remembers their states. #### Improved quick trade panels [#improved-quick-trade-panels] The **Market quick trade panel** has been moved not to cover the important controls of the [Price chart](../widgets/price-chart). Additionally, it now displays the **cross icon** to quickly close the panel if needed. *** ### Resolved issues [#resolved-issues-2] There have been no customer-facing issues reported in this release. ## November 7, 2025 [#november-7-2025] ### New features [#new-features-6] #### Tiered leverage system [#tiered-leverage-system] With this release, we're excited to introduce the **tiered leverage system** that provides more sophisticated leverage options based on your position sizes, offering better risk management. **Key points:** * **Dynamic leverage tiers**: Markets can now offer tiered leverage where your maximum available leverage decreases as your position size increases. This allows you to access higher leverage on smaller positions while maintaining appropriate risk controls on larger trades. * **Enhanced market information**: Markets with tiered leverage now display comprehensive leverage information in the **Market info** panel. A new **Leverage** tab shows all available tiers, including the notional value ranges and maximum leverage for each tier. * **Improved position tracking**: Your open positions now display both the leverage you selected when opening the position (**Requested leverage**) and the actual leverage being applied (**Leverage**). Detailed tooltips explain how these values are calculated, giving you better visibility into your margin usage. * **Smart leverage selection**: When placing orders on markets with tiered leverage, the system automatically calculates your margin requirements across all applicable tiers. You can see the exact margin required before placing your order. **How it works** For markets with dynamic leverage, your position is allocated across different tiers based on its notional value. Each tier has its own maximum leverage limit, typically starting with higher leverage for smaller positions and decreasing as position size grows. This allows you to maintain appropriate risk management. **Order placement** When trading on tiered markets, you can still select your preferred leverage (up to the maximum allowed for the first tier), and the system will automatically apply the appropriate leverage limits. The margin calculator shows you the exact requirements before you place your order. All existing positions continue to operate normally with no changes to your current trading experience. Markets without tiered leverage continue to work exactly as before. *** ### Improvements [#improvements-5] #### Improved documentation experience [#improved-documentation-experience] The documentation window is now fully resizable, allowing traders to adjust both vertical and horizontal dimensions independently. All screenshots can now be zoomed, making detailed interface elements clearly visible. #### Streamlined market selection [#streamlined-market-selection] The market selection control is now displayed as the **chevron icon** directly next to the market name in widgets. The magnifying glass icon has been removed. Both the market name and chevron are now clickable and open the market selector. #### Reorganized market information access [#reorganized-market-information-access] The market info popover has been relocated under the **info icon** in the widget header to maintain accessibility while keeping the market name area focused solely on selection functionality, creating a cleaner and more consistent user interface. #### Enhanced workspace tab design [#enhanced-workspace-tab-design] A clear distinction between active and inactive workspace tabs has been achieved due to intuitive styling. Workspace option buttons are now hidden by default to reduce visual clutter and only appear when tabs are active or being hovered over. This applies to both default and custom workspace tabs, creating a cleaner interface while maintaining full functionality when needed. *** ### Resolved issues [#resolved-issues-3] There have been no customer-facing issues reported in this release. ## October 9, 2025 [#october-9-2025] ### New features [#new-features-7] #### Placing orders from the Price chart [#placing-orders-from-the-price-chart] The [Price chart](../widgets/price-chart) widget now supports direct order placement with two new quick trading panels. The **Market quick trade panel** provides a persistent interface for instant buy/sell orders, while the **Limit quick trade panel** allows hover-based order placement at specific price levels. When enabled through **Price chart settings**, both panels offer configurable amount presets and leverage ratio selection for margin trading (when applicable), creating a seamless trading experience without leaving the chart view. #### Bulk order canceling [#bulk-order-canceling] The [Open orders](../widgets/open-orders) widget introduces a **Cancel all** button that closes all active orders simultaneously. This feature provides better risk management capabilities during volatile market conditions. #### In-platform documentation [#in-platform-documentation] User documentation is now integrated directly within the Trading terminal interface. This eliminates the need to switch between applications when accessing help materials or reference guides, keeping essential information readily available during trading sessions. #### New market subtype [#new-market-subtype] The new **Commodities** subtype has been added for CFD markets, enhancing the market categorization system. *** ### Improvements [#improvements-6] #### Enhanced position tracking [#enhanced-position-tracking] A new **Direction** column has been added to **Trades** info in the [Open positions](../widgets/open-positions) and [Closed positions](../widgets/closed-positions) widgets. It indicates whether a position size increased (In) or decreased (Out) as a result of each trade. This enhancement provides clearer visibility into position movement patterns. #### Cross rates calculation precision [#cross-rates-calculation-precision] Accuracy for cross-rate calculations has been improved by introducing a new cross-rate scale parameter. It has a default value of 8 and can be adjusted in configuration files. This addresses the previous limitation where cross rates were rounded to the root asset type scale (typically 2 decimal places), causing incorrect zero values in certain scenarios. The improvement ensures accurate cross-rate calculations across all currency and cryptocurrency pairs, regardless of their relative values. #### Redesigned Settings interface [#redesigned-settings-interface] The **Settings** menu has been restructured with a new tabbed popup interface. Related configuration options are now logically grouped, making settings easier to navigate and manage. #### Pre-filled Limit order price [#pre-filled-limit-order-price] Limit order placement now includes automatic price pre-population using the best bid or ask price from the order book. This static pre-fill reduces manual entry requirements and helps prevent pricing errors during order submission. #### Updated sorting of open positions [#updated-sorting-of-open-positions] [Open positions](../widgets/open-positions) are now sorted chronologically with the newest positions displayed at the top, improving visibility of recent trading activity. #### Improved messages [#improved-messages] User communications have been updated throughout the platform, including improved Introduction tour messaging for better onboarding and clearer system notifications. #### UI enhancements [#ui-enhancements] UI improvements for this release include: * **Support for dynamic resizing of the trading interface layout**: The trading interface now features a responsive layout system that dynamically adjusts to browser window resizing. Widgets automatically scale and reposition to maintain optimal viewing regardless of screen size changes. * **Loader**: [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now display loading indicators when fetching additional data. * **Improved PnL representation**: When displayed on charts, the PnL values are now accompanied by "+" or "–" signs for immediate profit/loss recognition. * **Improved scrollbars**: Scrollbar positioning has been refined to prevent overlay of table content, ensuring all data remains visible and accessible. *** ### Resolved issues [#resolved-issues-4] There have been no customer-facing issues reported in this release. ## July 2, 2025 [#july-2-2025] ### New features [#new-features-8] #### Trading reports [#trading-reports] We've implemented a new feature enabling you to generate trading reports for a specific period of time and download them as zipped CSV files to your computer. The report includes a detailed information on: * **Trade history** * Closed positions * Executed orders * Trades * **Transfers history** * **Account statistics** * Total balance * Realized PnL * Swaps * Funding * Commissions The data is available for any period within the last **92 days** (UTC time). The following timeframe presets have been implemented for your convenience: * Today * Current: week, month, quarter * Previous: week, month, quarter Access the new **Trading report** menu under the **Settings** icon on the topbar of the Trading terminal. *** ### Improvements [#improvements-7] #### Admin-managed orders and positions [#admin-managed-orders-and-positions] In the [Open positions](../widgets/open-positions), [Closed positions](../widgets/closed-positions), and [Order history](../widgets/order-history) widgets, if BP Admins have managed positions or orders, this is now indicated in the Reason field within the position or order details. Admins may manage these to assist traders upon request, address suspicious activity, and mitigate risks. *** ### Resolved issues [#resolved-issues-5] There have been no customer-facing issues reported in this release. ## May 30, 2025 [#may-30-2025] ### New features [#new-features-9] #### PF trading [#pf-trading] We are excited to introduce **Perpetual Futures (PF) trading** on our platform. These contracts feature a funding fee mechanism based on the Mark price and Funding rate. A positive rate means Long positions pay Shorts, and a negative rate means the reverse. You can see the countdown to the next funding fee settlement in the [Market summary](../widgets/market-summary) widget. This update also includes a new market type — Perpetual — enhancing your trading opportunities. *** ### Improvements [#improvements-8] #### Price chart setting [#price-chart-setting] The [Price chart](../widgets/price-chart) widget now supports displaying of open positions, as well as open and executed orders. Click the **gear icon** in the topbar to access Price chart settings and enable desired options. #### Close all positions [#close-all-positions] The [Open positions](../widgets/open-positions) widget now features a new **Close all** option, offering enhanced management capabilities. This update provides a more efficient way to handle multiple positions by allowing you to simultaneously close: * All open positions * All open positions with positive PnL * All open positions with negative PnL #### Enhanced price control [#enhanced-price-control] The following enhancements have been implemented for the [Price control](../widgets/price-control) widget: * **Editable price alerts**: You can now adjust existing price alerts by clicking a price. * **Enhanced market additions**: Price and percentage fields now automatically open for editing when a new market is added to the widget. * **Visual indicators**: Arrows near price triggers aren’t shown if the price feed is unavailable, reducing clutter and potential confusion. #### Historical data limits [#historical-data-limits] The [Order history](../widgets/order-history) and [Closed positions](../widgets/closed-positions) widgets now provide historical data with a limit of **92 days**. *** ### Resolved issues [#resolved-issues-6] There have been no customer-facing issues reported in this release. ## April 17, 2025 [#april-17-2025] ### New features [#new-features-10] #### Netting account type [#netting-account-type] With this release, a new **Netting** account type has been enabled. It intelligently consolidates all orders placed on the same market into a single position. Previously, the system supported only Hedging, where each order opens a separate position. **Key points of netting** * **Reduced margin requirements**: Instead of calculating margin requirements separately for each position, netting combines them, lowering overall capital needs. * **Lower trading costs**: By holding opposing positions, traders often incur double position swaps. Netting treats these positions as one, reducing unnecessary costs. * **Streamlined position management**: Managing multiple positions manually can become complicated, especially when balancing between different trade sizes, directions, leverages and margin requirements. Netting helps with it by combining positions into a single one. **Netting VS Hedging** Netting may sometimes lack the flexibility required for complex hedging strategies. In contrast, hedging excels by allowing traders to hold both long and short positions simultaneously without offsetting them. This enhances the ability to track and adjust individual trades easily while permitting precise margin management for separate positions. The Hedging type is perfectly suited for traders seeking detailed control over their positions. On the other hand, the Netting type ensures simplicity and reduced margin requirements, making it the perfect choice for straightforward trading strategies. **Workflow changes** When opening a new trading account, you must now choose its type: either Hedging or Netting. This choice is permanent and influences all future trades in the account. In the account selection interface, each account displays its type: `H` for Hedging or `N` for Netting. All existing accounts are automatically assigned to the Hedging type. *** ### Improvements [#improvements-9] #### Improved widget control [#improved-widget-control] With this release, you now have enhanced control over the viewing experience: * **Configuring widget columns**: Certain widgets allow you to configure widget columns in a way that best suits your needs, offering you the flexibility to select which columns you wish to display or hide. Additionally, you can arrange the order of these columns for your convenience, ensuring that the information you prioritize is always at your fingertips. * **Rearranging widget tabs**: All widgets now feature drag-and-drop functionality for rearranging tabs effortlessly. This user-friendly feature offers a more customized and organized interface, making it easier than ever to personalize your widget experience. #### Enhanced Order book [#enhanced-order-book] The Order book widget has been upgraded with new customizable settings. This update introduces intuitive controls, empowering you to adjust the widget view according to your preference: * **Full view**: Shows both buy and sell orders along with the market spread. * **Buy only view**: Displays only buy orders and the market spread. * **Sell only view**: Displays only sell orders and the market spread. *** ### Resolved issues [#resolved-issues-7] There have been no customer-facing issues reported in this release. ## January 15, 2025 [#january-15-2025] ### New features [#new-features-11] #### Take profit, Stop loss, Trailing stop [#take-profit-stop-loss-trailing-stop] With this release, the following new triggers for open positions have been implemented on the platform: * **Take profit**: A take-profit trigger is used to close a position automatically once the market hits a predefined price, ensuring the trader locks in profits. * **Stop loss**: A stop-loss order is a trigger to limit potential losses. It automatically closes a position when its price changes to a predetermined level. * **Trailing stop**: A trailing-stop order allows a trader to set a Stop price that dynamically adjusts as the market price moves. It's different from a regular stop-loss order because the Stop price isn't stationary but follows the market price by a specified value. When the asset price moves favorably, the Stop price updates, securing potential gains. However, if the price falls, the Stop price stays fixed to protect profits or limit losses. These settings can be used when trading on CFD markets and can be applied to Market, Limit, and Stop orders, as well as for currently open positions. The new settings can be enabled when placing an order via the [Place order](../widgets/place-order) widget (Advanced mode). Until a position is fully closed, they can also be adjusted or canceled via the [Open positions](../widgets/open-positions) widget. The information about applied settings is also available in the corresponding widgets: [Closed positions](../widgets/closed-positions), [Open orders](../widgets/open-orders), and [Order history](../widgets/order-history). *** ### Resolved issues [#resolved-issues-8] There have been no customer-facing issues reported in this release. *** ## Past releases [#past-releases] ### December, 2024 [#december-2024] #### New features [#new-features-12] ##### CFD trading [#cfd-trading] With this release, we're excited to announce the support for CFD (Contract for Difference) trading on our brokerage platform. This empowers you to trade with dynamic leverage, using your funds as collateral to secure positions confidently. Enjoy the flexibility to go both long and short, capitalizing on both bullish and bearish markets. Our CFD trading support boasts an intuitive interface, robust risk management tools, and real-time data. ##### Innovative market approach and instrument picker [#innovative-market-approach-and-instrument-picker] * **Market type**: Markets are now classified into Spot and CFD, reflecting their differing parameters. A panel indicating CFD or Spot is now included in all widgets. * **Market parameters and trading schedule**: Click a market name to access its key parameters and scheduled trading sessions. * **Market categories**: Now accessible via the top bar, offering a hierarchical view for easier selection and switching between markets. ##### Account margin settings [#account-margin-settings] Access the new [Account margin settings](../get-started/settings) to monitor your balances and configure assets to be used as collateral for CFD trading. ##### Reworked Place order widget [#reworked-place-order-widget] Place any order with a [single widget](../widgets/place-order) now. Choose Quick IOC Market or Stop with adjusted leverage — all conveniently in one place, along with an order summary. ##### Positions [#positions] Discover two new widgets for position monitoring: * [Open positions](../widgets/open-positions): Offers real-time monitoring of currently open positions with price changes, PnL, used margin, and other parameters. * [Closed positions](../widgets/closed-positions): Provides historical data on position details, prices, and realized PnL. ##### Risk management [#risk-management] You now have three essential widgets to maintain control: * [Margin](../widgets/margin): Monitor your margin account parameters in real time and respond swiftly to changes. * [Price control](../widgets/price-control): Set price alerts tailored to your specific needs and parameters. * [Messages](../widgets/messages): Receive system notifications and price alerts directly. ##### Market data [#market-data] Two new widgets have been introduced to enhance market monitoring: * [Market summary](../widgets/market-summary): Provides detailed information and updates on price changes for a specific market. * [All markets](../widgets/all-markets): Displays price change statistics across all markets simultaneously. #### Improvements [#improvements-10] * Performance has increased significantly, allowing each trader to hold up to 1,000 CFD positions open. * Limits have been increased to 3,000 requests per second. #### Resolved issues [#resolved-issues-9] There have been no customer-facing issues reported in this release. *** ### June 20, 2024 [#june-20-2024] #### Improvements [#improvements-11] * Account selection is now available from the topbar of the Trading terminal. Once you change your account, all the widgets will automatically adjust to show relevant information for the selected account. * Tabs are now available in the Trading terminal. You can place up to 10 tabs to open multiple workspaces simultaneously for better information organization. You can utilize pre-configured layouts for your workspaces or create custom ones. *** ### June 13, 2024 [#june-13-2024] #### New features [#new-features-13] ##### iOS mobile application [#ios-mobile-application] With this release, our team is thrilled to announce the launch of the brand-new iOS mobile app. The mobile app is closely integrated with B2CORE mobile. Along with single sign-on implemented, it allows you to seamlessly navigate between the apps, without re-entering credentials. In the mobile app, just like in the web version of the Trading terminal, you can access all of your BP accounts, place orders, monitor market data, and so on. For your convenience, it all can be done in a very similar way as in the web version. A consistent and user-friendly interface makes using the app easy and intuitive. Among the key features and services that the new BP mobile offers: * The account list with detailed balances, to always keep your funds under control. Creation and renaming of accounts, to keep your funds well organized. * Asset balances screen, with the amounts of free and frozen funds specified and with the possibility to hide assets with zero balances. * The Order book and price chart, to monitor and analyze trading data and make buy or sell decisions, with a quick and easy jump to the order placing screen. * Candles and line charts, with easy switching and the possibility to scroll the data for historical values. * Limit & Market order placing, with all time in force options supported in the Web version (Market: IOC, FOK; Limit: IOC, FOK, GTC, GTD, Day). * Open and history orders lists, with easy access to order parameters and details, quick canceling or repeating an order. * Light and dark themes and many more. ### October 18, 2023 [#october-18-2023] #### New features [#new-features-14] With this initial release, our team is happy to announce the launch of our new Trading terminal. ##### Placing orders [#placing-orders] The platform currently supports placing Market, Limit, Stop Market, and Stop Limit orders (refer to [Order types](../knowledge-base/order-types)). You can also choose from various [Time in force](../knowledge-base/time-in-force) options such as FOK, IOC, GTC, GTD, and DAY. ##### Widgets [#widgets] The platform provides you with enhanced widgets that are specifically designed for convenient trading. These widgets allow you to easily place orders, access the Order book, monitor open orders and order history, and much more. Refer to [Place order](../widgets/place-order) and the other pages of the Widgets section for more information. ##### Dashboard [#dashboard] The customizable dashboard allows you to personalize the layout to suit your needs and keep you focused on what's important. Refer to [Interface overview](../get-started/customizing-your-terminal) to learn more about workspace customization. ## Summary [#summary] This widget provides AI-powered market analysis and trading recommendations for the selected market. AI Assistant The widget is organized into the following sections: * [AI Recommendation](#ai-recommendation): Overall recommendation score. * [Forecast](#forecast): Price target and market sentiment. * [Signal Drivers](#signal-drivers): Technical, on-chain, and sentiment signals. * [Suggested Actions](#suggested-actions): AI-generated trading suggestions. * [Key Metrics](#key-metrics): Market data overview. ## AI Recommendation [#ai-recommendation] Displays a numeric score from 0 to 100 representing the overall AI assessment of the market, along with a label such as **Strong Buy**, **Buy**, **Neutral**, **Sell**, or **Strong Sell**. A higher score indicates a more favorable outlook. ## Forecast [#forecast] **1Y Price Target** The forecasted price in one year and the expected percentage change from the current price. *** **Market Sentiment** A visual bar showing the ratio between bullish and bearish sentiment among market participants. ## Signal Drivers [#signal-drivers] Signals that influence the AI recommendation, categorized into three types: * **Technical**: Signals based on technical analysis indicators such as RSI and Moving Averages. * **On-Chain**: Signals based on blockchain data such as ETF inflows, active addresses, and total value locked (TVL). * **Sentiment**: Signals based on community and analyst opinions. Each signal includes a description and an impact assessment: **Bullish**, **Bearish**, or **Neutral**. ## Suggested Actions [#suggested-actions] A list of AI-generated trading suggestions based on the current market conditions. These are informational recommendations, not automated trading signals. ## Key Metrics [#key-metrics] The following market data is displayed: **All-Time High** The highest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **All-Time Low** The lowest price ever recorded for the asset (in USD) and the percentage difference from the current price. *** **24h Volume** The total trading volume over the last 24 hours in USD. *** **Market Cap** The total market capitalization of the asset in USD. AI-generated insights are for informational purposes only. The AI Assistant widget can be enabled or disabled by the platform administrator. If the widget isn't available in the **Add Widget** menu, contact your broker. ## Summary [#summary] Use this widget to monitor price data on all markets available on the platform. The widget is dynamic and is continuously updated in real time. All markets ## Fields [#fields] The following information is provided about each market: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current market price, in the quote asset and in the platform root asset. This value is green if the price is rising and red if it's falling. *** **24h change** The price change over the last 24 hours, in absolute and percentage values. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. ## Summary [#summary] This widget displays the list of all asset balances on your account. Assets ## Settings [#settings] ### Hide zero balances [#hide-zero-balances] Use this option to hide all assets with zero balances from the list. It's enabled by default. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each asset: **Asset** The alphabetical code of the asset. The first asset in the list is the **root asset** of the platform. *** **Caption** The asset name. *** **Available** The balance at your disposal, meaning the difference between your total assets and a sum of all limit orders placed by this time. This value is calculated as *Total – Halted*, where *Halted* is the asset amount frozen on the account for execution of placed Limit orders. *** **Available, \{RAT}** The available balance, in conversion to the platform root asset. *** **Total** The overall amount of the asset available in your wallet, including locked funds. *** **Total, \{RAT}** The total balance, in conversion to the platform root asset. ## Summary [#summary] This widget displays a list of your closed positions on the selected account. The entire history of your closed positions is available. Closed positions The widget lists only closed positions. For a list of currently open positions, use the [Open positions](open-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists closed positions for the last three months. To display positions closed during a specific time period, use the **Select date range** field. The most recently closed positions appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related orders [#view-related-orders] Click the **chevron icon** in a position row to expand a list of position-closing orders. As positions can be partially closed, there may be more than one line. For each executed position-closing order, a separate line is added. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Pos. closed size** The closed volume, in lots, which is equivalent to the corresponding filled order volume. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Close price** The volume-weighted average price (VWAP) of trades related to a position-closing order. *** **Close order ID** The identifier of an order closing the position. *** **Realized PnL, \{RAT}** The actual profit or loss earned, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Close price* – *Open price*). For **Short** positions, this value is calculated as *Position size* × (*Open price* – *Close price*). *** **\{RAT} notional** The equivalent of the closed volume in the platform root asset. *** **History rate to \{RAT}** The rate to the platform root asset at the moment of position closing. *** **Reason** The reason for closing a position. Possible values: * **Trader**: The position was closed by you. * **Admin**: The position was closed by an Admin. * **Stop-out**: The position was automatically closed by the system, as a result of Stop out. * **Stop loss**: The position was closed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The position was closed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The position was closed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. *** **Open date, time** The date and time when a position was opened. *** **Closed date, time** The date and time when a position-closing order was last updated (fully executed). ## Summary [#summary] This widget helps you monitor margin parameters and statistics. Margin ## Fields [#fields] All values are in displayed in conversion to the platform root asset: **Your margin level** The ratio of your funds to a used collateral, in percents. This value is calculated as *Equity* / *Used margin* × 100%. Possible values: * **Empty**: No open positions. * **Low risk**: Everything is ok. * **Margin call**: Your margin level fell below the set Margin call value. You received a notification urging you to increase the margin level to avoid a Stop out. Remember that if you ignore this warning, the margin level may continue to decrease. During the Margin call, you can only close existing positions; opening new positions isn’t possible. * **Stop out level**: Your margin level fell below the set Stop out value; the platform started a process of liquidating your positions. This process continues until the margin level exceeds this required value. **ANY** currently open position can be closed regardless of its side and volume. *** **Margin balance** The total amount of your funds that can be used as a collateral for CFD trading. It’s calculated as Σ(*TotalAmountX* × *MarginRatioX* × *Rate X/RAT*), where: * *TotalAmountX* is the the total amount of the asset X, including both available and locked funds. * *MarginRatioX* is the Margin ratio set for the asset X. * *Rate X/RAT* is the constantly updated rate of the asset X to the platform root asset. The Margin balance is continually recalculated based on price fluctuations. An increase in the prices of assets boosts available Balance & Free margin. Conversely, a decrease in asset prices may reduce the available Balance and Free margin. Additionally, a decline in the prices of assets with open positions may trigger Margin calls and Stop outs. *** **Credit** A promotional bonus granted by your broker for margin (CFD and Perpetual) trading, shown in the platform root asset (RAT). When you have no credit, this row shows 0. Credit increases your Equity and Free margin and can be used as collateral to open positions. It becomes available immediately when granted and never expires. However, credit cannot be withdrawn as cash, so it is excluded from your withdrawable balance. Your broker can revoke credit at any time, and the row updates in real time when this happens. The row includes an info tooltip that reads: *Promotional credit for margin trading only. Cannot be withdrawn.* *** **Equity** The potential balance of your account if all your positions were closed right now. This value is calculated as *Margin balance* + *Credit* + *Unrealized PnL*. *** **Used margin** The amount of funds that is used for maintaining all your open positions. Is opposed to the *Free margin*. The Used margin for positions on a specific market is calculated using the maximum value between the total margin of long positions and the total margin of short positions: MAX(*MarketPositionLong*, *MarketPositionShort*). **Example** **Step 1: Initial balance** * Margin balance: $10,000 * Opened positions: 0 * Free margin: $10,000 * Used margin: $0 **Step 2: Open a long position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 100 = $1,001 * After opening: * Free margin: $8,999 * Used margin: $1,001 **Step 3: Open a long position (Leverage 1:20)** * Market: CFD EUR/USD * Position size: 1 lot (100,000 units) * Current price: $1.001 * Required margin: $(100,000 × 1.001) / 20 = $5,005 * After opening: * Free margin: $3,994 * Used margin: $6,006 **Step 4: Open a short position (Leverage 1:100)** * Market: CFD EUR/USD * Position size: 9 lots (900,000 units) * Current price: $1 * Required margin: $(900,000 × 1.001) / 100 = $9,009. The system verifies that upon opening this position, the MarketUsedMargin remains valid by satisfying the condition: **MarketUsedMargin** = MAX(*MarketPositionLong*, *MarketPositionShort*) = MAX(6,006, 9,009) = 9,009. Since the condition is met, the position opens. * After opening: * Free margin: $991 * Used margin: $9,009 As a result, you can open multiple opposite positions without significantly increasing the Used margin. Furthermore, closing positions never increases the Used margin. *** **Free margin** The amount of funds that can be used for opening new positions. *** **Unrealized PnL** The total potential profit or loss earned from all open positions. This value is calculated as *Σ(Unrealized PnL for Long positions + Unrealized PnL for Short positions)*, where: * *Unrealized PnL for Long positions* = *Position size* × (*Current price* – *Open price*) * *Unrealized PnL for Short positions* = *Position size* × (*Open price* – *Current price*) ## Summary [#summary] Use this widget to assess the current market depth indicating the actual liquidity of an asset, which is evaluated based on the number of currently open orders to buy and sell it as well asset prices and volumes at various price levels. Market depth The widget is dynamic and is continuously updated in real time. The widget displays a chart indicating the overall volume of buy (green) and sell (red) orders at various price levels awaiting execution at the moment. You can hover the mouse pointer over the chart to learn the exact price and volume of an asset traded at a specific price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ## Summary [#summary] Use this widget to monitor statistics on a specific instrument. The widget is dynamic and is continuously updated in real time. Market summary To monitor multiple instruments at a time, use the [Watch list](watch-list) widget. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the first column. To change the market, click the market symbol and select a different one from the list. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual), market ticker and full name of the market. *** **Current price** The current top-of-the-book price, in the quote asset. *** **Current price, \{RAT}** The current top-of-the-book price, in conversion to the platform root asset. *** **24h change** The price change over the last 24 hours. This value is calculated as *Current price* – *Price 24h ago*. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h high** The highest trade price over the last 24 hours. This value is always green. *** **24h low** The lowest trade price over the last 24 hours. This value is always red. *** **Info icon** Click this icon to view market details and trading sessions schedule. ## Summary [#summary] This widget displays a list of received notifications, both system and configured via the [Price control](price-control) widget. Messages ## Settings [#settings] ### Mark as read [#mark-as-read] Unread alerts are marked with a red dot in the list: * Click the dot to mark the notification as read. * Click **Mark all as read** to mark all new notifications as read at once. * Click the **three dots** icon in the upper right corner of the widget to access the **Hide read notifications option**. The counter of unread alerts is also displayed on the **bell icon** in the topbar. ## Summary [#summary] This widget displays a list of Limit orders that have been placed from this specific account and are currently open and assigned one of the following [statuses](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. Open orders The widget lists only open orders, that are currently not filled or partially filled. For a list of orders in the final statuses, use the [Order history](order-history) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders for all the time. To display orders for a specific time period, use the **Select date range** field. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled so far. *** **Fee** The total commission paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that hasn’t yet been filled. *** **Limit price** For Limit orders, the Limit price set when placing the order. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set. *** **Used leverage** For margin trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Started*, *Pending*, or *Working*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Valid until** The date and time when an order expires. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Admin**: The order was placed by an Admin. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Cancel orders [#cancel-orders] To cancel an order, click the **×** in the corresponding row. To cancel all active orders at once, click the **Cancel all** button in the widget header. ## Summary [#summary] This widget displays a list of your positions currently open on the selected account. Open positions The widget lists only open positions. For a list of closed positions, use the [Closed positions](closed-positions) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists open positions for all the time. To display positions opened during a specific time period, use the **Select date range** field. The most recent position appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ### View related trades [#view-related-trades] Click the **chevron icon** in a position row to expand a list of related trades. ### Close positions [#close-positions] To close a position, hover over it and click the **CLOSE** button that appears. To close all/multiple positions at once, click **Close all** and select the desired option: close all positions or close positions with positive/negative PnL. ## Fields [#fields] The following information is provided about each position: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Position ID** The position identifier. *** **Side** The position side: Buy or Sell. *** **Position size** The current position volume, in lots. *** **Open price** The volume-weighted average price (VWAP) at which the position was opened. *** **Current price** The current market price of the base asset: bid for Long positions and ask for Short positions. *** **Stop loss** The [Stop loss](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Take profit** The [Take profit](../knowledge-base/price-triggers) value, if set when placing the order. If the value wasn't set, you can use the **Add** button to configure it. *** **Unrealized PnL, DAY, \{RAT}** The potential profit or loss earned for a current day, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *First bid price for today*). For **Short** positions, this value is calculated as *Position size* × (*First ask price for today* – *Current ask price*). If a position was opened today, then the *Open VWAP* is used instead of the *First price for today*. *** **Unrealized PnL, DAY, %** The potential profit or loss earned for a current day, in percents. *** **Unrealized PnL, Total, \{RAT}** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset. For **Long** positions, this value is calculated as *Position size* × (*Current bid price* – *Open VWAP*). For **Short** positions, this value is calculated as *Position size* × (*Open VWAP* – *Current ask price*). *** **Unrealized PnL, Total, %** The potential profit or loss earned for the entire period from the moment the position was opened, in conversion to the platform root asset, in percents. *** **Used margin, \{RAT}** The amount of your funds used for maintaining a position, in conversion to the platform root asset. *** **Leverage** The actual leverage ratio used for opening a position. *** **Req. leverage** The leverage ratio you requested when opening a position. *** **\{RAT} notional** The current position size equivalent in the platform root asset. *** **Rate to \{RAT}** The current exchange rate of a quote asset to the platform root asset. *** **Open date, time** The date and time when a position was opened. *** **Updated date, time** The date and time of the latest position-related trade. *** **Reason** The reason for opening a position: * **Trader**: The position was opened by you. * **Admin**: The position was opened by an Admin. * **Webhook alert**: The position was opened via a [TradingView webhook](../get-started/settings#tradingview-webhooks). *** **Comment** The text note inherited from the opening order. Up to 100 characters. The comment can't be edited after the order is placed. ## Summary [#summary] This widget displays a list of currently open buy and sell limit orders for a selected asset along with the current bid-ask spread. Order book The widget is dynamic and is continuously updated in real time. It provides three different sections displaying the following information: * Open sell orders are highlighted in red and listed in the top section. The best ask, which is the sell order with the lowest price, is displayed at the bottom of this list. * Open buy orders are highlighted in green and listed in the bottom section. The best bid, which is the buy order with the highest price, is displayed at the top of this list. * The middle section displays the current bid-ask spread indicating the gap between the best ask and bid prices declared for an asset. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Display only asks/bids [#display-only-asksbids] In the upper part of the widget, you can choose how to display the Order book: * Full view. * Buy orders only + spread. * Sell orders only + spread. ## Fields [#fields] Each row of the Order book provides the following information about a selected market: **Price, \{QUOTE}** The price, in the quote asset. *** **Amount, \{BASE}** The total amount of the base asset available at a corresponding price level. *** **Total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. In addition, you can use the [Market depth](market-depth) widget to evaluate the liquidity of a specific asset based on the overall volume of orders traded at various price levels. For Spot markets, hover over Order book rows to view additional information and buy or sell assets in click: **Average price** The average price, in the quote asset. *** **Total volume** The total amount of the base asset available at a corresponding price level. *** **Grand total** The total amount, in the quote asset, required to fully execute the orders at a corresponding price level. *** **Buy** / **Sell** Click the button to instantly place a Market order to buy or sell the asset at the selected price level. ## Summary [#summary] This widget provides up-to-date information about the orders executed on a selected market partially or in full, as well as the orders that were canceled, rejected, and expired. The entire order history of your account is available. Order history The widget lists only the orders to which final statuses are assigned. For a list of orders that are still being executed, use the [Open orders](open-orders) widget. ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the orders with the *Completed* status for the last three months. To display orders for a specific time period, use the **Select date range** field. To display orders with specific statuses, select one or more from the dropdown above the list. The most recent order appears at the top of the list. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types). *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Filled** The order amount that has been filled. *** **Fee** The total commissions paid for executing an order and the currency in which the commission was paid. *** **Remaining** The order amount that wasn't filled. *** **Avg execution price** The order execution price, as an average price of all trades executed while filling the order. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Status** The current order [status](../knowledge-base/order-statuses): *Completed*, *Cancelled*, *Rejected*, or *Expired*. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Order ID** The system identifier of an order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Reason** The reason for placing the order: * **Trader**: The order was placed by you. * **Stop-out**: The order was placed by the system, to close positions as a result of Stop out. * **Stop loss**: The order was placed by the [Stop loss](../knowledge-base/price-triggers) trigger. * **Take profit**: The order was placed by the [Take profit](../knowledge-base/price-triggers) trigger. * **Webhook alert**: The order was placed via a [TradingView webhook](../get-started/settings#tradingview-webhooks). ## Summary [#summary] Use this widget to place new orders. Place order The widget has two states: ### The PRO toggle is disabled [#the-pro-toggle-is-disabled] In this state, you can quickly place **IOC Market** and **GTC Limit** orders by selecting the order side (Buy/Sell) and type (Market/Limit), and specifying the order size (in lots) and price (for Limit orders). You can also place orders on CFD markets with the maximum leverage automatically applied. ### The PRO toggle is enabled [#the-pro-toggle-is-enabled] In this state, you get access to more precise order settings, such as: * **Stop orders** * **Time in force** * **Leverage** * **Take profit, Stop loss, Trailing stop** * **Comment** * **Complete order information** The **Comment** field allows you to attach a text note to the order (up to 100 characters). The comment is inherited by the resulting position and can't be edited after the order is placed. ## Settings [#settings] ### Select a market [#select-a-market] The market on which the order will be placed is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Place an order [#place-an-order] To place an order, fill in the parameters, review order details and preliminary calculated values, and then confirm the order by clicking the **Place** button. For a Limit order whose price crosses the current top-of-book — Buy at or above the best ask, or Sell at or below the best bid — the platform shows a confirmation dialog before submission. The dialog shows the entered price and the current best bid/ask, and lets you confirm or cancel the order. This warning is enabled by default; you can disable it from the dialog (**Do not show this warning again**) or from the **Limit order cross-TOB warning** toggle in [Settings](../get-started/settings#action-confirmation). ### Set price triggers [#set-price-triggers] If using **Take profit, Stop loss, Trailing stop**, set the prices in consideration of the current highest market bid/ask or a specified Limit price: These values can be adjusted any time until the position is fully closed via the [Open positions](open-positions) widget. You can't place orders during non-trading hours, according to the trading calendar schedule. The order controls are disabled when the selected account is Halted or Frozen. For more information, see [Account status](../get-started/customizing-your-terminal#account-status). You will not be able to place an order if the execution of the order causes your margin level to fall below the *Margin call* level. The same conditions apply to withdrawal operations. ## Summary [#summary] This widget displays a price chart showing fluctuation of prices for a selected market over a certain time period. Price chart The horizontal axis (X-axis) represents the time scale, and the vertical axis (Y-axis) indicates the price level. ## Settings [#settings] ### Select a market [#select-a-market] The current market is displayed in the widget header. To change the market, click the market symbol and select a different one from the list. ### Customization [#customization] Multiple customization options are provided, allowing you to configure the chart according to your preferences. You can switch between bar, candle, Heikin Ashi, line, area and baseline views, as well as specify the time period for which data should be displayed. The chart supports numerous financial indicators, such as moving averages and regressions, and can feature a variety of custom shapes, including arrows and lines, pitchforks, and various ranges, allowing you to perform an in-depth market analysis. ### Display options [#display-options] The widget supports displaying of open positions, price triggers, open and executed orders. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart) to enable desired options. ## Placing orders [#placing-orders] ### Enable placing orders [#enable-placing-orders] To enable placing orders directly from the Price chart, you need to activate the corresponding settings: 1. Click the **gear icon** in the topbar and access [Price chart settings](../get-started/settings#price-chart). 2. Activate the **Market quick trade panel** or **Limit quick trade panel** toggle, or both. 3. If needed, adjust the amount presets. These amounts will be available for quick selection when placing an order. ### Market quick trade panel [#market-quick-trade-panel] If the corresponding setting is activated, the draggable **Market quick trade panel** is constantly displayed on the Price chart. ### Limit quick trade panel [#limit-quick-trade-panel] If the corresponding setting is activated, the **+** will appear when hovering over price levels on the chart. Clicking it will open the **Limit quick trade panel**: * in the upper half of the chart — to sell; * in the lower half of the chart — to buy. ### Place a new order [#place-a-new-order] To place a new Market or Limit order from the Price chart, when a corresponding panel is displayed: 1. Select the **amount** from configured presets. 2. Select a **leverage** ratio, if trading on CFD or PF markets. 3. Click **Buy** or **Sell**. The order will be placed according to the selected type. ## Summary [#summary] Use this widget to configure alerts that will be delivered to the [Messages](messages) widget when an instrument price reaches the specified level. Price control ## Settings [#settings] ### Configure a new alert [#configure-a-new-alert] To configure a new alert: 1. Click the **Add market** button to select a required market from the list. 2. Click the **+** icon below the instrument name to add a new alert trigger. 3. In the displayed fields, specify the exact price or the price change in percents (positive or negative). The other value will be calculated automatically. 4. Click the **check mark icon** to add the trigger. Now you will receive a notification in the [Messages](messages) widget, once the instrument price hits the specified level. You can configure multiple triggers for each instrument. ### Edit alerts [#edit-alerts] Click the price to edit the existing alert. ### Remove alerts [#remove-alerts] Click the **×** button on the trigger panel to remove it and stop receiving corresponding notifications. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ## Summary [#summary] This widget displays a list of untriggered Stop orders created on the selected account. Once a market price reaches your predetermined Stop price, the Stop order is activated and submitted as either a Market or Limit order. It's then removed from this widget. You can now find it in either the [Open orders](open-orders) or [Order history](order-history) widget, depending on its current status. Stop orders ## Settings [#settings] ### Adjust the time period [#adjust-the-time-period] By default, the widget lists the Stop Market and Stop Limit orders for all the time. The most recent order appears at the top of the list. To display orders for a specific time period, use the **Select date range** field. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each order: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Side** The order side: Buy or Sell. *** **Order type** The [order type](../knowledge-base/order-types): Stop Market or Stop Limit. *** **Time in force** The [Time in force](../knowledge-base/time-in-force). *** **Amount** The order amount, in the base currency. *** **Stop price** The stop price specified when creating an order. When the market reaches this price, the Stop order will be placed (as a Market or Limit order. *** **Limit price** The price of a Limit order that will be placed when the Stop price is triggered. *** **Used leverage** For CFD trading, the leverage ratio used when placing an order. *** **Created at** The date and time when an order was placed. *** **Updated at** The date and time of the latest update to the order. *** **Comment** The text note attached to the order when it was placed. Up to 100 characters. The comment can't be edited after the order is placed. *** **Order ID** The system identifier of an order. ## Summary [#summary] Use this widget to monitor statistics on multiple instruments at a time. The widget is dynamic and is continuously updated in real time. Watch list ## Settings [#settings] ### Add/remove instruments [#addremove-instruments] Click the **Add market** button to select a required market from the list. Click the **×** button in the instrument row to remove it from the list and stop monitoring. ### Configure columns [#configure-columns] Click the **Configure columns** button in the widget header to adjust the displayed information: * **Mark or unmark column checkboxes**: To display or hide them; the column checkboxes highlighted in grey can’t be unmarked. * **Drag and drop the columns**: To adjust their order in the table. ## Fields [#fields] The following information is provided about each instrument: **Market** The market type (Spot, CFD, or Perpetual) and market ticker. *** **Full name** The market full name or description. *** **Last price** The price of the last trade. *** **24h change, %** The price change over the last 24 hours, in percents. This value is calculated as ((*Current price* – *Price 24h ago*) / *Current price*) × 100. This value is green if the price is rising and red if it's falling. A dash in this field means that there is no *Price 24h ago* data available. *** **24h low** The lowest trade price over the last 24 hours. *** **24h high** The highest trade price over the last 24 hours.