This documentation is designed for our Business Partners, interested in electronically connecting with BSD Broker.
In general, BSD Broker accommodates two forms of service usage for the partners:
Three environments are available to facilitate integration at different stages:
MiCA regulation:
Specific endpoint errors are descibed under specific endpoints, some errors are common to all requests. When contacting BSD support please always provide value of trace response parameter so we can try to find more info about specific error in application logs
Status code | Error code | Description |
---|---|---|
401 | Error indicates issues with authentication. Please check if you have valid token and create new token if expired | |
401 | InvalidCredentials | Error indicates that you provided invalid credentials for creating authentication token. Please check clientId and clientSecret |
400 | ValidationError | Error indicates that input data is not valid. Please check errors property on response for more details |
403 | ActionNotAllowed | Error indicates that requested user is authenticated but has insufficient permissions. |
404 | NotFound | Error indicates that requested user id or partner id was not found on server or user is blocked. Please check details property on response for more details |
500 | InternalServerError | Error indicates backend related error. Please contact BSD support with trace for more information |
Our API can return two types of error responses depending on the nature of the error encountered:
For other types of errors that do not involve validation, the response does not include an errors array. Instead, the response provides a clear message and code that indicate the nature of the error, along with other relevant details.
Example of a standard error response:
{
"status": 422,
"title": "Unprocessable Entity",
"code": "AssetNotAvailable",
"message": "Required currency/entity not available in this account",
"detail": null,
"errors": null,
"instance": "/api/v1/user/data",
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1"
}
When a request fails due to validation errors, the response includes an errors array filled with all the validation issues encountered. This type of response typically occurs when input data does not meet the criteria set by the API's input validation rules.
Example of a validation error response:
{
"status": 400,
"title": "Bad Request",
"code": "ValidationError",
"message": "Parameters usage incorrect in the call, check the detail field",
"detail": null,
"errors": [
{
"code": "PredicateValidator",
"field": "username",
"message": "Username is required."
},
{
"code": "PredicateValidator",
"field": "email",
"message": "Email address is invalid."
}
],
"instance": "/api/v1/partner/auth",
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1"
}
On sandbox and prelive environments, edge cases can be tested by placing 'special' values for certain fields when calling the API.
Endpoint | Condition | Effect |
---|---|---|
Create user | externalReference ends with TST01 | status code 200, user gets created, API response is delayed by 100s |
Create user | externalReference ends with TST02 | status code 503, user does not get created, API response is delayed by 100s |
Import user kyc data | externalReference ends with TST03 | status code 200, KycStatus will always be Pending |
Import user kyc data | externalReference ends with TST04 | status code 200, KycStatus will be Confirmed, IsBlocked will be true |
Import user kyc data | externalReference ends with TST05 | status code 503 |
Import user kyc data | externalReference ends with TST06 | status code 200, KycStatus will be Pending for 5 minutes, then it will set to Rejected |
Request quote | assetCode: ETH, amount: 0.001001 | status code 503 |
Request quote | assetCode: ETH, amount: 0.001002 | status code 200, API response is delayed by 10s |
Place order | assetCode: ETH, amount: 0.001003 | status code 410, QuoteExpired |
Place order | assetCode: ETH, amount: 0.001004 | status code 422, UnstableMarket |
Place order | assetCode: ETH, amount: 0.001005 | status code 503, ServiceUnavailable |
Place order | assetCode: ETH, amount: 0.001006 | status code 200, Response is delayed by 100s (network timeout), Order is placed |
Place order | assetCode: ETH, amount: 0.001007 | status code 503, Response is delayed by 100s (network timeout), Order is not placed |
Place order | assetCode: ETH, amount: 0.010008 | status code 200, Response will return Failed status, but still place order |
This process is initiated manually from the back office dashboard, usually triggered by an email or a support ticket.
In the revocation process, the existing order is put into 'Revoked' status. In addition, a new 'storno' order is created with the same amount and reversed side.
In the price improvement process, the revocation process is applied first. Then, an additional new order is created with the same side as the original order but with a better price.
Example - revoke
Example - price improvement
Detecting and processing revokes (and price improvements) can be fully automated by the client backend.
To detect revoked orders partner should implement a process similar to the one bellow.
$lastProcessedId=id-of-last-processed-order-or-null
Every 5 min:
$revokedOrders = 'Get revoked orders'; startingAfter=$lastProcessedId
for $orderId in $revokedOrders:
{
$stornoOrderId, $priceImprovementOrderId = 'Get an order'; orderId=$orderId
$stornoOrder = 'Get an order'; orderId=$stornoOrderId
if $priceImprovementOrderId != null:
$priceImprovementOrder = 'Get an order'; orderId=$priceImprovementOrderId
{Process everything}
$lastProcessedId=$orderId
}
Please note, for brevity, the procedure described above does not include pagination, which a real implementation should include.
The process is described in FIX section: Order revoke and price improvement process.
Currently supported crypto assets and their essential details.
Asset Code | Name | Amount Precision | Price Precision | Min. Withdrawal Amount |
---|---|---|---|---|
AAVE | Aave | 8 | 10 | 1 |
ADA | Cardano | 6 | 10 | 10 |
ALGO | Algorand | 6 | 10 | 100 |
AXS | Axie Infinity Shards | 8 | 10 | 2 |
BAT | Basic Attention Token | 8 | 10 | 50 |
BCH | Bitcoin Cash | 8 | 10 | 0.05 |
BTC | Bitcoin | 8 | 10 | 0.001 |
CHZ | Chiliz | 8 | 10 | 150 |
CRV | Curve DAO Token | 8 | 10 | 20 |
DOGE | Dogecoin | 8 | 10 | 100 |
DOT | Polkadot | 8 | 10 | 1 |
ETC | Ethereum Classic | 8 | 10 | 0.5 |
ETH | Ethereum | 8 | 10 | 0.01 |
GRT | The Graph | 8 | 10 | 100 |
LINK | Chainlink | 8 | 10 | 3 |
LTC | Litecoin | 8 | 10 | 0.1 |
MANA | Decentraland | 8 | 10 | 50 |
POL | Polygon | 8 | 10 | 5 |
QNT | Quant | 8 | 10 | 0.1 |
SAND | The Sandbox | 8 | 10 | 50 |
SHIB | Shiba Inu | 0 | 10 | 2500000 |
SOL | Solana | 8 | 10 | 0.05 |
UNI | Uniswap | 8 | 10 | 3 |
XLM | Stellar Lumens | 7 | 10 | 50 |
XRP | XRP | 6 | 10 | 10 |
XTZ | Tezos | 6 | 10 | 10 |
This is the code that is used by REST API where assetCode is required.
When specifying amount in crypto-currency (for orders, withdrawals and deposits), number of decimals should not exceed this.
All quotes and orders returned from endpoints will have price rounded to 10 decimals.
Use provided clientId and clientSecret to generate access token. Once you have your token, you must include it in every API request in the header.
If you submit an invalid or expired token in an API request, or forget to include the token in the header, then the API will respond with a 401 Unauthorized error. In this case, your application must call this endpoint to generate a new one.
Access tokens are valid for 1 hour.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
clientId required | string non-empty Client identifier provided by Boerse Stuttgart Digital |
clientSecret required | string non-empty Client secret provided by Boerse Stuttgart Digital |
{- "clientId": "40633122a47c4f41b62830f1c0fe39c4",
- "clientSecret": "GBAyfVL7YWtP6gudLIjbRZV..."
}
{- "result": {
- "accessToken": "string"
}
}
B2B & B2B2C PARTNER ENDPOINTS
The Get user info endpoint is available both for B2B and B2B2C partner users and has not further restrictions in terms of the partner type.
B2B2C ONLY PARTNER ENDPOINTS
The user management features, such as the endpoints for creating users, changing users, importing user KYC data, changing user KYC data, requesting user deletion are designed for the integration of our B2B2C partners. For B2B partners these endpoints of the API are restricted and will return an HTTP 403 (forbidden) response code.
The diagram bellow illustrates the entire onboarding process for an end user in a B2B2C environment. The usage of BSDigital user API in the on-boarding process is highlighted within a boxed area.
sequenceDiagram
autonumber
actor Enduser as Enduser
Enduser->>Partner App: Register for crypto trading
Partner App->>Partner Backend: Request KYC data sharability
critical KYC data must be sharable
Partner Backend->>+Partner Backend: Check KYC data sharability
option KYC data outdated / older than 24 hours
Partner Backend->>+Partner App: KYC data outdated
Partner App->>+Enduser: Review KYC data screen <br/> (First name, Last name, Address, Legitimation data, AML data,..etc)
Enduser->>Partner App: Confirm/Update KYC data
Partner App->>Partner Backend: Confirm up-to-date KYC
option Validation Date of ID document outdated
Partner Backend->>+Partner App: ID document validation outdated
Partner App->>+Enduser: Upload new ID document screen
Enduser->>Partner App: Upload ID document (e.g. via phonto or PDF or ...)
Partner App->>Partner Backend: Forward ID document
Partner Backend->>+Partner Backend: Store ID document
end
Partner Backend->>Partner App: Confirm KYC data sharability
Partner App->>+Enduser: Success screen
Enduser->>Partner App: Confirm to continue
Partner App->>+Enduser: KYC data confirmation/update screen
Enduser->>Partner App: Confirm/Update KYC data (T&Cs, non-Fatca user, etc.)
Partner App->>+Partner Backend: KYC submit start
Partner Backend->>+Partner Backend: Check all KYC data availability (T&C confirmation etc.)
Partner App->>+Enduser: KYC pending screen (up to X minutes)
rect rgba(102, 102, 255, 0.19)
note right of Partner Backend: User creation (BSDigital User API)
Partner Backend->>BSDigital Backend: Request Create user
BSDigital Backend->>Partner Backend: Return created user ID
Partner Backend->>Partner Backend: Link BS Digital User ID
Partner Backend->>BSDigital Backend: Import user KYC data
BSDigital Backend->>Partner Backend: KYC data has been imported<br/> and is being processed
BSDigital Backend->>BSDigital Backend: Back office checks (AML, etc.)
Note over BSDigital Backend,Partner Backend: After all checks have passed
BSDigital Backend->>Partner Backend: Webhook notification (user_updated)
end
Partner Backend->>Partner App: KYC submit success
Partner App->>Enduser: KYC success screen
The highlighted section is divided into three parts:
To create a new user you need to call Create a user endpoint. At this point you only need to provide reference data. The response will contain the newly created User-ID, which you need to store in your backend and is needed for all further API calls related to that User. If there is a network error during this call, the call can be repeated. If you wish to change some user data user the Change user endpoint.
After user is successfully created, you have to import his KYC-data. To do so, you need to call Import user kyc data endpoint and provide user personal information, address and legitimization details as well as tax and AML relevant information. A successful response from this endpoint only means that provided KYC-data was accepted for processing. Trading is not possible yet, until the KYC-data has been processed successfully. You will receive a webhook notification when this happens. If you wish to change the imported kyc data use the Change user kyc data endpoint.
After the KYC has been successfully processed by the BSDigital back-office, a webhook-notification will be sent to your configured webhook-URL. This notification will contain the new KYC-Status of the user:
To create a new user, first use Create a user endpoint then use Import user kyc data to upload kyc data and initiate onboarding process.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
branch | string or null Partner branch. Optional. Used for classifying user for example by bank branch, department or any other smaller divisions. |
externalReference | string or null External reference. Optional. Used for storing unique partner user identifier |
tags | string or null Partner tags. Reserved for custom user tags |
{- "branch": "StuttgartOffice",
- "externalReference": "partner-df514599724248a3b14afde61d79c3e",
- "tags": "Bucket123"
}
{- "result": {
- "userId": "df514599724248a3b14afde61d79c3eauser",
- "externalReference": "partner-df514599724248a3b14afde61d79c3e"
}
}
Use this endpoint to modify user data after already Creating a user.
In the request body, include only the fields you wish to update, omit all others.
Example of changing user data:
{
"branch": "StuttgartOffice"
}
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
branch | string or null Partner branch. Optional. Used for classifying user for example by bank branch, department or any other smaller divisions. |
externalReference | string or null External reference. Optional. Used for storing unique partner user identifier |
tags | string or null Partner tags. Optional. Reserved for custom user tags |
{- "branch": "StuttgartOffice - Optional",
- "externalReference": "partner-df514599724248a3b14afde61d79c3e - Optional",
- "tags": "Bucket123 - Optional"
}
{- "result": {
- "userId": "df514599724248a3b14afde61d79c3eauser",
- "externalReference": "partner-df514599724248a3b14afde61d79c3e"
}
}
This allows you to get the users info by either the default User Id or External Reference.
When user kyc data is successfully processed, user status will be set to Confirmed.
This endpoint can be used to check user status and also to retrieve all the kyc data that was imported.
To use a different identifier, modify the UserId parameter.
The available options for UserIdType are:
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
userIdType | string The type of the identifier. The given identifier can either be the default "UserId" or "ExternalReference"(Unique user identifier). |
{- "result": {
- "userId": "df514599724248a3b14afde61d79c3eauser",
- "salutation": "Mr",
- "firstName": "Max",
- "lastName": "Mustermann",
- "address": {
- "line1": "Musterstraße",
- "line2": "1",
- "postalCode": "10000",
- "city": "Berlin",
- "country": "DE",
- "state": "BE"
}, - "mobileNumber": "+4923423234",
- "birthDate": "1990-12-05",
- "birthCity": "Berlin",
- "birthCountry": "DE",
- "nationality": "DE",
- "maritalStatus": "Single",
- "legitimation": {
- "documentNumber": "L3GP1C6FF34534",
- "type": "IdCard",
- "issuer": "BA REINICKENDORF BÜRGERBÜRO RATHAUS",
- "country": "DE",
- "issuedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z"
}, - "taxId": "2454027948945",
- "taxIdCountry": "DE",
- "branch": "string",
- "externalReference": "string",
- "tags": "string",
- "isBlocked": true,
- "kycStatus": "string",
- "fatcaRelevant": false,
- "fatcaCrsConfirmedAt": "2019-08-24T14:15:22Z",
- "pepRelevant": false,
- "scheduledDateOfDeletion": "12-12-2024"
}
}
Use this endpoint to upload kyc data and initiate onboarding process. After successfully importing the kyc data, it will be processed. If the data is processed successfully, you will receive a webhook notification and be able to trade. You can change the imported data via Change user kyc data endpoint.
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
salutation | string or null Optional. Salutation Mr or Ms |
firstName required | string [ 2 .. 50 ] characters First name |
lastName required | string [ 2 .. 50 ] characters Last name |
required | object Address |
mobileNumber | string or null Mobile phone number |
birthDate required | string <date-time> non-empty Required. Birth date |
birthCity required | string [ 1 .. 35 ] characters Required. Birth city |
birthCountry required | string = 2 characters Required. Birth country (ISO 3166 alpha-2 Code) |
nationality required | string = 2 characters Required. Nationality (ISO 3166 alpha-2 Code) |
maritalStatus | string or null Optional. Marital status (Divorced, Married, Single, Widowed) |
pepRelevant | boolean or null Optional. Customer is a political exposed person |
fatcaRelevant required | boolean Default "false", no customers with positive FATCA status should be imported |
fatcaCrsConfirmedAt | string or null <date-time> Required when FatcaRelevant = false. UTC Timestamp (ISO 8601 format) from when the person verified their FATCA relevance |
object or null Optional. Legitimation details | |
taxId | string or null Optional. Tax number |
taxIdCountry | string or null Optional. Tax residency country (ISO 3166 alpha-2 Code) |
amlConfirmedAt required | string <date-time> non-empty Required. Last legitimation date (ISO 8601 UTC format) on which the user last confirmed his personal KYC data. |
{- "salutation": "Mr",
- "firstName": "Max",
- "lastName": "Mustermann",
- "address": {
- "line1": "Musterstraße",
- "line2": "1",
- "postalCode": "10000",
- "city": "Berlin",
- "country": "DE",
- "state": "BE"
}, - "mobileNumber": "+4923423234",
- "birthDate": "1990-12-05",
- "birthCity": "Berlin",
- "birthCountry": "DE",
- "nationality": "DE",
- "maritalStatus": "Single",
- "pepRelevant": false,
- "fatcaRelevant": false,
- "fatcaCrsConfirmedAt": "2019-08-24T14:15:22Z",
- "legitimation": {
- "documentNumber": "L3GP1C6FF34534",
- "type": "IdCard",
- "issuer": "BA REINICKENDORF BÜRGERBÜRO RATHAUS",
- "country": "DE",
- "issuedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z"
}, - "taxId": "2454027948945",
- "taxIdCountry": "DE",
- "amlConfirmedAt": "2019-08-24T14:15:22Z"
}
{- "result": {
- "userId": "string",
- "type": "string",
- "source": "string"
}
}
Use this endpoint to modify existing kyc data that has already been imported using Import user kyc data. You can modify the data even if the kyc has not yet been processed.
In the request body, include only the fields you wish to update, omit all others. At least one field must be provided in the request body. Delete specific non user manditory fields by providing either "" for string fields, or "0001-01-01" for date fields.
Example of changing kyc data:
{
"maritalStatus": "Married",
"lastName": "Mustermann"
}
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
salutation | string or null Optional. Salutation Mr or Ms |
firstName | string or null Optional. First name |
lastName | string or null Optional. Last name |
object or null Optional. Address | |
mobileNumber | string or null Optional. Mobile phone number |
nationality | string or null Optional. Nationality (ISO 3166 alpha-2 Code) |
maritalStatus | string or null Optional. Marital status (Divorced, Married, Single, Widowed) |
pepRelevant | boolean or null Optional. Customer is a political exposed person |
object or null Optional. Legitimation details | |
taxId | string or null Optional. Tax number |
taxIdCountry | string or null Optional. Tax residency country (ISO 3166 alpha-2 Code) |
{- "salutation": "Mr - Optional",
- "firstName": "Max - Optional",
- "lastName": "Mustermann - Optional",
- "address": {
- "line1": "Musterstraße",
- "line2": "1",
- "postalCode": "10000",
- "city": "Berlin",
- "country": "DE",
- "state": "BE"
}, - "mobileNumber": "+4923423234 - Optional",
- "nationality": "DE - Optional",
- "maritalStatus": "Single - Optional",
- "pepRelevant": false,
- "legitimation": {
- "documentNumber": "L3GP1C6FF34534",
- "type": "IdCard",
- "issuer": "BA REINICKENDORF BÜRGERBÜRO RATHAUS",
- "country": "DE",
- "issuedAt": "2019-08-24T14:15:22Z",
- "validUntil": "2019-08-24T14:15:22Z"
}, - "taxId": "2454027948945 - Optional",
- "taxIdCountry": "DE - Optional"
}
{- "result": {
- "userId": "string",
- "source": "string"
}
}
This endpoint allows you to schedule a date for deleting a user by providing the desired date and an optional reason for deletion. If no date is specified, the deletion date will be set to the current day. If the endpoint is called again before the deletion date, it will update the date of deletion or the reason, if provided.
You can keep track of a user’s scheduled deletion date by calling the Get User Info endpoint.
There is a daily worker that checks if users are eligible for deletion and deletes them if they meet the criteria. To verify if a user has been deleted, call an endpoint such as the Get User Info endpoint. If the user does not exist, you will receive an error.
If a user’s account is not empty, or is faulty on the scheduled deletion day, the account will be blocked instead of deleted.
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
reason | string or null Optional. Account deletion reason |
scheduledAt | string or null <date> Optional. Scheduled date of deletion. If not provided then deletion set to today |
deletedBy | string or null Optional. Contract cancelled by Branch / Department / User |
{- "reason": "Account no longer needed",
- "scheduledAt": "2024-12-31",
- "deletedBy": "User"
}
{- "result": {
- "userId": "string",
- "scheduledDeleteAt": "2019-08-24"
}
}
Returns current bid and ask prices for all assets (instruments) in Euros. These prices are calculated for an order size of 100 euro and are for informational purposes only.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
userId | string Boerse Stuttgart Digital user identifier |
{- "result": {
- "currency": "string",
- "items": [
- {
- "assetCode": "BTC",
- "ask": 30,
- "bid": 29,
- "mid": 29.5
}
], - "quoteAt": "2019-08-24T14:15:22Z"
}
}
Returns historic mid prices for selected asset (instrument).
The range is [present - periodLenght, present]
.
assetPair required | string Example: BtcEur Asset pair for which price history will be returned |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
periodLength required | number <double> Example: periodLength=1 Time period, in days. Accepted values are:
|
{- "period": "1.00:00:00",
- "bucketSize": "00:05:00",
- "expireOn": "00:05:00",
- "items": [
- {
- "y": 0,
- "closeTime": "2019-08-24T14:15:22Z"
}
], - "eurDiff": 0,
- "percentDiff": 0
}
We offer request for quote orders and market orders.
Issuing a request for quote order involves two steps:
sequenceDiagram
autonumber
Partner Backend->>BSDigital Backend: Request a quote
BSDigital Backend->>Partner Backend: Return quote id and price
Partner Backend->>BSDigital Backend: Place an order (quote id)
BSDigital Backend->>Partner Backend: Return order Id
Some implementation details:
Market orders always execute with current market price. The exact price of the trade is only known after the trade is done.
Issuing a market order involves only a single call to 'Place an order' endpoint.
sequenceDiagram
autonumber
Partner Backend->>BSDigital Backend: Place an order (orderType=Market)
BSDigital Backend->>Partner Backend: Return order Id
Some implementation details:
Order status | Description |
---|---|
Submitted | the order has been submitted and is being processed |
Completed | the order is completed |
Revoked | the order has been revoked |
Failed | the order has failed |
The list of possible application errors and how to handle them is available at this error list. The following diagram shows how to handle most common ones.
sequenceDiagram
autonumber
Note over Partner App, Partner Backend: reference to either buy or sell process,<br/> which is the same until this point
Partner App->>Partner Backend: Place the order for the given quote ID
Partner Backend->>BSDigital Backend: Place the order <br/> POST /api/v1/partner/{partnerId}/users/{userId}/orders<br/><br/> Both order amount and fiat-amount<br/> returned by request quote must be submitted.
BSDigital Backend->>BSDigital Backend: Check order validity (See error handling for details)
BSDigital Backend->>BSDigital Backend: Check if the user has been deleted or blocked in the meantime.
alt 410 Quote expired
BSDigital Backend->>Partner Backend: Return error
Partner Backend->>Partner App: It took longer than 15 secs to<br/> place the order with the given quote ID<br/><br/> Display message that quote has expired. <br/><br/> Offer user to request a new quote<br/> with same quantities as before.<br/><br/> The process must start from the point<br/> of requesting a quote again.
else 422 Unstable market
BSDigital Backend->>Partner Backend: Return error
Partner Backend->>Partner App: The price offered by the quote<br/> and the current market price<br/> have diverged too much.<br/><br/> Display message that order cannot be executed<br/> because of volatile market.<br/><br/> Offer user to request a new quote<br/> with same quantities as before.<br/><br/> The process must start from the point<br/> of requesting a quote again.
end
If the network connection fails in the process of placing an order (regardless of buy or sell), the order might still be processed by BSDigital backend. It is best to display a message to the user "Processing of order is taking a bit longer, we will notify you when its done". If the order is an buy order, you also have to "block" euros until you are sure of the order status on BSDigital backend. To check that, you need to periodically call GetOrder using the quote id, until it either returns "not found", or returns the placed order with a status corresponding to the statuses described in the Order statuses section. Depending on the response you either return the blocked Euros to the user or not and restart the entire order process from the "request a quote" point again. The following sequence diagram show a potential flow including the endpoint for getting an order list.
sequenceDiagram
autonumber
Note over Partner App, Partner Backend: reference to either buy or sell process,<br/> which is the same until this point
Partner App->>Partner Backend: Place the order for the given quote ID
Partner Backend->>BSDigital Backend: Place the order <br/> POST /api/v1/partner/{partnerId}/users/{userId}/orders<br/><br/> Both order amount and fiat-amount<br/> returned by request quote must be submitted.
BSDigital Backend->>BSDigital Backend: Check order validity (See error handling for details)
BSDigital Backend->>BSDigital Backend: Check if the user has been deleted or blocked in the meantime.
Note over Partner Backend, BSDigital Backend: network issues at this point of time
BSDigital Backend-xPartner Backend: Connection issues or timeout
loop check order existance / api recovery
Partner Backend->>BSDigital Backend: get a the specific order by quote id<br/>/api/v1/partner/{partnerId}/users/{userId}/orders/{quoteId}<br/><br/> The orderId is the ID of the quote
alt 200 OK and order status is either 'Submitted', 'Completed' or 'Revoked'
BSDigital Backend->>Partner Backend: return the requested order
Partner Backend->>Partner Backend: Order has successfully<br/> been placed<br/>Exit loop.
else 404 and Error code 'NotFound' or status is "Failed"
BSDigital Backend->>Partner Backend: Return error
Partner Backend->>Partner Backend: No order with the<br/> given ID found.<br/>Exit loop.
else Connection issues or timeout
BSDigital Backend-xPartner Backend: Connection issues or timeout
Partner Backend->>Partner Backend: Loop until connection issues persist
end
Partner Backend->>Partner Backend: check whether order was returned
end
alt Order has successfully been placed
Partner Backend->>Partner App: Return the order
else Order has not been placed
Partner Backend->>Partner App: Order was not created.<br/> Start from the beginning with requesting a quote again<br/> and unblock user money
end
This can be used to get all available crypto assets and their configurations. The assets returned are ordered by name in ascending order.
Please note that the response of this endpoint is paged.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
limit | integer <int32> A limit on the number of objects to be returned, between 1 and 100. Default is 30. |
{- "result": {
- "items": [
- {
- "assetCode": "string",
- "name": "string",
- "decimalPrecision": 0,
- "minWithdrawalAmount": 0
}
], - "hasMore": true
}
}
This request returns a buy or sell quote for either a chosen amount of crypto or the chosen euro amount. It should be used in connection with 'Place an order' endpoint.
While executing request some specific errors can occur:
Status code | Error code | Description |
---|---|---|
400 | ValidationError | Error indicates issues with input data. Validation check valid values for asset code, side and amounts, ..etc. Details about which field is not valid and why is available inside errors array in response |
400 | RoundingError | Error indicates that input amount is not rounded properly |
403 | ActionNotAllowed | Trading is disabled for this user |
404 | NotFound | Error indicates that the given user has been blocked or deleted and the quote cannot be processed |
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
assetCode required | string non-empty Asset code |
amount | number or null <decimal> The amount of the crypto asset to request a quote for Required unless you specified fiat amount |
fiatAmount | number or null <decimal> The fiat amount to request a quote to buy or sell Required unless you specified crypto amount |
side required | string non-empty Enum: Buy or Sell. |
{- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "side": "string"
}
{- "result": {
- "quoteId": "string",
- "assetCode": "BTC",
- "amount": 0,
- "fiatAmount": 0,
- "currency": "string",
- "price": 0,
- "side": "string",
- "validUntil": "2019-08-24T14:15:22Z"
}
}
This endpoint can be used to set the commission of price improved orders.
userId required | string Boerse Stuttgart Digital user identifier |
orderId required | string Price improved order identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
commission | number <decimal> [ 0 .. 100000 ] Updated commission. Fixed fiat fee in EUR with 2 decimals |
{- "commission": 2.22
}
{- "result": {
- "orderId": "string",
- "commission": 0
}
}
Place an order request for the previously obtained quote or issue a market order.
While executing request some specific errors can occur:
Status code | Error code | Description |
---|---|---|
400 | ValidationError | Error indicates issues with request parameters please check errors array for details. |
400 | RoundingError | Error indicates that input amount is not rounded properly. Please check valid decimal places for requested asset. |
403 | ActionNotAllowed | Trading is disabled for this user. |
404 | NotFound | Error indicates that the given user has been blocked or deleted and the order can not be placed. |
410 | QuoteExpired | Error indicates that price changed too much and the quote cannot be accepted anymore. Please request a new quote. |
422 | NotEnoughAsset | Error indicates that sell order can not be executed due not enough assets on users portfolio. |
422 | UnavailableCollateral | Error indicates that the order was rejected due to insufficient collateral balance. |
422 | UnstableMarket | Error indicates that order can not be executed due unstable market, so price changes to much from quoting time. Please request new quote. |
422 | ServiceUnavailable | Error indicates that order can not be executed because one of external services was not available. Please request a new quote. If error persists for longer time period please contact BSD support. |
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
orderType | string or null Order type. Enum: Rfq or Market Defaul: Rfq |
assetCode required | string non-empty Asset code |
side required | string non-empty Enum: buy or sell. |
price | number or null <decimal> The execution price of the order. Required for a quote order and not allowed for a market order. |
amount | number or null <decimal> The amount or quantity of crypto asset to buy or sell. Required for a quote order. For Market orders you can use only Amount or FiatAmount. |
fiatAmount | number or null <decimal> The fiat amount of crypto asset to buy or sell. Required for a quote order. For Market orders you can use only Amount or FiatAmount. |
quoteId | string or null The quote identifier as received as response to quote obtained prior to the order. Required for a quote order and not allowed for a market order. |
onBehalfOf | string or null <= 100 characters Customer side identifier of user on behalf of order will be executed. |
commission | number or null <decimal> Fixed fiat fee in EUR with 2 decimals Can be different per customer once the customer is at a different bank (in our API documentation we call it "branch"). |
clientOrderId | string or null The order-id of the client for which this order will be executed. Optional in quote order and required on Market order. Maximum length is 35 character May consist of alphanumerical characters (a-z, A-Z, 0-9) and underscores (_) only |
secondaryClientOrderId | string or null A secondary / additional order-id of the client for which this order will be executed. Optional. Maximum length is 35 character May consist of alphanumerical characters (a-z, A-Z, 0-9) and underscores (_) only |
{- "orderType": "BTC",
- "assetCode": "BTC",
- "side": "Buy",
- "price": 0,
- "amount": 0,
- "fiatAmount": 0,
- "quoteId": "string",
- "onBehalfOf": "string",
- "commission": 0,
- "clientOrderId": "string",
- "secondaryClientOrderId": "string"
}
{- "result": {
- "orderId": "string",
- "clientOrderId": "string",
- "orderType": "BTC",
- "status": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
}
This can be used to query previously executed orders. The orders returned are ordered by creation time in descending order (newest are returned first). Please note that the response of this endpoint is paged.
While executing request some specific errors can occur:
Status code | Error code | Description |
---|---|---|
400 | ValidationError | Error indicates issues with request parameters please check errors array for details |
404 | NotFound | Error indicates that the given user has been blocked or deleted and orders cannot be retrieved |
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
assetCode | string Asset code |
limit | integer <int32> A limit on the number of objects to be returned, between 1 and 100. Default is 10. |
startingAfter | string A cursor for use in pagination. startingAfter is an object ID that defines your place in the list. |
endingBefore | string A cursor for use in pagination. endingBefore is an object ID that defines your place in the list. |
{- "result": {
- "items": [
- {
- "orderId": "string",
- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "price": 0,
- "side": "string",
- "status": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "onBehalfOf": "string",
- "commission": 0,
- "clientOrderId": "string",
- "secondaryClientOrderId": "string"
}
], - "hasMore": true
}
}
This endpoint returns revoked orders for all partner users in ascending order of the revocation time. Please note that the response of this endpoint is paged.
While executing this request some specific errors can occur:
Status code | Error code | Description |
---|---|---|
400 | ValidationError | Error indicates issues with request parameters please check errors array for details |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
limit | integer <int32> A limit on the number of objects to be returned, between 1 and 100. Default is 10. |
startingAfter | string A cursor for use in pagination. startingAfter is an object ID that defines your place in the list. |
endingBefore | string A cursor for use in pagination. endingBefore is an object ID that defines your place in the list. |
{- "result": {
- "items": [
- {
- "userId": "string",
- "orderId": "string",
- "revokedAt": "2019-08-24T14:15:22Z"
}
], - "hasMore": true
}
}
Fetch an order using either the default Order/Quote ID or the Client Order ID.
To use a different identifier, modify the OrderIdType parameter.
The available options for OrderIdType are:
While executing request some specific errors can occur:
Status code | Error code | Description |
---|---|---|
404 | NotFound | Error indicates that order id does was not found on server. Please check if you have valid order identifier |
404 | NotFound | Error indicates that the given user has been blocked or deleted and the order cannot be retrieved |
userId required | string Boerse Stuttgart Digital user identifier |
orderId required | string The identifier of the order to retrieve. "OrderId"(default) or "ClientOrderId" |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
orderIdType | string The type of the identifier. The given identifier can either be the default "OrderId"(Both the ID of the order or the quote may be used here) or "ClientOrderId"(Users own identifier). |
{- "result": {
- "orderId": "string",
- "orderType": "BTC",
- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "price": 0,
- "side": "string",
- "status": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "onBehalfOf": "string",
- "priceImprovementOrderId": "string",
- "stornoOrderId": "string",
- "revokedOrderId": "string",
- "commission": 0,
- "clientOrderId": "string",
- "secondaryClientOrderId": "string",
- "revocationReason": "string"
}
}
This section covers endpoints related to crypto transfers (deposits and withdrawals).
In order to get a full transaction history, you can obtain that by calling the following endpoints:
Use this endpoint to get the wallet address for crypto deposits.
userId required | string Boerse Stuttgart Digital user identifier |
assetCode required | string Asset code |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
{- "result": {
- "assetCode": "string",
- "address": "string",
- "tag": "string"
}
}
Use this endpoint to get a paginated list of all crypto deposits for a certain asset.
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
assetCode | string Asset code |
limit | integer <int32> A limit on the number of objects to be returned, between 1 and 100. Default is 10. |
startingAfter | string A cursor for use in pagination. startingAfter is an object ID that defines your place in the list. |
endingBefore | string A cursor for use in pagination. endingBefore is an object ID that defines your place in the list. |
{- "result": {
- "items": [
- {
- "depositId": "string",
- "transactionHash": "string",
- "recordedAt": "2019-08-24T14:15:22Z",
- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "fromAddress": "string",
- "fromAddressTag": "string",
- "toAddress": "string",
- "toAddressTag": "string",
- "status": "string"
}
], - "hasMore": true
}
}
Use this endpoint to get a paginated list of all crypto withdrawals for a certain asset.
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
assetCode | string Asset code |
limit | integer <int32> A limit on the number of objects to be returned, between 1 and 100. Default is 10. |
startingAfter | string A cursor for use in pagination. startingAfter is an object ID that defines your place in the list. |
endingBefore | string A cursor for use in pagination. endingBefore is an object ID that defines your place in the list. |
{- "result": {
- "items": [
- {
- "withdrawalId": "string",
- "transactionHash": "string",
- "recordedAt": "2019-08-24T14:15:22Z",
- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "fromAddress": "string",
- "fromAddressTag": "string",
- "toAddress": "string",
- "toAddressTag": "string",
- "status": "string"
}
], - "hasMore": true
}
}
Use this endpoint to create a new withdrawal for a given asset.
While executing this request some specific errors can occur:
Status code | Error code | Description |
---|---|---|
400 | RoundingError | Error indicates that input amount is not rounded properly. Please check valid decimal places for requested asset |
403 | ActionNotAllowed | Withdrawals are disabled for this user |
404 | NotFound | Error indicates that the given user has been blocked or deleted and the withdrawal cannot be processed |
422 | NotEnoughAsset | Error indicates that sell order can not be executed due not enough assets on users portfolio |
422 | InvalidWalletAddress | Error indicates that the crypto wallet address could not be validated |
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
assetCode required | string non-empty Asset code |
amount required | number <decimal> The amount or quantity of crypto asset to withdraw from the address given |
address required | string non-empty The destination address for this withdraw |
addressTag | string or null Tag of the blockchain address the withdrawal is made to A Tag/Memo is an additional address feature necessary for identifying a transaction recipient or sender beyond a wallet address. |
{- "assetCode": "string",
- "amount": 0,
- "address": "string",
- "addressTag": "string"
}
{- "result": {
- "withdrawalId": "string",
- "recordedAt": "2019-08-24T14:15:22Z",
- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "toAddress": "string",
- "toAddressTag": "string"
}
}
This allows you to get a withdrawal by using either the default Withdrawal Id or the Transaction Hash.
It can be used to check whether the transaction belonging to your account originated from BSD Broker.
To use a different identifier, modify the WithdrawalIdType parameter.
The available options for WithdrawalIdType are:
userId required | string Boerse Stuttgart Digital user identifier |
withdrawalId required | string The identifier of the withdrawal to retrieve. "WithdrawalId"(default) or "TransactionHash". |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
withdrawalIdType | string The type of the identifier. The given identifier can either be the default "WithdrawalId" or "TransactionHash". |
{- "result": {
- "withdrawalId": "string",
- "transactionHash": "string",
- "recordedAt": "2019-08-24T14:15:22Z",
- "assetCode": "string",
- "amount": 0,
- "fiatAmount": 0,
- "fromAddress": "string",
- "fromAddressTag": "string",
- "toAddress": "string",
- "toAddressTag": "string",
- "status": "string"
}
}
Use this endpoint to get whitelisted withdrawal addresses for a given asset.
userId required | string Boerse Stuttgart Digital user identifier |
assetCode required | string Asset code |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
{- "result": [
- {
- "assetCode": "string",
- "address": "string"
}
]
}
User portfolio will include all the instruments the user currently owns. It will also include the current Euro value, invested value and the current profit or loss.
For B2B partners this will return the aggregated portfolio of the partner.
userId required | string Boerse Stuttgart Digital user identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
{- "result": {
- "value": 0,
- "investedValue": 0,
- "openPLRatio": 0,
- "openPLValue": 0,
- "currency": "string",
- "instruments": [
- {
- "assetCode": "string",
- "assetClass": "string",
- "displayName": "string",
- "totalValueShare": 0,
- "investedValue": 0,
- "openPLValue": 0,
- "openPLRatio": 0,
- "value": 0,
- "volume": 0
}
]
}
}
Use this endpoint to get portfolio performance chart.
userId required | string Boerse Stuttgart Digital user identifier |
timePeriod required | string Time period for data points. Accepted values are:
|
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
{- "result": {
- "items": [
- {
- "value": 0,
- "date": "2019-08-24T14:15:22Z"
}
]
}
}
Returns the collateral balance of the given partner account.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
userId | string Boerse Stuttgart Digital user identifier |
{- "result": {
- "total": 0,
- "available": 0,
- "unsettled": 0
}
}
Webhooks are a form of server-to-server communication which send notifications as soon as specific events occur. By subscribing to webhooks, you can reduce the number of API calls that your solution makes and build your solution to react to important events in real time.
This guide explains how to subscribe to the BSD Partner-Webhooks and contains an explanation and sample payload for each webhook event.
First, your solution must expose a URL (HTTPS) where BSD can send webhook notifications to.
Then, for each event type you wish to subscribe to, you must call the POST Create a webhook subscription method. Supply the following in the request:
event_type
: The type of webhook event to subscribe to.url
: The URL to which BSD will send the webhook notification.When you register a new webhook subscription, the BSD API will check the availability of the provided URL by sending a single POST
notification. The notification does not include a body, but it includes the BSD-WEBHOOK-EVENT-TYPE
header with a value of WEBHOOK-SUBSCRIPTION
.
If your URL returns a 2XX
HTTP response code, then the BSD API will create the webhook subscription and return you a 201 Created
response. In the response body, you will find the secret
property. You must use the value of this property to verify the authenticity
of BSD webhook notifications. The API only exposes this secret once, so if you misplace it, then you must register a new webhook subscription.
Once a webhook subscription has been created, it cannot be modified. You must delete the webhook subscription and register a new one with the desired updated properties.
Implement the following HTTP response codes for the URL where your solution will receive webhook notifications:
Response Code | Reaction |
---|---|
2XX Success |
BSD will consider the notification delivered and will not retry. |
410 Gone |
BSD will mark the notification delivery as rejected and cancels the subscription on this particular URL. |
422 Unprocessable Entity |
The delivery is marked as rejected, and BSD webhook service will not re-attempt to deliver the notification. |
Any response code not listed above will place the webhook notification into a retry loop. The retry will happen up to 3 times with a delay of 2 to 8 seconds between each attempt. If the notification is still not delivered, then the webhook service will stop retrying.
A webhook notification consists of two parts:
Each webhook notification will contain the following headers:
BSD provides a signature hash in each webhook notification as the value of the BSD-Webhook-Signature header. This allows you to verify that the notification really came from BSD and protect against misuse of your webhook URL.
The webhook service generates the signature using the HMAC algorithm. It uses the secret from the webhook subscription as the HMAC key to encrypt the payload, and it encodes the digest used for the signature generation in the header. The BSD-Webhook-Subscription-Id header references the relevant secret for calculating the signature.
We recommend that you use the raw message payload to generate a signature hash to verify the one received in the header. This ensures your implementation will not break in case additional fields are introduced. Moreover, calculating on the raw message will ensure that parsing errors do not compromise your ability to verify the authenticity of your webhook traffic.
In order to explain how to verify the signature, we will use the following example, written in C#, where the secret is the one you received with the initial POST upon subscribing and the payload is the actual payload of the current request. The return value of the example method ComputeSignature is the value you have to compare against the BSD-Webhook-Signature header.
string ComputeSignature(string secret, string payload)
{
byte[] bytesSecret = Encoding.UTF8.GetBytes(secret);
using var hmac = new HMACSHA256(bytesSecret);
byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
return Hashing.HexStringFromBytes(hashBytes); // this is an internal method which is described below as well
}
string HexStringFromBytes(byte[] bytes)
{
var sb = new StringBuilder();
foreach (byte b in bytes)
{
var hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
{
"UserId": "Boerse Stuttgart Digital user identifier. This User Id is the id that you get as a response for the create user endpoint",
"KycStatus": "Confirmed"
}
Creates a new webhook subscription for a specific event. When you create a webhook subscription, we check the validity of the provided url by sending a single POST notification. The response from this endpoint contains a unique id for the subscription and a secret. Use this secret to verify the authenticity of the notifications. Webhook URLs cannot be changed after creating a webhook subscription. You must delete the existing webhook and register a new one with the new URL. Note that you will receive a new id and secret.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
url required | string non-empty Norification URL address |
eventType required | string non-empty Event type |
{- "url": "string",
- "eventType": "string"
}
{- "result": {
- "webhookSubscriptionId": "string",
- "secret": "string"
}
}
Returns current webhook subscriptions.
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
eventType | string Event type |
{- "result": {
- "items": [
]
}
}
Deletes the webhook subscription specified in the request URL. Please ensure that you have a replacement for a webhook before deleting it. All stored and unsent notifications will be lost.
webhookId required | string Webhook identifier |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
{- "result": { }
}
Use this endpoint to download partner specific files and reports.
fileName required | string file name to download |
partnerId required | string Partner identifier provided by Boerse Stuttgart Digital |
{- "code": "string",
- "message": "string",
- "errors": [
- {
- "field": "string",
- "code": "string",
- "message": "string"
}
], - "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string",
- "trace": "string",
- "property1": null,
- "property2": null
}
Use this endpoint to check if connection is working. Response code of 200 means everything is fine.
{- "code": "string",
- "message": "string",
- "errors": [
- {
- "field": "string",
- "code": "string",
- "message": "string"
}
], - "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string",
- "trace": "string",
- "property1": null,
- "property2": null
}
FIX api is offered as a complementary to the REST API. It is not meant as a complete substitute. Some of the processes, for example the on-boarding of B2B2C customers can only be done through the REST API.
It is important to review this document in line with the published FIX specification, of which this forms the part that is relevant and implemented for BSD Broker. This specification is publicly available and free, and can be obtained from www.fixprotocol.org.
Channel | Endpoint |
---|---|
Quotes | Please contact us for connection details. |
RfQ | Please contact us for connection details. |
Trading | Please contact us for connection details. |
TradeReport | Please contact us for connection details. |
BSD Broker FIX Session runs as a server. Therefore, the incoming institutions session will normally be deemed to be the client, firewalls and connectivity should be arranged accordingly.
FIX version – BSD Broker facilitates quote driven and trading and has been built around the FIX 4.4 specification, which implemented Quotes, therefore the interface does not attempt to be backwardly compatible with any previous version of the FIX specification. FIX attempts to maintain backward compatibility and therefore this specification should be compatible with 4.4 or previous versions, it is however the onus of the institutions to determine the specific compatibility.
Currently encryption is realized only on transport protocol level. On message level no encryption or signing is supported.
In case of lost messages - for example due to an unexpected connection failure - for all channels, except Quotes channel, the standard FIX-protocol synchronization is used. On Logon the client has to determine from the MsgSeqNo of the acceptor that messages are missing and send a ResendRequest(2).
For Quotes channel the initiator must reset the FIX session on every connect (restarting with message sequence number 1). To recover just resend the last Quote Request.
A FIX session in all channels except Quotes channel should not be active for longer than one week. There are two ways to archieve a frequently session reset. The first option is the default and recommended way:
An initiator should reset the session once a week in the following way:
Note: to ensure that no Execution Report message is lost on TradeReport channel, the client must ensure that during the session reset process no trade is done, neither over REST API nor over FIX API. This applies only when the TradeReport channel is used.
Both sides agree on a period of time during the week in which the session will end. Within this period both sides do the session reset independently so that after the next connect the first two (Logon) messages have sequence number one. All parameters (time and duration) are negotiable. For example: session reset should be done every saturday at 4am. The session will end at saturday 3:55am and will start at 4:05am.
Note: in both options, when a session is more than two weeks old, the acceptor may force a disconnect by sending a Logout(5) message and will reject any Logon(A) message without ResetSeqNumFlag(141)=Y with the text "FIX session has expired. Please send LOGON with ResetSeqNumFlag(141) = Y and MsgSeqNum(34) = 1." In this exceptional case, messages maybe lost if trades are done between forced logout and successful logon. These lost messages can be requested manually at our support.
Specific errors to request messages are described under the appropriate message.
If the client gets an error message (for example in the field Text(58)) "Internal server error with id ..." please provide this id when contacting the BSD support.
In general every field that expects a defined number of values is sent with an invalid value, a Reject message will be sent as response. In particular:
Tag | Field Name | Comments |
---|---|---|
115 | OnBehalfOfCompID | Trading partner ID, required in all messages from the client in the RfQ channel. |
55 | Symbol | Must be a valid trading pair. |
146 | NoRelatedSym | In the Quote Request for RfQ must be 1 as only single quote requests are supported. |
54 | Side | Only 1 = Buy or 2 = Sell are allowed. |
40 | OrdType | On RfQ channel always D = Previously quoted, on Trading channel only 1 = Market is supported. |
569 | TradeRequestType | 0 = All trades, 1 = Matched trades matching criteria provided on request. |
263 | SubscriptionRequestType | Always 0 = Snaphot. |
Example:
8=FIX.4.4 | 9=179 | 35=3 | 34=35 | 49=BSD_RFQ | 52=20240126-15:57:31.366 | 56=RFQ_CLIENT1 | 128=fb2a616d-2ec5-4144-8f09-f5883a5f677e | 45=35 | 58=Value is incorrect (out of range) for this tag | 371=115 | 372=R | 373=5 | 10=163 |
Italic tags are values of tags indicates custom extensions in the FIX.4.4 protocol.
These are the new fields defined by this API:
Tag | Field Name | Description |
---|---|---|
20020 | ExternalTraderID | Defines the external dashboard trader identifier |
20021 | RevokedOrderID | Revoked order identifier points from storno to original order |
20022 | StornoOrderID | Storno order identifier points from original order to storno order |
20023 | PriceImprovementOrderID | Price improvement order identifier points from original to new price improved order |
20024 | RevokedOrderTransactTime | Revoked order transaction time in UTC |
FIX stipulates that a certain amount of information must be passed with every message in the header, these fields are flagged as Req’d (Required / Mandatory) in the FIX specification. Also, BSD Broker requires a certain amount of information in order to correctly route the message back to the institution node. The mandatory header fields for FIX and BSDBroker are listed below:
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
8 | BeginString | Y | FIX.4.4 (Always unencrypted, must be first field in message) |
9 | BodyLength | Y | (Always unencrypted, must be second field in message) |
35 | MsgType | Y | (Always unencrypted, must be third field in message) |
34 | MsgSeqNum | Y | Integer message sequence number. |
49 | SenderCompID | Y | (Always unencrypted) |
52 | SendingTime | Y | Time of message transmission (always expressed in UTC) |
56 | TargetCompID | Y | BSD_QUOTING, BSD_TRADING, BSD_TRADEREPORT or BSD_RFQ (Always unencrypted) |
115 | OnBehalfOfCompID | N | Trading partner ID, required in all messages from the client in the Trading and RfQ channel. This is basically the userId provided during the onboarding (B2B) or the userId of the user the trade is intended for (B2B2C) |
128 | DeliverToCompID | N | Trading partner ID, required in all business messages from the server in the "Trading" and "Trade Report" channel. |
Note: The SenderCompID(49) is specified by the BSD for each institution.
Note: Please make sure to only send tags specified in this documentation and per message. All messages having other tags, will be rejected.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
10 | CheckSum | Y | (Always unencrypted, always last field in message) |
The following diagram shows the initiation of a FIX connection.
sequenceDiagram
Note over Initiator,Acceptor: Disconnected
Initiator-->>Acceptor: TCP connection
Note over Initiator,Acceptor: TCP connection is established
Initiator->>Acceptor: Logon (MsgType=A)
Acceptor->>Initiator: Logon (MsgType=A)
Note over Initiator,Acceptor: FIX connection is established
Initiator->>Acceptor: Heartbeat (MsgType=0)
Acceptor->>Initiator: Heartbeat (MsgType=0)
Sent by the client to initiate a session and by the server as an acknowledgement. Only one session may exist per connection; sending a Logon message within an established session is an error.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | A |
34 | MsgSeqNum | Y | Must be 1 in Quotes and RfQ channel. In TradeReport channel the next sequence number of the session. |
98 | EncryptMethod | Y | Always 0 (unencrypted) |
108 | HeartBtInt | Y | Must be ≤ 30 (secs). Values greater are capped at 30. Server sends Test Request if client messages are not received in approximately (HeartBtInt x 1.5) seconds. Server terminates session if client messages are not received in approximately (HeartBtInt x 2 seconds). Note same value used by both sides. |
141 | ResetSeqNumFlag | N | 'Y' for Quote and RfQ channel, 'N' for TradeReport channel, except session reset. Required from client. |
553 | Username | N | The provided clientId, you have been given during onboarding. This is the same as used for authenticate in REST API. Required from client. |
554 | Password | N | The provided clientSecret, you have been given during onboarding. This is the same as used for authenticate in REST API. Required from client. |
Examples
8=FIX.4.4 | 9=97 | 35=A | 34=1 | 49=RFQ_CLIENT1 | 52=20240126-14:24:37.319 | 56=BSD_RFQ | 98=0 | 108=30 | 141=Y | 553=test | 554=test | 10=198 |
8=FIX.4.4 | 9=73 | 35=A | 34=1 | 49=BSD_RFQ | 52=20240126-14:24:37.367 | 56=RFQ_CLIENT1 | 98=0 | 108=30 | 10=095 |
Every reject of a logon request is followed by a disconnect of the underlying TCP/IP connection. Note that if tag Username(553) is missing, the connection will be closed immediatly without sending any response.
No changes to the FIX.4.4 specification.
No changes to the FIX.4.4 specification.
No changes to the FIX.4.4 specification.
No changes to the FIX.4.4 specification.
No changes to the FIX.4.4 specification.
Both sides can initiate the end of the connection. Every connection close without the Logout handshake will be treated as abnormal closure of the session.
In case of a planned system shutdown, the service will send a News message with Urgency = Flash (1) and the constant headline "SYSTEM SHUTDOWN IN 10 MINUTES. PLEASE LOGOUT."
If a client does not logout within 10 minutes, the server will send the Logout message and close the connection even the Logout response from the client is missing.
Within these 10 minutes, a logon is not possible. Any logon request will be rejected with one of the messages "System will shutdown in XXXs." or "System is shut down.".
sequenceDiagram
Note over Initiator,Acceptor: FIX connection is established
Initiator->>Acceptor: Logout (MsgType=A)
Acceptor->>Initiator: Logout (MsgType=A)
Initiator--xAcceptor: TCP disconnect
Note over Initiator,Acceptor: FIX connection is terminated
All text is always ASCII encoded.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | B |
61 | Urgency | Y | 0 = Normal, 1 = Flash, 2 = Background |
148 | Headline | Y | Subject. |
33 | NoLinesOfText | Y | Number of lines in the message, maybe 0. |
>58 | Text | Y | One line of the message. |
Example
8=FIX.4.4 | 9=129 | 35=B | 34=2 | 49=BSD_TRADING | 52=20230823-09:55:59.786 | 56=TRADING_CLIENT1 | 33=0 | 61=1 | 148=SYSTEM SHUTDOWN IN 10 MINUTES. PLEASE LOGOUT. | 10=077 |
The quotes workflow allows to subscribe to a quote stream for all valid trading pairs.
sequenceDiagram
Initiator->>Acceptor: Quote Request (MsgType=R)
Acceptor->>Initiator: Mass Quote (MsgType=i)
Acceptor->>Initiator: Mass Quote (MsgType=i)
Acceptor->>Initiator: Mass Quote (MsgType=i)
The following FIX message types are supported in the RfQ workflow:
MsgType | Message Name | Direction* |
---|---|---|
R | QuoteRequest | O |
S | Mass Quote | I |
* I = Inbound to Client, O = Outbound from Client
Subscribe/Unsubscribe of quotes for trading pairs. Each request replaces the subscription list at the server. That means if the client wants to add a new trading pair to the subscriptions all already subscribed trading pairs must be resend in the request.
After sending the request the server will respond with one Mass Quote message containing the last known quotes from each trading pair (if available).
These prices are calculated for an order size of 100 euro and are for informational purposes only.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | R |
131 | QuoteReqID | Y | Unique identifier for this request, created by the client. |
146 | NoRelatedSym | Y | Number of related symbols (trading pairs) in request. If set to zero (0), all quotes will be unsubscribed. |
>55 | Symbol | N | Required if NoRelatedSym greater than zero. One or more valid trading pair. |
Example
8=FIX.4.4 | 9=313 | 35=R | 34=2 | 49=QUOTING_CLIENT1 | 52=20230823-10:01:19.411 | 56=BSD_QUOTING | 131=3ebb9d31-9980-4501-bbe1-8fdcc8b0003e | 146=17 | 55=BTC/EUR | 55=LTC/EUR | 55=ETH/EUR | 55=XRP/EUR | 55=BCH/EUR | 55=LINK/EUR | 55=UNI/EUR | 55=SOL/EUR | 55=ADA/EUR | 55=DOT/EUR | 55=DOGE/EUR | 55=SHIB/EUR | 55=POL/EUR | 55=ALGO/EUR | 55=SAND/EUR | 55=MANA/EUR | 55=AAVE/EUR | 10=177 |
This message will be sent on any quote change as long a subscription exists.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | i |
131 | QuoteReqID | Y | Unique identifier for this request, created by the client. |
117 | QuoteID | Y | Unique identifier of this quote message created by the server. |
296 | NoQuoteSets | Y | The number of sets of quotes in the message. |
>302 | QuoteSetID | Y | Sequential number for the Quote Set, starting with 1. |
>295 | NoQuoteEntries | Y | The number of quotes for this Symbol (55) that follow in this message. Nested Repeating Group follow |
>>299 | QuoteEntryID | Y | Uniquely identifies the quote as part of a QuoteSet. |
>>55 | Symbol | Y | A valid trading pair. |
>>132 | BidPx | N | Bid price. |
>>133 | OfferPx | N | Ask price. |
Example
8=FIX.4.4 | 9=816 | 35=i | 34=2 | 49=BSD_QUOTING | 52=20230823-10:04:57.798 | 56=QUOTING_CLIENT1 | 117=0f746bc0-d24d-456a-992d-ed0bb853aaab | 131=3ebb9d31-9980-4501-bbe1-8fdcc8b0003e | 296=1 | 302=1 | 295=17 | 299=1 | 55=BTC/EUR | 132=20000 | 133=21000 | 299=2 | 55=LTC/EUR | 132=20000 | 133=21000 | 299=3 | 55=ETH/EUR | 132=20000 | 133=21000 | 299=4 | 55=XRP/EUR | 132=20000 | 133=21000 | 299=5 | 55=BCH/EUR | 132=20000 | 133=21000 | 299=6 | 55=LINK/EUR | 132=20000 | 133=21000 | 299=7 | 55=UNI/EUR | 132=20000 | 133=21000 | 299=8 | 55=SOL/EUR | 132=20000 | 133=21000 | 299=9 | 55=ADA/EUR | 132=20000 | 133=21000 | 299=10 | 55=DOT/EUR | 132=20000 | 133=21000 | 299=11 | 55=DOGE/EUR | 132=20000 | 133=21000 | 299=12 | 55=SHIB/EUR | 132=20000 | 133=21000 | 299=13 | 55=POL/EUR | 132=20000 | 133=21000 | 299=14 | 55=ALGO/EUR | 132=20000 | 133=21000 | 299=15 | 55=SAND/EUR | 132=20000 | 133=21000 | 299=16 | 55=MANA/EUR | 132=20000 | 133=21000 | 299=17 | 55=AAVE/EUR | 132=20000 | 133=21000 | 10=056 |
The RfQ workflow allows you to request a tradeable quote. The server responds with a quote that is valid for a defined timespan. The customer can trade on this quote sending a new order single with the quote reference.
sequenceDiagram
Initiator->>Acceptor: Quote Request (MsgType=R)
alt Quote Ok
Acceptor->>Initiator: Quote (MsgType=S)
opt
Initiator->>Acceptor: New Order Single (MsgType=D)
Acceptor->>Initiator: Execution Report (MsgType=8)
end
else Quote not available
Acceptor->>Initiator: QuoteRequestReject (MsgType=AG)
end
The following FIX message types are supported in the RfQ workflow:
MsgType | Message Name | Direction* |
---|---|---|
R | QuoteRequest | O |
S | Quote | I |
AG | Quote Request Reject | I |
G | New Order Single | O |
8 | Execution Report | I |
* I = Inbound to Client, O = Outbound from Client
stateDiagram-v2
[*] --> Filled : Trade
[*] --> Rejected : Reject
Filled --> Canceled
Filled --> [*]
Rejected --> [*]
Canceled --> [*]
These are the valid values for the field OrdStatus (39) in case of OrdTyp (40) is Limit or Stop order:
Value | Name | Description |
---|---|---|
2 | Filled | The order has been completely filled. |
4 | Canceled | The order has been canceled by backoffice. |
8 | Rejected | The server failed to confirm the validity of the order and the order submission has failed. |
This request returns a buy or sell Quote (in Euro) for either a chosen amount of crypto or a chosen Euro amount. The quote price returned is the price for which cryptos will bought or sold.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | R |
131 | QuoteReqID | Y | Unique identifier for this request, created by the client. |
146 | NoRelatedSym | Y | Must be 1 as only single quote requests are supported. |
55 | Symbol | Y | A valid trading pair. |
54 | Side | Y | Only 1 = Buy or 2 = Sell are allowed. |
38 | OrderQty | N | The amount of the crypto asset to request a quote for. Required unless you specified CashOrderQty(152) (fiat amount). |
152 | CashOrderQty | N | The fiat amount to request a quote to buy or sell. Required unless you specified OrderQty(38) (crypto amount). |
Note: Only one of the fields OrderQty(38) and CashOrderQty(152) must be set. If none or both are set in a message the service will respond with a Quote Request Reject message.
Examples
8=FIX.4.4 | 9=171 | 35=R | 34=2 | 49=RFQ_CLIENT1 | 52=20240125-08:56:32.799 | 56=BSD_RFQ | 115=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 131=31a16668-f919-456d-bdab-4b83af3d7339 | 146=1 | 55=BTC/EUR | 54=1 | 38=15 | 10=106 |
8=FIX.4.4 | 9=175 | 35=R | 34=5 | 49=RFQ_CLIENT1 | 52=20240125-08:57:39.610 | 56=BSD_RFQ | 115=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 131=9ac60578-1298-4dc3-95c4-b9fb5ca6ae8d | 146=1 | 55=BTC/EUR | 54=1 | 152=40000 | 10=138 |
8=FIX.4.4 | 9=172 | 35=R | 34=7 | 49=RFQ_CLIENT1 | 52=20240125-08:58:28.736 | 56=BSD_RFQ | 115=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 131=2d0883d7-dda1-489d-bc35-0d5f0c601b16 | 146=1 | 55=BTC/EUR | 54=2 | 38=0.5 | 10=184 |
8=FIX.4.4 | 9=174 | 35=R | 34=9 | 49=RFQ_CLIENT1 | 52=20240125-08:59:25.041 | 56=BSD_RFQ | 115=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 131=2961084e-fee0-4829-abc8-7826269cbfcc | 146=1 | 55=BTC/EUR | 54=2 | 152=5000 | 10=041 |
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | S |
131 | QuoteReqID | Y | Unique identifier of the corresponding request. |
117 | QuoteID | Y | Unique identifier of this quote created by the server. Musst be passed in the New Order Single. |
537 | QuoteType | Y | Always 1 = Tradeable. |
55 | Symbol | Y | A valid trading pair. |
38 | OrderQty | Y | The value that was sent in the Quote Request. |
152 | CashOrderQty | Y | The value that was sent in the Quote Request. |
192 | OrderQty2 | Y | The corrected (rounded) quantity of the backend. This is the value for the OrderQty(38) that must be passed in the New Order Single. |
132 | BidPx | N | The bid price. Required if Side = Buy in the request. |
133 | OfferPx | N | The offer price. Required if Side = Sell in the request. |
134 | BidSize | N | The corrected fiat amount of the backend. This is the value for the CashOrderQty(152) that must be passed in the New Order Single. Required if Side = Buy in the request. |
135 | OfferSize | N | The corrected fiat amount of the backend. This is the value for the CashOrderQty(152) that must be passed in the New Order Single. Required if Side = Sell in the request. |
62 | ValidUntilTime | Y | UTCTimestamp until this quote is valid. |
Examples
8=FIX.4.4 | 9=242 | 35=S | 34=2 | 49=BSD_RFQ | 52=20240125-08:56:35.368 | 56=RFQ_CLIENT1 | 38=15 | 55=BTC/EUR | 62=20240125-08:56:49.681 | 117=78131079-ee8a-4eb1-90d9-3aec60f2aa5f | 131=31a16668-f919-456d-bdab-4b83af3d7339 | 132=37263.776961754344 | 134=49916.58 | 192=1.33954698 | 537=1 | 10=178 |
8=FIX.4.4 | 9=245 | 35=S | 34=5 | 49=BSD_RFQ | 52=20240125-08:57:39.792 | 56=RFQ_CLIENT1 | 55=BTC/EUR | 62=20240125-08:57:54.778 | 117=0f0daac5-9f4b-407c-8452-db300294f713 | 131=9ac60578-1298-4dc3-95c4-b9fb5ca6ae8d | 132=37261.354031262168 | 134=40000.0 | 152=40000 | 192=1.07349829 | 537=1 | 10=005 |
8=FIX.4.4 | 9=236 | 35=S | 34=7 | 49=BSD_RFQ | 52=20240125-08:58:28.917 | 56=RFQ_CLIENT1 | 38=0.5 | 55=BTC/EUR | 62=20240125-08:58:43.903 | 117=660c34d3-1539-4804-bff3-d273cd44f4c6 | 131=2d0883d7-dda1-489d-bc35-0d5f0c601b16 | 133=36318.544038243091 | 135=18159.27 | 192=0.5 | 537=1 | 10=220 |
8=FIX.4.4 | 9=243 | 35=S | 34=9 | 49=BSD_RFQ | 52=20240125-08:59:25.575 | 56=RFQ_CLIENT1 | 55=BTC/EUR | 62=20240125-08:59:40.560 | 117=099b665d-8d2b-4377-ac19-9add5f5ab7b5 | 131=2961084e-fee0-4829-abc8-7826269cbfcc | 133=36332.512436951857 | 135=5000.0 | 152=5000 | 192=0.13761779 | 537=1 | 10=239 |
This message is sent in case of a quote is not available.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | AG |
131 | QuoteReqID | Y | Unique identifier of the corresponding request. |
658 | QuoteRequestRejectReason | Y | 99 = Other |
146 | NoRelatedSym | Y | Always 1. |
55 | Symbol | Y | The valid trading pair of the request. |
54 | Side | Y | The value of the request. |
38 | OrderQty | N | The value of the request, if available. |
152 | CashOrderQty | N | The value of the request, if available. |
58 | Text | N | A human readable error description. |
Examples
8=FIX.4.4 | 9=196 | 35=AG | 34=3 | 49=BSD_RFQ | 52=20240126-12:44:29.876 | 56=RFQ_CLIENT1 | 58=Value -1 for OrderQty(38) is invalid. It must be positive. | 131=734194d7-0901-4bdb-8d16-703616941fc6 | 658=99 | 146=1 | 55=AAVE/EUR | 38=-1 | 10=172 |
8=FIX.4.4 | 9=208 | 35=AG | 34=5 | 49=BSD_RFQ | 52=20240126-12:45:23.493 | 56=RFQ_CLIENT1 | 58=Either field OrderQty(38) or field CashOrderQty(152) must be set. | 131=7f66b54d-923e-4f39-8013-1d037c5f681f | 658=99 | 146=1 | 55=AAVE/EUR | 38=1 | 152=2 | 10=057 |
8=FIX.4.4 | 9=195 | 35=AG | 34=5 | 49=BSD_RFQ | 52=20240126-15:42:23.264 | 56=RFQ_CLIENT1 | 58=Exchange order amount not rounded correctly | 131=553145bd-efe3-4c5d-b2dd-dd96cc69dde3 | 658=99 | 146=1 | 55=AAVE/EUR | 152=0.1234567890123 | 10=072 |
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | D |
11 | ClOrdID | Y | ID passed by the client and returned in the response Execution Report. Not processed by the server. Values defined on partner level. Maximum length is 35 character. May consist of alphanumerical characters (a-z, A-Z, 0-9) and underscores (_) only. |
526 | SecondaryClOrdID | N | Additional ID passed by the client and returned in the response Execution Report. Not processed by the server. Maximum length is 35 character. May consist of alphanumerical characters (a-z, A-Z, 0-9) and underscores (_) only. |
55 | Symbol | Y | A valid trading pair. Must match the symbol of the referenced Quote request. |
54 | Side | Y | The side of the order, must be the same value as in the Quote Request. |
60 | TransactTime | Y | Time this order request was initiated/released by the institution. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
38 | OrderQty | Y | Crypto amount of the order, must be the value of OrderQty2(192) in the Quote. |
152 | CashOrderQty | Y | Fiat amount of the order, must be the value of BidSize(134) or OfferSize(135) in the Quote. |
40 | OrdType | Y | Always D = Previously quoted. |
117 | QuoteID | Y | The QuoteID of the Quote. |
Example
8=FIX.4.4 | 9=251 | 35=D | 34=27 | 49=RFQ_CLIENT1 | 52=20240125-09:07:49.984 | 56=BSD_RFQ | 115=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 11=f85c73f5-e534-4666-bbbf-311fcceddc59 | 38=0.35 | 40=D | 54=1 | 55=BTC/EUR | 60=20240125-09:07:49.984 | 117=cb1e4280-aa16-4f5b-8086-6e15672e540b | 152=13046.11 | 10=140 |
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | 8 |
37 | OrderID | Y | Unique ID created by the server. (Always equals the QuoteID(117) of the [Quote](#quote-for-rfq-s] message). |
11 | ClOrdID | N | Unique ID created by the client in the New Order Single message. Not set in case of storno or price improvement orders. See Order revoke and price improvement process for more details. |
41 | OrigClOrdID | N | Used in storno or price improvement orders to point to the correspondending client order. See Order revoke and price improvement process for more details. |
526 | SecondaryClOrdID | N | Additional ID from the New Order Single. |
17 | ExecID | Y | Unique identifier of execution message. |
150 | ExecType | Y | One of the Valid values for ExecType(150). |
39 | OrdStatus | Y | One of the Valid values for OrdStatus(39). |
103 | OrdRejReason | N | Only available in case of OrdStatus = Rejected. One of the Order Reject Reason values for RfQ. |
55 | Symbol | Y | Valid trading pair. |
54 | Side | Y | Only 1 = Buy or 2 = Sell are allowed. |
152 | CashOrderQty | N | Required if the OrdStatus(39) is Filled. The total volume in fiat currency (EUR) of the trade. |
151 | LeavesQty | Y | Always 0. |
14 | CumQty | Y | If OrdStatus = Filled then the OrderQty of the New Order Single otherwise 0. |
6 | AvgPx | Y | If OrdStatus = Filled then the BidPx or OfferPx of the Quote otherwise 0. |
60 | TransactTime | Y | Trade execution time as recorded on server side. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
58 | Text | N | A human readable error description in case of OrdRejReason(103) = Other(99). |
20021 | RevokedOrderID | N | Revoked order identifier points from storno to original order |
20022 | StornoOrderID | N | Storno order identifier points from original order to storno order |
20023 | PriceImprovementOrderID | N | Price improvement order identifier points from original to new price improved order |
20024 | RevokedOrderTransactTime | N | Revoked order transaction time as recorded on server side. Present on storno orders. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
Example
8=FIX.4.4 | 9=294 | 35=8 | 34=27 | 49=BSD_RFQ | 52=20240125-09:07:51.843 | 56=RFQ_CLIENT1 | 6=37274.595716898540 | 11=f85c73f5-e534-4666-bbbf-311fcceddc59 | 14=0.35 | 17=c3abf36b-661f-41dd-a671-eb679a67dfa8 | 37=cb1e4280-aa16-4f5b-8086-6e15672e540b | 39=2 | 54=1 | 55=BTC/EUR | 60=20240125-09:07:51.838 | 150=F | 151=0 | 152=13046.10850091448900 | 10=115 |
Value | Name | Description |
---|---|---|
1 | Unknown Symbol | Wrong value for Symbol (55) (The symbol differs from the Quote Request, an invalid symbol will result in a reject) message. |
4 | Too late to enter | The order arrived too late at the exchange due to the ValidUntilTime (62) of the Quote. |
5 | Unknown Order | The QuoteID (37) is not known. |
6 | Duplicate Order | A order for the QuoteID (37) was already sent. |
13 | Incorrect quantity | The OrderQty (38) of the New Order Single differs from the value in Quote Request. |
99 | Other | Unexpected error occurred. |
100 | NotEnoughAsset | Error indicates that sell order can not be executed due not enough assets on users portfolio. |
101 | UnstableMarket | Error indicates that order can not be executed due unstable market, so price changes to much from quoting time. Please request new quote. |
Examples
8=FIX.4.4 | 9=223 | 35=8 | 34=3 | 49=BSD_RFQ | 52=20240125-09:26:49.447 | 56=RFQ_CLIENT1 | 6=0 | 11=dd2c4302-13f1-44db-90ab-14b1cf4fc171 | 14=0 | 17=2bc81866-7c13-4324-8f15-a1d0f47abbd5 | 37=NONE | 39=8 | 54=1 | 55=AAVE/EUR | 60=20240125-09:26:49.447 | 103=1 | 150=8 | 151=0 | 10=088 |
8=FIX.4.4 | 9=223 | 35=8 | 34=45 | 49=BSD_RFQ | 52=20240125-09:15:44.536 | 56=RFQ_CLIENT1 | 6=0 | 11=05b0bf15-366a-4d20-b838-f53d7b54eb59 | 14=0 | 17=44c5ab61-6cc1-4cc7-a83a-1971a4cf2087 | 37=NONE | 39=8 | 54=1 | 55=BTC/EUR | 60=20240125-09:15:44.535 | 103=4 | 150=8 | 151=0 | 10=037 |
8=FIX.4.4 | 9=223 | 35=8 | 34=47 | 49=BSD_RFQ | 52=20240125-09:16:26.315 | 56=RFQ_CLIENT1 | 6=0 | 11=ca2883b6-a482-4bec-a381-95534883bf92 | 14=0 | 17=7257d9cb-5d41-48cc-b3bb-3b379786471c | 37=NONE | 39=8 | 54=1 | 55=BTC/EUR | 60=20240125-09:16:26.315 | 103=5 | 150=8 | 151=0 | 10=229 |
8=FIX.4.4 | 9=223 | 35=8 | 34=35 | 49=BSD_RFQ | 52=20240125-09:11:34.567 | 56=RFQ_CLIENT1 | 6=0 | 11=80b3e0d8-bee2-40ea-ad44-0adddcac361c | 14=0 | 17=709db614-add0-451d-86a8-c395f4e98515 | 37=NONE | 39=8 | 54=1 | 55=BTC/EUR | 60=20240125-09:11:34.567 | 103=6 | 150=8 | 151=0 | 10=020 |
8=FIX.4.4 | 9=224 | 35=8 | 34=41 | 49=BSD_RFQ | 52=20240125-09:13:58.411 | 56=RFQ_CLIENT1 | 6=0 | 11=1d0f8bcd-5162-4e4e-930e-3360df593b08 | 14=0 | 17=7456c551-6319-4bdf-b16c-bdb07a77c4f4 | 37=NONE | 39=8 | 54=1 | 55=BTC/EUR | 60=20240125-09:13:58.411 | 103=13 | 150=8 | 151=0 | 10=086 |
The following FIX message types are supported in the trading workflow:
MsgType | Message Name | Direction* |
---|---|---|
D | New Order Single | O |
8 | Execution Report | I |
* I = Inbound to Client, O = Outbound from Client
The following sequence diagram shows a short message flow for a successfully executed order that was filled.
sequenceDiagram
Initiator->>Acceptor: New Order Single (D)
Acceptor->>Initiator: Execution Report (8) OrdStatus=PendingNew
Acceptor->>Initiator: Execution Report (8) OrdStatus=New
Acceptor->>Initiator: Execution Report (8) OrdStatus=Filled
stateDiagram-v2
[*] --> PendingNew
[*] --> Rejected
PendingNew --> Filled : Trade
PendingNew --> New
PendingNew --> Rejected
New --> Filled : Trade
Filled --> [*]
Rejected --> [*]
A New Order Single message is used by the client to place a market order.
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | D |
11 | ClOrdID | Y | Unique identifier created by the client. Maximum length is 35 character. May consist of alphanumerical characters (a-z, A-Z, 0-9) and underscores (_) only. |
55 | Symbol | Y | A valid trading pair. |
54 | Side | Y | Only 1 = Buy or 2 = Sell are allowed. |
60 | TransactTime | Y | Time this order request was initiated/released by the institution. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
38 | OrderQty | N | Quantity for the quote. Exact one of the tags OrderQty(38) or CashOrderQty(152) must be specified. |
152 | CashOrderQty | N | Fiat amount of the order. Exact one of the tags OrderQty(38) or CashOrderQty(152) must be specified. |
40 | OrdType | Y | Currently only 1 = Market is supported. |
Please make sure to also include the necessary header fields. Specifically the OnBehalfOfCompID needs to be taken into consideration. The response to this message will be an execution report with the appropriate status (normally PendingNew).
Example
8=FIX.4.4 | 9=209 | 35=D | 34=2 | 49=TRADING_CLIENT1 | 52=20240829-09:29:52.103437 | 56=BSD_TRADING | 115=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 11=3d8cab81-d571-41a3-afdb-ecf02a85dec1 | 38=0.0001 | 40=1 | 54=1 | 55=BTC/EUR | 60=20240829-09:29:52.101 | 10=101 |
The Execution Report (8) message is used to:
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | 8 |
37 | OrderID | Y | Required to be unique for each chain of orders. If OrdStatus(39) = Pending New(A) OrderID has value 'NONE'. |
11 | ClOrdID | N | Unique ID created by the client in the New Order Single message. Not set in case of storno or price improvement orders. See Order revoke and price improvement process for more details. |
41 | OrigClOrdID | N | Used in storno or price improvement orders to point to the correspondending client order. See Order revoke and price improvement process for more details. |
17 | ExecID | Y | Unique identifier for this message, created by the server (trade identifier). |
150 | ExecType | Y | One of the Valid values for ExecType(150). |
39 | OrdStatus | Y | One of the Valid values for OrdStatus(39). |
103 | OrdRejReason | N | Only available in case of OrdStatus = Rejected. One of the Order Reject Reason values for Trading. |
55 | Symbol | Y | Valid trading pair. |
54 | Side | Y | Only 1 = Buy or 2 = Sell are allowed. |
152 | CashOrderQty | N | Required if the OrdStatus(39) is Filled. The total volume in Fiat currency (EUR) of the trade. |
40 | OrdType | N | Currently only 1 = Market is supported. |
151 | LeavesQty | Y | Always 0. |
14 | CumQty | Y | If OrdStatus = Filled then the OrderQty of the New Order Single otherwise 0. |
6 | AvgPx | Y | Calculated average price of all fills on this order. |
60 | TransactTime | N | Trade execution time as recorded on server side. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000). Required if OrdStatus(39) is Filled(2) |
58 | Text | N | May contain additional information about the reason for rejected orders in case of OrdRejReason(103) = Other(99). |
20021 | RevokedOrderID | N | Revoked order identifier points from storno to original order |
20022 | StornoOrderID | N | Storno order identifier points from original order to storno order |
20023 | PriceImprovementOrderID | N | Price improvement order identifier points from original to new price improved order |
20024 | RevokedOrderTransactTime | N | Revoked order transaction time as recorded on server side. Present on storno orders. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
Examples
8=FIX.4.4 | 9=248 | 35=8 | 34=2 | 49=BSD_TRADING | 52=20240829-09:29:55.518387 | 56=TRADING_CLIENT1 | 128=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 6=0 | 11=3d8cab81-d571-41a3-afdb-ecf02a85dec1 | 14=0 | 17=4bc107d3-e5b2-4faa-8e39-e54a7b8ce1c2 | 37=NONE | 39=A | 40=1 | 54=1 | 55=BTC/EUR | 150=A | 151=0 | 10=197 |
8=FIX.4.4 | 9=335 | 35=8 | 34=3 | 49=BSD_TRADING | 52=20240829-09:29:58.781166 | 56=TRADING_CLIENT1 | 128=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 6=54558.574670600000 | 11=3d8cab81-d571-41a3-afdb-ecf02a85dec1 | 14=0.0001 | 17=f3aff439-302b-4789-8be9-60e9bb7cef19 | 37=f7871e63c2004ad28c0279298a580c11ord | 39=2 | 40=1 | 54=1 | 55=BTC/EUR | 60=20240829-09:29:57.309 | 150=F | 151=0 | 152=5.46 | 10=115 |
Value | Name | Description |
---|---|---|
99 | Other | Unexpected error occurred. |
100 | NotEnoughAsset | Error indicates that sell order can not be executed due not enough assets on users portfolio. |
Example
8=FIX.4.4 | 9=282 | 35=8 | 34=17 | 49=BSD_TRADING | 52=20240829-09:36:09.617152 | 56=TRADING_CLIENT1 | 128=fb2a616d-2ec5-4144-8f09-f5883a5f677d | 6=0 | 11=3d8cab81-d571-41a3-afdb-ecf02a85dec1 | 14=0 | 17=80bee0d6-1f53-4ef0-afb7-40b380173cb5 | 37=NONE | 39=8 | 40=1 | 54=2 | 55=SOL/EUR | 60=20240829-09:36:09.615 | 103=100 | 150=8 | 151=0 | 10=209 |
The TradeReport channel offers a stream of Execution Report(8) messages regardless whether the trades are done with the REST or the FIX API. In this channel FIX message synchronization and recovery are supported. This will ensure that the client will receive messages for all trades regardless whether the client is connected or not.
This channel is only available on explicit request by a customer.
sequenceDiagram
Initiator->>Acceptor: Logon (MsgType=A)
Acceptor->>Initiator: Logon (MsgType=A)
Acceptor->>Initiator: Execution Report (MsgType=8)
Acceptor->>Initiator: Execution Report (MsgType=8)
Acceptor->>Initiator: Execution Report (MsgType=8)
The following FIX message types are supported in the RfQ workflow:
MsgType | Message Name | Direction* |
---|---|---|
8 | Execution Report(8) | I |
* I = Inbound to Client, O = Outbound from Client
Tag | Field Name | Mandatory | Comments |
---|---|---|---|
35 | MsgType | Y | 8 |
37 | OrderID | Y | Unique ID created by the server. (Always equals the QuoteID(117) of the [Quote](#quote-for-rfq-s] message). |
11 | ClOrdID | N | ID from the New Order Single. If the trade was done by REST API this field will be omitted. |
526 | SecondaryClOrdID | N | Additional ID from the New Order Single or REST API. Values defined on partner level. |
17 | ExecID | Y | Unique identifier of execution message. |
150 | ExecType | Y | One of the Valid values for ExecType(150). |
39 | OrdStatus | Y | One of the Valid values for OrdStatus(39). |
55 | Symbol | Y | Valid trading pair. |
54 | Side | Y | Only 1 = Buy or 2 = Sell are allowed. |
152 | CashOrderQty | Y | The total volume in fiat currency (EUR) of the trade. |
151 | LeavesQty | Y | Always 0. |
14 | CumQty | Y | The OrderQty of the New Order Single or the amount of the "Request a quote" REST request. |
6 | AvgPx | Y | The BidPx or OfferPx of the Quote or the price of the "Request a quote" response. |
60 | TransactTime | Y | Trade execution time as recorded on server side. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
20020 | ExternalTraderID | N | External trader identifier - present when entered field OnBehalfOf on REST API |
20021 | RevokedOrderID | N | Revoked order identifier points from storno to original order |
20022 | StornoOrderID | N | Storno order identifier points from original order to storno order |
20023 | PriceImprovementOrderID | N | Price improvement order identifier points from original to new price improved order |
20024 | RevokedOrderTransactTime | N | Revoked order transaction time as recorded on server side. Present on storno orders. The resolution should be 1 microsecond. The expected field format is YYYYMMDD-HH:MM:SS.ssssss (e.g., 20221124-20:59:47.480000) |
Note if the trade was done over the FIX API and the client uses both channels (RfQ and TradeReport) the Execution Report is sent twice. The two messages differs only in the fields BodyLength(9), MsgSeqNum(34), SenderCompID(49), SendingTime(52), TargetCompID(56), ExecID(17), DeliverToCompID(128) and CheckSum(10). The field DeliverToCompID is only available in the Trade Report channel.
Examples
8=FIX.4.4 | 9=290 | 35=8 | 34=3 | 49=BSD_TRADEREPORT | 52=20240301-09:50:33.139 | 56=TRADEREPORT_CLIENT1 | 128=d60e79cc-00a1-4037-a53b-60d047ea0c60 | 6=0.635301353186 | 14=0.75 | 17=31d0fd03-7eb5-468a-b826-47ee7448d3b0 | 37=1287fed2-c530-4e32-9a14-bf668dafddc0 | 39=2 | 54=1 | 55=ADA/EUR | 60=20240301-09:50:33.134 | 150=F | 151=0 | 152=0.48 | 20020=trader1 | 10=005 |
8=FIX.4.4 | 9=291 | 35=8 | 34=10 | 49=BSD_TRADEREPORT | 52=20240301-09:52:12.906 | 56=TRADEREPORT_CLIENT1 | 128=111e543e-0be7-4a72-ac24-26ecb6bf9260 | 6=7.699824667800 | 14=1.7 | 17=2667979e-3154-47bb-af82-1c282ed28785 | 37=a481558e-7344-4a81-baa6-a1d319acc909 | 39=2 | 54=2 | 55=DOT/EUR | 60=20240301-09:52:12.906 | 150=F | 151=0 | 152=13.08 | 20020=trader1 | 10=164 |
Revoke is initiated manually from back office dashboard. New storno order with same amounts but reverse side is created and then two execution reports are sent to the client, one for original order, and one for new storno order.
sequenceDiagram
box Client
participant I_RfQ as Initiator (RfQ|Trading)
end
box BS Digital Broker
participant A_RfQ as Acceptor (RfQ|Trading)
participant Backend
actor Backoffice as Back office
end
I_RfQ->>A_RfQ: New Order Single (MsgType=D)
A_RfQ->>Backend: Process
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=F|OrdStatus=2)
Backoffice->>Backend: Revoke order process
Backend->>A_RfQ: Revoke message
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=H|OrdStatus=4) - original order
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=H|OrdStatus=2) - storno order
sequenceDiagram
box Client
participant I_RfQ as REST-Client
participant I_TR as Initiator (Trade Report)
end
box BS Digital Broker
participant A_RfQ as REST-Service
participant A_TR as Acceptor (Trade Report)
participant Backend
actor Backoffice as Back office
end
I_RfQ->>A_RfQ: PlaceOrder Request
A_RfQ->>Backend: Process
Backend->>A_TR: Trade message
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=F|OrdStatus=2)
A_RfQ->>I_RfQ: PlaceOrder Response
Backoffice->>Backend: Revoke order process
Backend->>A_TR: Revoke message
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=H|OrdStatus=4) - original order
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=H|OrdStatus=2) - storno order
Note: Revoke messages over webhooks are ommitted, because here is the focus on FIX messages.
Example Buy trade with OrderID=123 was revoked. Then these two execution reports are sent (in table are represented only the most important fields for this case)
OrderID | ExecType | OrdStatus | Side | RevokedOrderID | StornoOrderID | RevokedOrderTransactTime | ClOrdID | OrigClOrdID | Comments |
---|---|---|---|---|---|---|---|---|---|
123 | H (Trade Cancel) | 4 (Canceled) | Buy | 124 | From New Order Single | Field not available | Trade report for original order | ||
124 | H (Trade Cancel) | 2 (Filled) | Sell | 123 | 20240624-20:59:47.480000 | Field not available | From New Order Single | Trade report for storno order |
Price improvement is initiated manually from back office dashboard. Two new orders are created. First one is storno order with same amounts and second is same side as original order with changed price. Then three execution reports are sent to the client, one for original order, one for storno order and one for new price improvement order.
sequenceDiagram
box Client
participant I_RfQ as Initiator (RfQ|Trading)
end
box BS Digital Broker
participant A_RfQ as Acceptor (RfQ|Trading)
participant Backend
actor Backoffice as Back office
end
I_RfQ->>A_RfQ: New Order Single (MsgType=D)
A_RfQ->>Backend: Process
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=F|OrdStatus=2)
Backoffice->>Backend: Price improvement order process
Backend->>A_RfQ: Price improvement message
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=G|OrdStatus=4) - original order
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=G|OrdStatus=2) - new storno order
A_RfQ->>I_RfQ: Execution Report (MsgType=8|ExecType=G|OrdStatus=2) - new order with new price
sequenceDiagram
box Client
participant I_RfQ as REST-Client
participant I_TR as Initiator (Trade Report)
end
box BS Digital Broker
participant A_RfQ as REST-Service
participant A_TR as Acceptor (Trade Report)
participant Backend
actor Backoffice as Back office
end
I_RfQ->>A_RfQ: PlaceOrder-Request
A_RfQ->>Backend: Process
Backend->>A_TR: Trade message
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=F|OrdStatus=2)
A_RfQ->>I_RfQ: PlaceOrder-Response
Backoffice->>Backend: Price improvement order process
Backend->>A_TR: Price improvement message
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=G|OrdStatus=4) - original order
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=G|OrdStatus=2) - new storno order
A_TR->>I_TR: Execution Report (MsgType=8|ExecType=G|OrdStatus=2) - new order with new price
Note: Price-improvement messages over webhooks are ommitted, because here is the focus on FIX messages.
Example Buy trade for OrderID=123 will have an improved price. Then these three execution reports are sent (in table are represented only the most important fields for this case)
OrderID | ExecType | OrdStatus | Side | RevokedOrderID | StornoOrderID | PriceImprovementOrderID | RevokedOrderTransactTime | ClOrdID | OrigClOrdID | Comments |
---|---|---|---|---|---|---|---|---|---|---|
123 | G (Trade Correct) | 4 (Canceled) | Buy | 124 | 125 | From New Order Single | Field not available | Trade report for original order | ||
124 | G (Trade Correct) | 2 (Filled) | Sell | 123 | 125 | 20240624-20:59:47.480000 | Field not available | From New Order Single | Trade report for storno order | |
125 | G (Trade Correct) | 2 (Filled) | Buy | 123 | 124 | 20240624-20:59:47.480000 | Field not available | From New Order Single | Trade report for price improved order |
Type | Message | Originator |
---|---|---|
A | Logon | Both |
0 | Heartbeat | Both |
1 | Test Request | Both |
3 | Reject | Both |
5 | Logout | Both |
B | News | Server |
j | Business Message Reject | Server |
Note: These messages are used on all channels.
Type | Message | Possible Response Messages | Quote | RfQ | TradeReport | Trading |
---|---|---|---|---|---|---|
R | Quote Request/ for RfQ |
Mass Quote (i) Quote (S) Quote Request Reject |
X | X | - | - |
D | New Order Single for RfQ | Execution Report for RfQ | - | X | - | X |
Note: The Reject (3) or Business Message Reject (j) messages are possible responses for all messages.
Type | Message | In Response To | Quote | RfQ | TradeReport | Trading |
---|---|---|---|---|---|---|
8 | Execution Report for RfQ/ for TradeReport |
New Order Single for RfQ/ Logon |
- | X | X | X |
i | Mass Quote | Quote Request | X | - | - | - |
S | Quote | Quote Request for RfQ | - | X | - | - |
Z | Quote Request Reject | Quote Request for RfQ | - | X | - | - |
B | News | X | X | X | X |
Valid trading pairs are (field Symbol (55)). Trading pairs are case sensitive!
Value | Name | Description |
---|---|---|
0 | New | The server has confirmed that the order is valid. The order has been successfully entered into the server's order management system. This order status may be skipped. This status applies to stop orders when they have been triggered and are working. The server may not send a message for the "New" order state. If the order can be filled immediately, the server may skip the "New" message and send only a "Trade"/"Rejected" Execution Report message to indicate a fill. |
2 | Filled | The order has been completely filled. |
4 | Canceled | Only used in Revoke and Price improvement process. |
8 | Rejected | The server failed to confirm the validity of the order and the order submission has failed. |
A | Pending New | An order has been received by server and is being processed. This is the acknowledgement to a New Order Single request. |
Value | Name | Description |
---|---|---|
0 | New | The server has confirmed that the order is valid. The order has been successfully entered into the server's order management system. This order status may be skipped. This status applies to stop orders when they have been triggered and are working. The server may not send a message for the "New" order state. If the order can be filled immediately, the server may skip the "New" message and send only a "Trade"/"Rejected" Execution Report message to indicate a fill. |
8 | Rejected | Response to a New Order Single(D) request that could not be fullfilled. |
A | Pending New | An order has been received by server and is being processed. This is the acknowledgement to a New Order Single request. |
F | Trade | Response to a New Order Single(D) request that was successfully executed and fully filled. |
G | Trade Correct | Only used in Price Improvement Process. |
H | Trade Cancel | Only used in Revoke Process. |
When using Quickfix as client library, the following configuration can be used to connect to prelive (assuming the clientId is <myclientId>):
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=20
FileStorePath=store
FileLogPath=log
StartTime=00:00:00
EndTime=00:00:00
UseDataDictionary=Y
LogoutTimeout=5
TimeStampPrecision=Microsecond
[SESSION]
BeginString=FIX.4.4
DataDictionary=FIX44_Quoting.xml
SocketConnectHost=<quoting-url> (please contact us)
SocketConnectPort=7200
SenderCompID=QUOTING_<myclientId>
TargetCompID=BSD_QUOTING
HeartBtInt=30
SSLEnable=Y
SSLValidateCertificates=N
ResetOnLogon=Y
ResetOnDisconnect=Y
[SESSION]
BeginString=FIX.4.4
DataDictionary=FIX44_RfQ.xml
SocketConnectHost=<rfq-url> (please contact us)
SocketConnectPort=7201
SenderCompID=RFQ_<myclientId>
TargetCompID=BSD_RFQ
HeartBtInt=30
SSLEnable=Y
SSLValidateCertificates=N
ResetOnLogon=N
ResetOnDisconnect=N
[SESSION]
BeginString=FIX.4.4
DataDictionary=FIX44_Trading.xml
SocketConnectHost=<trading-url> (please contact us)
SocketConnectPort=7203
SenderCompID=TRADING_<myclientId>
TargetCompID=BSD_TRADING
HeartBtInt=30
SSLEnable=Y
SSLValidateCertificates=N
ResetOnLogon=N
ResetOnDisconnect=N
[SESSION]
BeginString=FIX.4.4
DataDictionary=FIX44_TradeReport.xml
SocketConnectHost=<tradereport-url> (please contact us)
SocketConnectPort=7202
SenderCompID=TRADEREPORT_<myclientId>
TargetCompID=BSD_TRADEREPORT
HeartBtInt=30
SSLEnable=Y
SSLValidateCertificates=N
ResetOnLogon=N
ResetOnDisconnect=N
Note: the referred data dictionaries "FIX44_RfQ.xml", "FIX44_Quoting.xml", "FIX44_TradeReport.xml", "FIX44_Trading.xml" are adapted versions of the original FIX44.xml shipped with the quickfixn libraries containing the exact message definitions defined in this API. Please contact us, if you want to use these files. Otherwise you can also disable validation by setting "UseDataDictionary=N".