NAV
javascript python

FIX API

Introduction

FIX is a robust, reliable, and time-proven way for market participants to exchange requests to buy/sell certain assets, market data streaming, control settlement process, and many other things.

For more information and supporting materials on the FIX protocol, please refer to the FPL website, http://www.fixprotocol.org

XTRD uses a slightly modified specification of FIX 4.4 in order to facilitate both market data streaming and trading activities. Below are the links on ready-to-use dictionaries for popular FIX engines:

XTRD provides two types of sessions - trading and market data with their own set of messages. Each session requires authentication, and, depending on the configuration might enforce SSL usage.

We offer a demo environment that can be used during the integration stage and code samples for several FIX engines and programming languages: https://bitbucket.org/xtrd/xtrd_demos/src/master/

Maintenance

Our goal is to provide the best possible service to our customers and it's impossible without constant changes and improvements on our end.

In order to create predictability, we chose a small ten minutes window that should be enough for us to deploy new changes and install security patches.

Both market data and trading sessions are subject to scheduled restarts and might not be available for up to 10 minutes each day.

Below are the maintenance schedules for all current locations:

Datacenter Start time End time
LD4 07:00 UTC 07:10 UTC
NY4 08:00 UTC 08:10 UTC
TY8 09:00 UTC 09:10 UTC

Market Data Session

Market Data session uses to transmit books updates from the XTRD servers back to the client.

In order to optimize bandwidth, books updates are delivered in a form of incremental changes between books states.

The correct workflow includes receiving the initial book(s) state followed by applying incoming changes. These changes are self-explanatory:

Workflow

Messages Structure

The Feed server is using a slightly modified FIX 4.4. specification(see Market Data Incremental Refresh).

Example:

Field Name Example
BeginString 8=FIX.4.4
BodyLength 9=502
MsgType 35=A
SenderCompID 49=COMPANY_NAME
TargetCompID 56=XTR-MD-1
MsgSeqNum 34=1000123
SendingTime 52=2018-08-02T03:30:30.658
Tag Field Name Required Comments
8 BeginString Y Identifies the beginning of the message and represents the Transmission Protocol version.
Supported values:
  • FIX.4.4
9 BodyLength Y Message length (number of bytes) forward to the CheckSum tag.
35 MsgType Y Defines message type e.g. Logon(A)
49 SenderCompID Y Assigned value used to identify sender of a message
56 TargetCompID Y Assigned value used to identify receiving firm
Supported values:
  • XTRD-MD-1
34 MsgSeqNum Y Integer message sequence number
52 SendingTime Y Time of message transmission (always expressed in UTC (Universal Time Coordinated, also known as "GMT")

Example:

Field Name Example
CheckSum 10=250
Tag Field Name Required Comments
10 CheckSum Y Three bytes, simple checksum

Messages

Logon

Example:

Field Name Example
EncryptMethod 89=0
HeartBtInt 108=5
ResetSeqNumFlag 141=Y
Username 553=account_1
Password 554=StR0nG_P

MsgType: A

Direction: IN/OUT

Description: Logon should be sent as a very first message to establish FIX session and pass authentication process. In the case of successful authentication, server will respond with corresponding Logon message.

Tag Field Name Required Comments
98 EncryptMethod Y Supported Values:
  • 0 - None
108 HeartBtInt Y 108=5
141 ResetSeqNumFlag N Indicates both sides of a FIX session should reset sequence numbers
553 Username Y Session Username
Required for Outgoing message
554 Password Y Session Password
Required for Outgoing message

Logout

Example:

Field Name Example
Text 58=Incorrect Username or Password

MsgType: 5

Direction: IN/OUT

Description: Logout message is used as a confirmation.

Tag Field Name Required Comments
58 Text N Disconnection reason in human-readable format
Please note, that this field might be absent

SecurityListRequest

Example:

FieldName Example
SecurityReqID 320=REQ_1
SecurityListRequestType 559=0
SecurityExchange 207=HUOBI

MsgType: x

Direction: OUT

Description: this message is used to receive a list of all tradable instruments on a particular exchange.

Tag FieldName Required Comments
320 SecurityReqID Y Unique request ID
559 SecurityListRequestType Y Type of request being performed by a counterparty.
Supported values:
  • 4 - All Securities
207 SecurityExchange Y Exchange name to extract a list of all instruments

SecurityList

Example:

FieldName Example
SecurityReqID 320=REQ_1
SecurityResponseID
SecurityRequestResult 560=0
TotNoRelatedSym 393=51
LastFragment 893=false
Text 58=Exchange ABC not found
NoRelatedSym 146=1
Symbol 55=ETH
/BTC
SecurityExchange 207=HUO
BI
Price Precision 5001=8
Size Precision 5002=4

MsgType: y

Direction: IN

Description: this message is used to return a list of Securities that matched criteria, specified in SecurityListRequest. Taking into account, that such lists could be big enough, all instruments will be streamed one by one(one instrument per SecurityList message).

Combination of TotNoRelatedSym(393) and LastFragment(893) tags can be used to identify the end of a transmission.

Tag FieldName Required Comments
320 SecurityReqID Y ID from the initiating SecurityListRequest
322 SecurityResponseID Y
560 SecurityRequestResult Y Supported Values:
  • 0 - Valid request
  • 1 - Invalid or unsupported request
  • 2 - No instruments found those match selection criteria
  • 3 - Not authorized to retrieve instruments data
393 TotNoRelatedSym N This field contains information about a number of instruments that matched initial
search criteria.
893 LastFragment N Boolean field that indicates is given message is last in particular transmission or not
58 Text C Optional field that will held human-readable information about the error(if occurred)
146 NoRelatedSym C In case of successful request - always 1
55 Symbol C
207 SecurityExchange C
5001 Price Precision C Integer value that represents a number of decimal points in prices for given Symbol/Exchange
5002 Size Precision C Integer value that represents a number of deciman points in size for given Symbol/Exchange

MarketDataRequest

Example:

Field Name Example
MDReqID 262=1001_1
SubscriptionRequestType 263=1
MarketDepth 264=0
MDUpdateType 265=1
NoMDEntryTypes 267=1
MDEntryType 269=0
NoRelatedSym 141=1
Symbol 55=ETH/BTC
SecurityExchange 207=HUOBI

MsgType: V

Direction: OUT

Description: given command used to initiate subscription on real-time market data for symbol(s) on the particular exchange(s). In case of a successful request, the server will respond with a book’s snapshot followed by incremental updates for this book.

Server provides flexibility to choose between a quantity of information being transmitted by configuring MarketDepth. Caller might choose to receive a full book(sometimes a way big) by specifying setting zero to tag 264 or use a custom quantity such as 5(5 BIDSs and 5 ASKs).

MDEntryTypes should always contain two types – BID(0) and OFFER(1).

Caller might subscribe on several instruments from several exchanges using single MarketDataRequest message.

Please note, that subscription request will be processed using “all or nothing” principles. This means that for complex requests that contain at least one error in subscription, the whole message will be rejected.

Tag Field Name Required Comments
262 MDReqID Y Unique ID
263 SubscriptionRequestType Y Supported Values:
  • 1 - Snapshot plus Updates
  • 2 - disable previous Snapshot plus Updates request
264 MarketDepth Y The field used to specify the number of bids/asks to receive.
Supported Values:
  • 0 - Full book
265 MDUpdateType Y Supported values:
  • 1 - Incremental updates
267 NoMDEntryTypes Y You can choose one or several values
269 MDEntryType Y Supported Values:
  • 0 - BID
  • 1 - OFFER
  • 2 - TRADE
146 NoRelatedSym Y It is possible to subscribe to several symbols using a single MarketDataRequest
message
55 Symbol Y Symbol name
207 SecurityExchange Y Name of the exchange to receive market data

MarketDataRequestReject

Example:

Field Name Example
MDReqID 262=100_112
MDReqRejReason 281=0
Text 58=ABC/TEST

MsgType: Y

Direction: IN

Description: in case of logically incorrect MarketDataRequest message, subscription for the particular symbol will be rejected and server will provide additional information about the cause.

If initial MarketDataRequest messages contained several instruments that caused errors, then the server will respond with the only one MarketDataRequestReject messages under the same MDReqID and contains a description of the first error.

Tag Field Name Required Comments
262 MDReqID Y Unique MDReqID provided in MarketDataRequest message that has been failed.
281 MDReqRejReason Y
  • 0 - Unknown symbol
  • 1 - Duplicated MDReqID
  • 3 - Insufficient Permissions
  • E - Unknown SecurityExchange
58 Text Y Error description in a human-readable format

MarketDataSnapshotFullRefresh

Example:

Field Name Example
MDReqID 262=100_1
Symbol 55=ETH/BTC
SecurityExchange 207=HUOBI
RptSeq 83=2685
NoMDEntries 268=1
MDEntryType  269=0
MDEntryPx 270=0.035089
MDEntrySize 271=3.014
MDEntryDate 272=20180601
MDEntryTime 273=03:30:30.657145

MsgType: W

Direction: IN

Description: this message contains book snapshot for the particular instrument. A number of levels could be controlled by MarketDepth parameter submitted as part of MarketDataRequest message.

Tag Field Name Required Comments
262 MDReqID Y MDReqID associated with the previous request
55 Symbol Y Symbol name
207 SecurityExchange Y Exchange name
83 RptSeq Y Sequence number of events
268 NoMDEntries Y
269 MDEntryType Y Supported Values:
  • 0 - BID
  • 1 - OFFER
270 MDEntryPx Y Price
271 MDEntrySize Y Entry size
272 MDEntryDate Y Date when the given entry has been added or modified last time
ISO 8601 format is used, UTC timezone
273 MDEntryTime Y Time when the given entry has been added or modified, UTC timezone

MarketDataIncrementalRefresh

Example:

Field Name Example
MDReqID 262=100_1
Symbol 55=ETH/BTC
SecurityExchange 207=HUOBI
NoMDEntries 268=1
MDUpdateAction 279=1
MDEntryType 269=0
MDEntryPx 270=0.035089
MDEntrySize 271=3.214
MDEntryDate 272=20180601
MDEntryTime 273=03:30:32.506124
AggressorSide 2446=0
RptSeq 83=587

MsgType: X

Direction: IN

Description: given message is used to transmit sequential updates for the particular order book. It might contain any number of NEW, UPDATE, DELETE and TRADE events that reflect the most recent book’s changes.

Valid processing order: DELETE → UPDATE → NEW.

Server always stream explicit DELETE events.

Please note, that standard FIX 4.4 MarketDataIncrementalRefresh message has been changed by moving Symbol(55) and Security Exchange(207) fields out of NoMDEntires(268) group.

Tag Field Name Required Comments
262 MDReqID Y MDReqID associated with the previous request
55 Symbol Y Symbol Name
207 SecurityExchange Y Exchange Name
268 NoMDEntries Y
279 MDUpdateAction Y Supported Values:
  • 0 - NEW
  • 1 - CHANGE
  • 2 - DELETE
  • 3 - RESET
For trade event should be NEW
269 9 MDEntryType Y Supported Values:
  • 0 - BID
  • 1 - OFFER
  • 2 - TRADE
270 MDEntryPx Y Price
271 MDEntrySize N Entry size. This field might be absent in case of DELETE event
272 MDEntryDate Y Date when the given entry has been added or modified last time
ISO 8601 format is used, UTC timezone
273 MDEntryTime Y Time when the given entry has been added or modified, UTC timezone
2446 AggressorSide N Indicates which side is the aggressor of the trade (MDEntryType = TRADE).
Supported Values:
  • 0 - BID
  • 1 - ASK
  • 2 - UNDEFINED
83 RptSeq Y MD Entry sequence number per instrument update

Trading Session

Trading sessions are used to send orders to different liquidity providers and to receive confirmations.

FIX session is a two-way asynchronous communication channel that does not require any polling/constant refreshes. Any changes in the order's status will be automatically pushed back to the client.

By default, a trading session works as a single entry point for all organization's accounts and exchanges which helps significantly reduce integration complexity. When more complex scenarios are needed, embedded ACL rules allow configuring who can send where.

Organizational structure

Organization An organization is an entity, that represents the entire client's company inside the XTRD.
Account An account is an entity that holds links to exchanges. Organizations can have multiple accounts.
Login This entity is used to perform trading operations.

Order states diagram

Once the server received client’s order, it will respond with ExecutionReport message with two possible statuses(OrdStatus field):

Dictionaries

Security Type

Type Value Description
Foreign Exchange Contract FOR All fiat to fiat pairs
Digital Assets Spot Contract CRYPROSPOT All crypto to crypto or crypto to fiat spot contracts
Perpetual Swap Contract PERPSWAP Perpetual swap contracts such as BTC-PERPETUAL
Futures Contracts FUT Futures contracts

Order Types

Order Type Comments
Market(1) When sending market orders, Price or StopPx is not required to be set
Limit(2) When sending limit orders, Price(44) field is required to be set

Order Sides

Only 2 sides are supported:

Time in Force

Type Comments
Day(0) If order becomes pending, it will be canceled at the end of the trading session
Good Till Cancel(1)
Immediate Or Cancel(3) Limit order will be executed at an exact price or better immediately, else will be canceled
Fill Or Kill(4) Order will be filled for the quantity specified in OrderQt, else will be canceled

Messages

Logon

MsgType: A

Direction: IN/OUT

Description: Logon should be sent as a very first message to establish FIX session and pass authentication process. In the case of successful authentication, server will respond with corresponding Logon message.

Tag Field Name Required Comments Example
98 EncrypMethod Y Always set to None(0) 98=0
108 HeartBtInt Y Heartbeat interval, always 30s 108=30
553 Username Y 553=1001
554 Password Y 554=Rr68twd6mw

Logout

MsgType: 5

Direction: IN/OUT

Description: Logout message is used as a confirmation.

Tag Field Name Required Comments
58 Text N Disconnection reason in human-readable format
Please note, that this field might be absent

NewOrderSingle

Example:

Field Name Example
Account 1=1001
ClOrdID 11=1234
12=ORD_1234
OrderQty 38=0.125
OrdType 40=1
Price 44=0.033528
StopPx 99=0.033612
Side 54=1
Symbol 55=ETH/BTC
TimeInForce 59=0
TransactionTime 60=20180912-12:05:15.105
ExDestination 100=OKEX
SecurityType 167=FOR
ExecInst 18=6

MsgType: D

Direction: OUT

Description: The message is used by institutions wishing to electronically submit securities and forex orders to a broker for execution.

Tag Field Name Required Comments
1 Account Y Login ID, associated with given session
11 ClOrdID Y Client assigned order ID
38 OrderQty Y Initial Order size
40 OrdType Y Type of order
Supported values:
  • Market(1)
  • Limit(2)
44 Price C Conditional field, indicating an expected fill price.
Required for:
  • Limit
99 StopPx C Conditional field, required for Stop order type
54 Side Y Order side used
Supported Values:
  • Buy(1)
  • Sell(2)
55 Symbol Y Symbol name
59 TimeInForce Y Control orders lifetime behavior.
Supported Values:
  • Day(0)
  • Good till Cancel(1)
  • Immediate or Cancel(3)
  • Fill Or Kill(4)
60 TransactionTime Y Timestamp in UTC timezone when the order was created with included milliseconds
100 ExDestination Y ECN or Venue name where the order will be sent/executed
167 SecurityType Y Type of security to trade.
Supported values:
  • CRYPTOSPOT - Digital Assets spot market contract
  • PERPSWAP - Digital Asset perpetual swap contract
  • FOR - Foreign exchange contract
  • FUT - Futures contract
18 ExecInst N Instructions for orders handling during execution.
Supported values:
  • Participate, don't initiate(6) - POST-ONLY
  • Do Not Increase(E)
  • No Cross(A)

OrderCancelRequest

Example:

Filed Name Example
Account 1=1001
ClOrdID 11=1234
OrderID 37=312351044
OrigClOrdID 41=1233
Side 51=1
Symbol 55=ETH/USD
TransactionTime 60=20180912-12:05:15.105

MsgType: F

Direction: OUT

Description: OrderCancelRequest is used to cancel the order in its entirety. Only orders in NEW or PARTIALLY_FILLED statuses can be canceled. If you need to cancel only a part of the non-filled amount (leaves quantity), please refer to OrderCancelReplaceRequest.

Tag Filed Name Required Comments
1 Account Y Trader, which hold particular order to cancel
11 ClOrdID Y Client order ID for cancel operation
37 OrderID Y OrderID which should be canceled
41 OrigClOrdID Y Client order ID of order which should be canceled
54 Side Y Order side of order, identified by OrigClOrdID/OrderID
55 Symbol Y Symbol, association with working order
60 TransactionTime Y Timestamp in UTC timezone when an order was created with included milliseconds

OrderCancelReject

Example:

Field Name Example
Account 1=1001
ClOrdID 11=CCL_001
OrigClOrdID 41=TRD_00231
OrderID 37=1123423
CxlRejReason 102=0
CxlRejResponseTo 434=1
Text 58=Can't cancel filled order
TransactionTime 60=20180912-12:15:15.105

MsgType: F

Direction: IN

Description: This message will be sent by the server in response to OrderCancelRequest if the operation failed for some reason.

Tag Field Name Required Comments
1 Account Y
11 ClOrdID C ID of client order which was used to perform cancel operation
41 OrigClOrdID C ID of canceling client order
37 OrderID C ID of working order on XTRD side. Usually transmitted as OrderID within ExecutionReport message
102 CxlRejReason Y Supported Values:
  • 0 - Too late to cancel
  • 1 - Unknown order(send when at least one of order related fields are missed, contains incorrect information or order can't be found)
  • 2 - Broker/Exchange option
  • 4 - Unable to Process
  • 99 - Other
434 CxlRejResp
onseTo
Y Supported Values:
  • 1 - OrderCancelRequest
58 Text C Textual comments about rejection reason
60 TransactionTime Y Timestamp in UTC timezone when Order can rejected

ExecutionReport

Example:

Field Name Example
Account 1=1001
ClOrdID 11=1234
12=ORD_1234
OrderID 37=312351043
SecondaryOrderID 198=ea4063b0-4b66-11ea-b77f2e728ce88125
ExecID 17=4000123541
MassStatusReqId 584=ord_req_1223
TotNumReports 911=14
LastRptRequested 913=Y
OrdType 40=1
Price 44=0.033953
Side 54=1
Symbol 55=ETH/BTC
OrdStatus 39=2
ExecType 150=F
AvgPx 6=0.033959
LastPx 31=0.033951
LastQty 32=0.100
CumQty 14=0.200
LeavesQty 151=0.300
Text 58=Account not found.
TimeInForce 59=0
TransactionTime 60=20180912-12:05: 15.105
ExDestination 100=OKEX
OrdRejReason 103=11
SecurityType 167=CRYPTOSPOT
Commission 12=0.001
CommisionType 13=3
CommissionCurrency 479=USD
ExecInst 18=6

MsgType: 8

Direction: IN

Description: Used to send order status information to a FIX client, such as confirmations, fills, and unsolicited changes

Tag Field Name Required Comments
1 Account Y Login ID, associated with a given session
11 ClOrdID Y Client-assigned order ID
37 OrderID Y Order ID on XTRD side
198 SecondaryOrderID C Order ID, assigned by target exchange
17 ExecID Y Order execution ID
This field will be set to zero("0") when processing OrderMassStatusRequest message
(ExecType=ORDER STATUS(I))
584 MassStatusReqId N Request ID, associated with OrderMassStatusRequest message
911 TotNumReports N A conditional field that will appear in the response to Order Mass Status Request(AF) message. Contains a total number of all orders that meet search criteria
912 LastRptRequested N A conditional field that appears only for reports with ExecType=ORDER STATUS.
Indicates that this is the very last message in the batch
40 OrdType Y Order Type (Market, Limit)
44 Price Y Conditional field, indicating expected fill price for Limit orders
54 Side Y Order side used
Supported Values:
  • Buy(1)
  • Sell(2)
55 Symbol Y Symbol name
39 OrdStatus Y Reports current order status
Supported values:
  • PENDING NEW(A)
  • NEW(0)
  • PARTIALLY FILLED(1)
  • FILLED(2)
  • CANCELED(4)
  • REJECTED(8)
150 ExecType Y Reports current execution status:
Supported values:
  • NEW(0)
  • TRADE(F)
  • CANCELED(4)
  • REJECTED(8)
  • ORDER STATUS(I)
6 AvgPx Y Average price of all executed parts(in case of partial fills)
31 LastPx C Price of last executed part. If order fully filled at once, LastPx will be same as AvgPx
32 LastQty C Last executed size.
14 CumQty Y Total executed quantity for a given order (sum of all fills)
151 LeavesQty Y Indicates quantity of order still not-executed yet live.
58 Text C May contain optional text information related to order status. E.g. textual explanation
of rejection
59 TimeInForce Y Control order lifetime behavior.
Supported Values:
  • Day(0)
  • Good till Cancel(1)
  • Immediate or Cancel(3)
  • Fill Or Kill(4)
60 TransactionTime Y Time of the most recent Order's update,timestamp in UTC timezone.
100 ExDestination Y ECN or Venue name where the order was sent/executed
103 OrdRejReason C If a case of a rejection, this field will help identify the source of error
  • Broker Option(0)
  • Unknown Symbol(1)
  • Exchange Closed(2)
  • Exceeds Limits(3)
  • Too Late(4)
  • Unknown Order(5)
  • Duplicated Order ID(6)
  • Unsupported Order Characteristics(11)
  • Incorrect Quantity(13)
  • Unknown Accounts(15)
  • Too Many Requests(50)
  • Other(99)
167 SecurityType Y Type of security.
Supported values:
  • FOR - Foreign Exchange Contract
  • CRYPTOSPOT - Digital Assets spot market contract
  • PERPSWAP - Digital Asset perpetual swap contract
  • FUT - Futures contract
12 Commission C Commission charged for the last execution or for the entire chain of executions(as a response for OrderMassStatusRequest).
Only orders in status PARTIALLY_FILLED(1) or FILLED(2) have this tag set.
13 CommisionType C Supported values:
  • Absolute(3)
Only orders in status PARTIALLY_FILLED(1) or FILLED(2) have this tag set.
479 CommissionCurrency C Currency used to charge given commission
Only orders in status PARTIALLY_FILLED(1) or FILLED(2) have this tag set.
18 ExecInst N Instructions for orders handling during execution.
Supported values:
  • Participate, don't initiate(6) - POST-ONLY
  • Do Not Increase(E)
  • No Cross(A)

OrderMassStatusRequest

Example:

Field Name Example
MassStatusReqId 584=request_123
MassStatusReqType 585=1
NoPartyIDs 453=1
PartyID 448=HUOBI
PartyRole 452=22

MsgType: AF

Direction: OUT

Description: This message is used when counterparty needs to obtain a list of list(working) orders that match certain criteria.

A response will be provided through a series of ExecutionReports that contains ExecType=Status and echoed back MassStatusReqId (584) field.

Tag Field Name Required Comments
584 MassStatusReqId Y Unique ID, associated with a given request
585 MassStatusReqType Y Specify the scope of a mass status request.
Supported Values:
  • 7 - status for all orders that belong to Organization
  • 8 - status for orders that belongs to a certain PartyID. In this case, additional information should be provided using NoPartyIds group. It is possible to provide more, than one PartyID at once.
453 NoPartyIDs C Mandatory, when MassStatusReqType=8 and holds a list of actual trading Logins.
Additionally, can be used to narrow request scope by specifying exchanges. If no exchange-related information is provided, the server will respond with a list that includes open orders from all exchanges.
448 PartyID   Exchange name
Login ID
452 PartyRole   Supported values:
  • 6 - Introducing Firm(Organization ID in XTRD terminology)
  • 11 - Order Origination Trader(Login in XTRD terminology)
  • 22 - Exchange

RequestForPositions

Example:

Field Name Example
PosReqId 710=req_1
PosReqType 724=0
SubscriptionRequestType 263=1
Account 1=1001
AccountType 581=1
ClearingBusinessDay 715=20191107
NoPartyIDs 453=1
PartyID HUOBI
PartyRole 452=22
TransactTime 60=20191107-12:05:15.105

MsgType: AN

Direction: OUT

Description: This message is used to request a list of positions associated with a given exchange and trading login. This information is available in the form of a snapshot or incremental updates send by the server once the position size changed.

Tag Field Name Required Comments
710 PosReqId Y Unique ID, associated with a given request
724 PosReqType Y Used to narrow the scope of information transmitted.
Supported values:
  • Position(0)
263 SubscriptionRequestType Y Used to subscribe or unsubscribe from reports.
Supported values:
  • Snapshot(0)
  • Snapshot and Updates(1)
  • Disable previous Snapshot and Updates request(2)
1 Account Y Organization ID
581 AccountType Y Type of account associated with a position request
Supported values:
  • 1 - Account
715 ClearingBusinessDay Y The Clearing Business Date referred to by this request
453 NoPartyIDs Y
448 PartyID Y Counterparty name e.g. name of the target exchange
Login ID
452 PartyRole Y Supported values:
  • 6 - Introducing Firm
  • 11 - Order Origination Trader
  • 22 - Exchange
60 TransactTime Y Time, when this request was initiated
Examples

Your Organization ID is 1001 and it manages four trading accounts – 1234, 2000, 2101, 4442.

You want to get a snapshot of all positions your organization has under the management. In this case, NoPartyIDs group will look as following:

Entry # Tag Name Value
0 448 PartyID 1001
0 452 PartyRole 6

This request(if executed successfully) should returns positions for logins 1234, 2000, 2101, and 4442.

If you are looking for positions that belong to certain logins(e.g. 1234 and 4442) then NoPartyIDs group will be as following:

Entry # Tag Name Value
0 448 PartyID 1234
0 452 PartyRole 11
1 448 PartyID 4442
1 452 PartyRole 11

RequestForPositionsAck

Example:

Field Name Example
PosMaintRptId 721=123456021
PosReqId 710=req_1
TotalNumPosReports 727=246
PosReqResult 728=0
PosReqStatus 729=0
NoPartyIDs 453=2
PartyID 448=XTRD
PartyRole 452=11
Account 1=1001
AccountType 581=1
SecurityExchange 207=OKEX
Text 58=Not authorized to request positions for given Account

MsgType: AO

Direction: IN

Description: This message will be sent as a confirmation to Request for Positions. It contains basic information such is request status and a number of positions returned with the following snapshot.

Tag Field Name Required Comments
721 PosMaintRptId Y Unique identifier for this position report
710 PosReqId N Request ID, copied from the parent message
727 TotalNumPosReports N Number of positions returned
728 PosReqResult Y Indicates the request status.
Supported values:
  • 0 - Valid Request
  • 1 - Invalid or Unsupported request
  • 2 - No positions found
  • 3 - Not authorized to request positions
729 PosReqStatus Y Status of request for positions.
Supported values:
  • 0 - Completed
  • 2 - Rejected
453 NoPartyIDs Y  
448 PartyID    
452 PartyRole   Supported values:
  • 11 - Order Origination Trader(Login ID)
  • 22 - Exchange
1 Account Y Organization ID
581 AccountType Y Type of account associated with a position request
Supported values:
  • 1 - Account
207 SecurityExchange N Name of the trading venue to get a list of the positions
58 Text N Human-readable error message

PositionReport

Example:

Field Name Example
PosMaintRptID 721=1002312
PosReqID 710=req_12
PosReqResult 728=0
ClearingBusinessDate 715=20191107
NoPartyIDs 453=2
PartyID 448=12
PartyRole 1=1001
Account 1=2342
AccountType 581=1
Symbol 55=ETH
SecurityType 167=FUT
NoPositions 702=1
PosType 703=ETR
LongQty 703=500.123000

MsgType: AP

Direction: IN

Description: This message is providing you with all your balances.

Tag Field Name Required Comments
721 PosMaintRptID Y Unique identifier for this position report
710 PosReqID N This filed will be set when returning positions snapshot and will be omitted for any
sequential updates
728 PosReqResult Y Always 0(Valid Request)
715 ClearingBusinessDate Y Always today
453 NoPartyIDs Y For a regular report, NoParties group contains 2 entries:
  • Position owner(Order Origination Trader)
  • Exchange
448 PartyID    
452 PartyRole N Supported values:
  • 11 - Order Origination Trader
  • 22 - Exchange
1 Account Y Organization ID
581 AccountType Y Type of account associated with a position request
Supported values:
  • 1 - Account
55 Symbol Y Human readable asset name
167 SecurityType Y Supported values:
  • CRYPTOSPOT
  • PERPSWAP
  • FUT
  • PERPSWAP
702 NoPositions Y  
703 PosType   Supported Values:
  • ETR - Electronic Trade Qty
704 LongQty Either LongQty or ShortQty is available as part of this group.
ShortQty is not available for SPOT markets.
705 ShortQty

TradingSessionStatusRequest

Example:

Field Name Example
TradSesReqID 335=session_request_1
SubscriptionRequestType 263=1

MsgType: g

Direction: OUT

Description: This message requests the current status and subscribes to status updates of all outgoing connections belonging to the acting client. In case of a successful request, the server will respond with TradingSessionStatuses messages.

Tag
Field Name
Required
Comments
335 TradSesReqID Y Unique ID associated with the given request
263 SubscriptionRequestType Y

Supported Values:

  • 1 - Snapshot plus Updates

TradingSessionStatus

Example:

Field Name
Example
TradSesReqID 335=session_request_1
TradingSessionID 336=DERIBIT
TradingSessionSubId 625=1
UnsolicitedIndicator 325=Y
TradSesStatus 340=2
Text 58=AUTH ERROR

MsgType: h

Direction: IN

Description: This message sends by the server in response to TradingSessionRequest(to transmit snapshot) or when one of the client's outgoing connections changed its status for various reasons e.g. because of the network error.

Tag
Field Name
Required
Comments
335 TradSesReqID Y Unique identifier for the Status Request, copied from the original TradingSessionStatusRequest message
336 TradingSessionID Y Name of the trading destination that changed its status
625 TradingSessionSubId Y Account ID, associated with Exchange from TradingSessionID. 
TradingSessionSubId uses to clearly identify which trading session changed its status as long the Organization might have multiple accounts and multiple outgoing connections to the same destination.
325 UnsolicitedIndicator Y

Supported Values:

  • N - message sent as a response to the initial command(this is a snapshot)
  • Y - message sent as a response to real-time changes in exchange connectivity status
340 TradSesStatus Y

Supported Values:

  • 2 - OPEN
  • 3 - CLOSED
58 Text N

Might contain additional information in case of the error

Management API

Introduction

XTRD OEMS provides easy to use REST API to automate certain aspects of integration such as Accounts and Exchanges management and so on.

URL schema represents resources linkage where Accounts are linked to parent Organization, and Exchanges are linked to Accounts. Exchanges themselves have their own resources that could be managed through the REST API.

Authentication

Each request to the management REST API should contain an authentication token. The token has to be provided within Api-Key-Token header. In order to obtain the token, the organization administrator has to manually generate it using the Client's Portal.

Accounts

XTRD OEMS designed as a multitenant application where a single Organization can carry underlying Accounts which, in their turn, carry Logins.

An Organization is an entity, designed to represent the end client. Some resources such as market data subscriptions or the number of messages sent are properties of the Organization.

An Account is a form of entity, that holds such valuable resources as links to exchanges. Therefore, all balances are associated with an Account.

A Login is an entity that uses to initiate operations under orders - open, cancel, update.

Each Account has only one Login, Organization might have multiple Accounts.

Get all Accounts

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

[
  {
    "id": 10,
    "name": "megatestt",
    "description": null
  },
  {
    "id": 2,
    "name": "Office X",
    "description": null
  }
]

This endpoint returns the list of all accounts, registered under your organization.

Method and path

GET /rest/organizations/{ORGANIZATION}/accounts

URL Parameters
Parameter Description
ORGANIZATION Organization ID
Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
Response Codes
Code Description
200 Request was successfully executed
401 Incorrect/slate token provided
403 Forbidden

Get Account by ID

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts/1", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

{
  "id": 1,
  "name": "FX UAT Account",
  "description": null
}

Endpoint to extract Account by it's ID.

Method and path

GET /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}

URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
Response Codes
Code Description
200 Request was successfully executed
401 Invalid token provided
403 Forbidden
404 Organization or Account with provided ID is not found

Add Account

Body example:

{
  "name": "FX UAT Account"
}

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
    body: {
      name: "FX UAT Account",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.post("https://service.url/rest/organizations/1/accounts/", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'}, data={"name": "FX UAT Account"})
data = request.json()

Response:

{
  "id": 75,
  "name": "FX UAT Account",
  "login": {
    "id": 28,
    "name": "FX UAT Account",
    "balance": 100.0
  }
}

Endpoint to add a new account into your organization. Server also will create a Login entry that can be used to perform trading operations.

Method and path

POST /rest/organizations/{ORGANIZATION}/accounts

URL Parameters
Parameter Description
ORGANIZATION Organization ID
Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
Response Codes
Code Description
200 Request was successfully executed
401 Invalid token provided
500 An error occured while processing the creation

Update Account information

Body example:

{
  "name": "Account 2 New Name"
}

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1",
  {
    method: "PUT",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
    body: {
      name: "Account 2 New Name",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.post("https://service.url/rest/organizations/1/accounts/1", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'}, data={"name": "Account 2 New Name"})
data = request.json()

Response:

{
  "id": 1,
  "name": "Account 2 New Name",
  "description": "some description"
}

Endpoint to update certain fields on a given Account. The only field that could be altered right now is the Account's name.

Method and path

POST /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}

URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
Response Codes
Code Description
200 Request was successfully executed
401 Invalid token provided
404 Account with given ID is not found
500 An error occured while processing the updating

Delete account

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.post("https://service.url/rest/organizations/1/accounts/1", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

{
  "id": 1,
  "name": "Account 2",
  "organization_id": 1,
  "description": "some description",
  "status": 1
}

Endpoint to delete Account.

Method and path

POST /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}

URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
Response Codes
Code Description
200 Request was successfully executed
401 Invalid token provided
404 Account with given ID is not found
500 An error occured while processing the deleting

Exchanges

This set of calls allows you to control links between Account and Exchange as a trading destination. According to the XTRD workflow, each Account can have an unlimited number of linked exchanges but their types should be different. E.g. Account 'Trading Desk #1' can't have two Binance accounts. If your workflow requires two or more exchanges of similar type, it is possible to create another Account and link new Exchange credentials to it.

Get all exchanges

Request:

let response = await fetch("https://service.url/rest/exchanges", {
  headers: {
    "Content-Type": "application/json",
    "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
  },
});
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/exchanges", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

[
  {
    "id": 10,
    "name": "GEMINI",
    "full_name": "Gemini exchange"
  },
  {
    "id": 12,
    "name": "BITFINEX",
    "full_name": "BitFinex exchange"
  },
  {
    "id": 20,
    "name": "BITMART",
    "full_name": "BitMart exchange"
  }
]

This method to get exchanges list. Success request will return full formed exchange objects.

Method and path

GET /rest/exchanges

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
Response Codes
Code Description
200 Request was successfully executed
401 Invalid token provided
500 Internal server error - exchanges can't be received because of certain reasons

Get configured exchanges

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts/1/exchanges", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

[
  {
    "id": 95,
    "account_id": 1,
    "exchanges": [
      {
        "id": 3,
        "name": "HITBTC"
      }
    ],
    "params": {
      "api_key": "3333***3344",
      "private_key": "3er3***3344"
    }
  }
]

This method returns a list of exchanges where given account can trade.

Method and path

GET /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
Response Codes
Code Description
200 Exchanges (a.k.a connectors) was successfully received
401 Invalid token provided
500 Internal server error - exchanges can't be received because of certain reasons

Add exchange to Account

Body example:

{
  "route_id": 3,
  "params": {
    "private_key": "abc",
    "api_key": "333344"
  }
}

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
    body: {
      route_id: 3,
      params: {
        private_key: "abc",
        api_key: "333344",
      },
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts/1/exchanges", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'}, { "route_id": 3, "params": {"private_key": "abc", "api_key": "333344"})
data = request.json()

Response:

{
  "id": 95,
  "account_id": 1,
  "exchanges": [
    {
      "id": 3,
      "name": "HITBTC"
    }
  ]
}

This method is provided to enable trading on a particular exchange. It required to provide credentials(such as Private Key, Api Key, SenderCompId and so on)

Method and path

POST /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
Response Codes
Code Description
200 Operation is accomplished successfully
201 Connector created but something went wrong:
400 Incomplete or incorrect data has been passed
401 Invalid token provided
404 Organization ID, Account ID, Router ID did not find
409 Account already has registered routing destination to target exchange or failed to create connector

Update credentials on Exchange

Body example:

{
  "private_key": "da281ca8-7a43-11ec-90d6-0242ac120003",
  "api_key": "66442f2c-c7ef-404b-b01c-30f2eb8ca318"
}

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges/1",
  {
    method: "PUT",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
    body: {
      private_key: "da281ca8-7a43-11ec-90d6-0242ac120003",
      api_key: "66442f2c-c7ef-404b-b01c-30f2eb8ca318",
    },
  }
);
if (response.ok) {
  let json = await response.text();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts/1/exchanges/1", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'}, { "private_key": "da281ca8-7a43-11ec-90d6-0242ac120003","api_key": "66442f2c-c7ef-404b-b01c-30f2eb8ca318"})
data = request.json()

Response:

Exchange was successfuly updated!

Endpoint allows to update/change credential information on Account/Exchange record. Some Exchanges have key expiry mechanisms so keys have to be updated from time to time.

Method and path

POST /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges/{EXCHANGE}

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
EXCHANGE ID of configured exchange
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID, Account ID, or Exchange ID is not found

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges/1",
  {
    method: "DELETE",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.delete("https://service.url/rest/organizations/1/accounts/1/exchanges/1", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

Exchange  was deleted from trading destination

Endpoint will remove the link between Exchange and the given Account.

All credentials will be deleted from our internal database.

If Account has open orders on this Exchange, they will remain open.

Trading history will still be stored and available for you.

Method and path

DELETE /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges/{EXCHANGE}

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
EXCHANGE ID of an exchange
Response Codes
Code Description
200 Operation is accomplished successfully
202 Exchange(a.k.a connector) deleted but user data not deleted
401 Invalid token provided
404 Organization ID, Account ID, Exchange ID did not find
409 Exchange is not deleted

Get connectivity statuses for all exchanges

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/status",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts/1/status", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

[
  {
    "id": 95,
    "status": 0,
    "extended_status": 8,
    "last_update_time": "2020-09-17T06:46:54.992Z",
    "attempts": 0
  }
]

Endpoint to extract connectivity statuses for all exchanges for given Account. A successful result will contain an array of objects, each of which represents status for a single exchange's link. Field extended_status holds additional information about what is going on with a link right now.

A link to exchange has several states such as DISCONNECTED or CONNECTED. Having a link in CONNECTED state doesn't mean that it's possible to trade. Once a connection is established, our system tries to synchronize its internal state(orders, positions, trading history) with what is currently available on the exchange. Transitions from stage to stage are reflected in extended_status field.

Method and path

GET /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/status

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID, Account ID is not found

Get connectivity statuses for a single exchange

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges/1/status",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/accounts/1/exchanges/1/status", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

{
  "id": 1,
  "status": 0,
  "extended_status": 8,
  "last_update_time": "2020-09-17T06:46:54.992Z",
  "attempts": 0
}

Endpoint for querying status information for a specific Exchange's link

Method and path

GET /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges/{EXCHANGE}/status

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
EXCHANGE ID of an exchange
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID, Account ID, Exchange ID is not found

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges/1/start",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.post("https://service.url/rest/organizations/1/accounts/1/exchanges/1/start", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

Trading started.

Endpoint to start link to a selected Exchange. Newly created links are always in DISCONNECTED status so this method has to be called in order to establish the connection and initiate all synchronization procedures.

Method and path

GET /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges/{EXCHANGE}/start

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
EXCHANGE ID of an exchange
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID, Account ID, Exchange ID is not found

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/accounts/1/exchanges/1/stop",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.post("https://service.url/rest/organizations/1/accounts/1/exchanges/1/stop", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

Trading stopped.

Endpoint to terminate a link to Exchange. It will not delete the connectivity itself, the method simply close the outgoing connection whatever protocol is used(WebSocket, FIX etc) endpoint to terminate a link to Exchange. It will not delete the connectivity itself, the method simply close the outgoing connection whatever protocol is used(WebSocket, FIX etc)

Method and path

POST /rest/organizations/{ORGANIZATION}/accounts/{ACCOUNT}/exchanges/{EXCHANGE}/stop

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ACCOUNT Account ID
EXCHANGE ID of an exchange
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID, Account ID, Exchange ID is not found

Routing destinations

Routes or routing destinations is the concept that helps to separate actual Exchange(e.g. Binance or FTX) from factual connectivity(link) established between XTRD servers and the exchange itself. Some exchanges, such as FTX or Gemini, might have more, than one route, for example, WebSockets and/or FIX.

Get routing destinations

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/routes/exchanges",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/routes/exchanges", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

[
  {
    "id": 1,
    "exchange": {
      "id": 11,
      "name": "OKEx"
    }
  },
  {
    "id": 2,
    "exchange": {
      "id": 4,
      "name": "CEX.IO"
    }
  },
  {
    "id": 3,
    "exchange": {
      "id": 4,
      "name": "CEX.IO"
    }
  }
]

Endpoint to return a list of all supported by server routing destinations.

It is possible when a single Exchange might have several routes. This happens, when we provide alternative implementations.

Method and path

GET /rest/organizations/{ORGANIZATION}/routes/exchanges

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID is not found

Get route description

Request:

let response = await fetch(
  "https://service.url/rest/organizations/1/routes/1/exchanges",
  {
    headers: {
      "Content-Type": "application/json",
      "Api-Key-Token": "sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw",
    },
  }
);
if (response.ok) {
  let json = await response.json();
}
import requests

request = requests.get("https://service.url/rest/organizations/1/routes/1/exchanges", {'Api-Key-Token': 'sHBXSvuk3fF2MKigsUI1AAAA1AAAgABYXJ0aHVyLnJhZGNoZW5rbw', 'Content-Type': 'application/json'})
data = request.json()

Response:

{
  "id": 42,
  "exchange": {
    "id": 7,
    "name": "BITTREX"
  },
  "parameters": [
    [
      {
        "key": "private_key"
      },
      {
        "key": "api_key"
      }
    ]
  ]
}

Endpoint to extract detailed information about the route from the server.

The most important information here is located inside the parameters array. These are the required parameters, for example, API Key or Private Key, that have to be provided in order to establish a real connection to the exchange of your interest.

Method and path

GET /rest/organizations/{ORGANIZATION}/routes//exchanges

Headers
Name Value
Content-Type application/json
Api-Key-Token your API token
URL Parameters
Parameter Description
ORGANIZATION Organization ID
ORGANIZATION Routing Destination ID
Response Codes
Code Description
200 Operation is accomplished successfully
401 Invalid token provided
404 Organization ID or Route ID is not found

Constants

Exchange connection statuses

Status ID Meaning
0 DISCONNECTED
1 DISCONNECTING
2 CONNECTING
3 CONNECTED
4 AWAIT SUBSCRIBE
5 AUTH REQUIRED
6 AUTH FAILED

Extended Statuses

Status ID Meaning
2000 Sync open orders
2001 Orders synchronization failed
2002 Sync trading history
2003 Trading history synchronization failed
2004 Sync positions
2005 Positions synchronization failed
2006 Ready to Trade
2007 Trading Disabled

UAT Environment

Introduction

Our demo environment provides the ability to finish the integration without putting real money at risk. To start the process, you'll need to create new or use existing credentials for one of the supported exchanges.

Important: do not use production credentials with a demo environment.

Exchange URL Comments
Binance Global https://testnet.binance.vision/
Binance Futures https://testnet.binancefuture.com USD-M Futures
Deribit https://test.deribit.com/
Coinbase Pro https://public.sandbox.pro.coinbase.com/
OKX
ByBit https://testnet.bybit.com/
CoinFLEX https://v2stg.coinflex.com/user-console/login

Available Instruments

Market Data Service provides production-level data(no delays) but is limited to several instruments.

Exchange Internal exchange name Symbol Native Name
Binance Global BINANCE BTC/USDT BTCUSDT
ETH/USDT ETHUSDT
LTC/USDT LTCUSDT
XRP/USDT XRPUSDT
Binance Futures BINANCE.FUTURES PERP:BTC-PERP:USDT BTCUSDT
PERP:ETH-PERP:USDT ETHUSDT
PERP:LTC-PERP:USDT LTCUSDT
Deribit DEREBIT PERP:BTC-PERP:BTC BTC-PERPETUAL
PERP:ETH-PERP:ETH ETH-PERPETUAL
PERP:BTC-PERP:USDC BTC_USDC-PERPETUAL
Coinbase Pro COINBASE BTC/USD BTC-USD
ETH/USD ETH-USD
LTC/USD LTC-USD
OKX OKEX BTC/USDT BTC-USDT
ETH/USDT ETH-USDT
LTC/USDT LTC-USDT
PERP:BTC-PERP:BTC BTC-USD-SWAP
PERP:ETH-PERP:ETH ETH-USD-SWAP
PERP:LTC-PERP:LTC LTC-USD-SWAP
ByBit USDT Swaps BYBIT.USDT.SWAPS PERP:BTC-PERP:USDT BTCUSDT
PERP:ETH-PERP:USDT ETHUSDT
PERP:LTC-PERP:USDT LTCUSDT
PERP:BNB-PERP:USDT BNBUSDT
PERP:ADA-PERP:USDT ADAUSDT
CoinFLEX COINFLEX BTC/USDC BTC-USD
ETH/USDC ETH-USD
LTC/USDC LTC-USD
PERP:BTC-PERP:USDC BTC-USD-SWAP-LIN
PERP:ETH-PERP:USDC ETH-USD-SWAP-LIN
PERP:LTC-PERP:USDC LTC-USD-SWAP-LIN