Introduction
Welcome to the STS Digital API documentation.
The purpose of this document is to provide information regarding the supported/expected message types when communicating with the STS Digital API.
This document is arranged in three main sections:
Authentication
REST
FIX 4.4
Notice
This API is subject to change. Any changes will be communicated clearly and in good time.
API Access Checklist
| Key | Value/Description |
|---|---|
baseAuthUrl |
https://stsdigital.eu.auth0.com |
audience |
Always "https://api.stsdigital.net" |
client_id |
Provided directly by STS Digital (Used as Username in FIX Logon) |
client_secret |
Provided directly by STS Digital |
baseUrl |
https://tokyo.stsdigital.net |
account |
The trading account ID. Provided directly by STS Digital |
SocketConnectHost |
fix.stsdigital.net |
SocketConnectPort |
Provided directly by STS Digital |
SenderCompID |
Provided directly by STS Digital (When sending messages to the FIX API, this should be the provided client ID) |
TargetCompID |
STS (When sending messages to the FIX API, this should be "STS". Messages from STS will invert this) |
Supported Symbols |
Provided directly by STS Digital |
Notes: * If a customer wants to operate multiple FIX sessions (e.g., for separate market data and orders), more information is required.
Authentication
curl --request POST \
--url https://stsdigital.eu.auth0.com/oauth/token \
--header 'content-type: application/json' \
--data '{"client_id":"{client_id}","client_secret":"{client_secret}","audience":"{audience}","grant_type":"client_credentials"}'
Example Response:
{
"access_token": "eyJhbGci…04Uv7sTg",
"scope": "oms:read fix:trade fix:market-data accounts:read",
"expires_in": 3600,
"token_type": "Bearer"
}
We use Auth0 as our authentication provider.
The base authentication URL for production is: https://stsdigital.eu.auth0.com.
To call any endpoint, or to create a FIX session, an access token is required. The access token is retrieved via a POST request. The access token has a lifetime of 60 minutes and should be cached and re-used during its lifetime, rather than re-requested on every request.
For REST calls, the access token is included as an authorization header. For FIX, the access token is used as the Password in the Logon message.
The "scopes" within the token determine what the token can be used for.
The base URL for production is: https://tokyo.stsdigital.net. Each request requires an access token as an authorization header. The details for obtaining an access token can be found in the Authentication section above. The authorization header format is: Authorization: Bearer {access_token}.
Where REST calls relate to FIX messages (e.g., GET orders/trades), the REST response will generally use the FIX tag names (e.g., orderQty, lastQty). Where the REST response uses a FIX enum (e.g., ordType), a "Text" field is included for convenience (e.g., ordTypeText). Be aware these Text fields may be removed in the future. The FIX enum values used are the default FIX 4.4 enum values.
POST {baseAuthUrl}/oauth/token
This endpoint is used to obtain an access token.
Parameters (Body):
| Parameter | Description |
|---|---|
client_id |
A client ID provided by STS Digital |
client_secret |
A client secret provided by STS Digital |
audience |
Always "https://api.stsdigital.net" |
grant_type |
Always "client_credentials" |
Rest Endpoints
GET {baseUrl}/v1alpha/accounts
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/accounts \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example Response: Array
<Account>
[
{
"accountId": "00000000-0000-0000-0000-000000000000",
"balances": [
{
"asset": "USDT",
"available": 100.0,
"locked": 0.0,
"total": 100.0
},
{
"asset": "STS",
"available": 500.00,
"locked": 0.0,
"total": 500.00
}
]
}
]
Gets a list of all accounts, including balances. The response will contain all accounts your token has access to.
Parameters:
N/A: No parameters for this endpoint
GET {baseUrl}/v1alpha/orders
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/orders?account=00000000-0000-0000-0000-000000000000 \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example Response: Array
<Order>
[
{
"orderID": "f4a0af11-7d12-4ac6-8e7d-e4bb13fe31cf",
"clOrdID": "2f3d2089-fff1-4675-a94f-29dbba3ffb36",
"exDestination": "sts",
"account": "00000000-0000-0000-0000-000000000000",
"side": "1",
"sideText": "Buy",
"ordType": "2",
"ordTypeText": "Limit",
"timeInForce": "4",
"timeInForceText": "Fill or Kill (FOK)",
"symbol": "STS-USDT",
"orderQty": 100.0,
"price": 0.12345,
"ordStatus": "8",
"ordStatusText": "Rejected",
"leavesQty": 100.0,
"cumQty": 0.0,
"avgPx": 0.0,
"ordRejReason": "99",
"ordRejReasonText": "Other",
"text": "Unable to fill order as there are no orders at this price.",
"createdTime": "2023-07-21T14:35:19.431",
"updatedTime": "2023-07-21T14:35:20.768127"
},
{
"orderID": "001b1a8a-27ce-4995-a0fe-fedec5b4f6c3",
"clOrdID": "5f3e3a67-ecba-444a-9b83-7c75100cbdac",
"exDestination": "sts",
"account": "00000000-0000-0000-0000-000000000000",
"side": "1",
"sideText": "Buy",
"ordType": "2",
"ordTypeText": "Limit",
"timeInForce": "4",
"timeInForceText": "Fill or Kill (FOK)",
"symbol": "STS-USDT",
"orderQty": 100.0,
"price": 1.2345,
"ordStatus": "2",
"ordStatusText": "Filled",
"leavesQty": 0.0,
"cumQty": 100.0,
"avgPx": 0.99999,
"ordRejReason": null,
"ordRejReasonText": null,
"text": null,
"createdTime": "2023-07-21T14:00:27.926",
"updatedTime": "2023-07-21T14:00:29.102674"
}
]
Gets a list of all orders (max 1,000 orders per response, default 100) ordered by timestamp descending. Use the optional parameter "before" to get orders before a specified UTC date time.
Parameters (Query String):
| Parameter | Description | Required | Default | Max |
|---|---|---|---|---|
| account | The account to retrieve the orders from | Yes | ||
| clOrdID | The client order ID provided when sending an order | Optional | ||
| orderID | The STS Digital order ID | Optional | ||
| before | UTC datetime | Optional | ||
| limit | Integer number of orders to return | Optional | 100 | 1,000 |
| onlyOpen | Boolean - if true, only open orders are returned | Optional | false |
GET {baseUrl}/v1alpha/trades
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/trades?account=00000000-0000-0000-0000-000000000000 \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example Response: Array
<Trades>
[
{
"execID": "aff7ecc2-9ade-4362-8619-87d676d20e56",
"orderID": "19f5dbd1-ce52-4cef-987e-de8f2ad96925",
"clOrdID": "4aac4218-4f59-41c9-872f-9bd3d004811e",
"exDestination": "sts",
"account": " 00000000-0000-0000-0000-000000000000",
"side": "1",
"sideText": "Buy",
"ordType": "2",
"ordTypeText": "Limit",
"timeInForce": "4",
"timeInForceText": "Fill or Kill (FOK)",
"symbol": "STS-USDT",
"orderQty": 100.0,
"price": 1.2345,
"lastQty": 100.0,
"lastPx": 0.99999,
"transactTime": "2023-07-21T14:32:18.816"
},
{
"execID": "656a8092-227b-4d6c-ac78-2eb207a85447",
"orderID": "6e733684-aa3c-4183-a52e-b686ebd65cda",
"clOrdID": "e16ec983-5098-4783-b921-f841865a9d75",
"exDestination": "sts",
"account": "00000000-0000-0000-0000-000000000000",
"side": "2",
"sideText": "Sell",
"ordType": "2",
"ordTypeText": "Limit",
"timeInForce": "4",
"timeInForceText": "Fill or Kill (FOK)",
"symbol": "STS-USDT",
"orderQty": 100.0,
"price": 0.987,
"lastQty": 100.0,
"lastPx": 1.00002,
"transactTime": "2023-07-21T14:24:24.611"
}
]
Gets a list of all trades (max 1,000 trades per response, default 100) ordered by timestamp descending. Use the optional parameter "before" to get trades before a specified UTC date time.
Parameters (Query String):
| Parameter | Description | Required | Default | Max |
|---|---|---|---|---|
| account | The account to retrieve the trades from | Yes | ||
| clOrdID | The client order ID provided when sending an order | Optional | ||
| orderID | The STS Digital order ID | Optional | ||
| before | UTC datetime | Optional | ||
| limit | Integer number of trades to return | Optional | 100 | 1,000 |
GET {baseUrl}/v1alpha/instruments
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/instruments?venue=sts&type=spot \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example Response: Array
<Instrument>
[
{
"instrumentId": 16441383,
"venue": "sts",
"type": "spot",
"normalizedInstrumentCode": "ETH-USDT",
"instrumentCode": "ETH-USDT",
"baseCurrency": "ETH",
"quoteCurrency": "USDT",
"priceTickSize": 0.1,
"orderTickSize": 0.1,
"pricePrecision": 15,
"quantityPrecision": 15,
"state": "active",
"signature": 943204159
},
{
"instrumentId": 16442085,
"venue": "sts",
"type": "spot",
"normalizedInstrumentCode": "SOL-USDT",
"instrumentCode": "SOL-USDT",
"baseCurrency": "SOL",
"quoteCurrency": "USDT",
"priceTickSize": 0.01,
"orderTickSize": 0.01,
"pricePrecision": 14,
"quantityPrecision": 14,
"state": "active",
"signature": 1821854710
}
]
Gets a list of all instruments with their trading parameters. Supported instrument types include spot, option, and future.
Parameters (Query String):
| Parameter | Description | Required |
|---|---|---|
| venue | The venue to retrieve the instruments from ('sts' only) | Yes |
| type | The instrument type (e.g., spot, option, future) | Optional |
GET {baseUrl}/v1alpha/transfers
Example cURL Request: (without account id)
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/transfers \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example cURL Request: (with account id)
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/transfers?accountId=00000000-0000-0000-0000-000000000000 \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example Response: Array
<CustomerPaymentStatusReportV14>
[
{
"grpHdr": {
"msgId": "faf7750f-6531-410d-b3e8-22d599180cf2",
"creDtTm": "2024-09-05T11:42:30.9692342Z"
},
"orgnlGrpInfAndSts": {
"orgnlMsgId": "92cd2a57-7c2d-49e1-95d0-19032b34f8ae",
"orgnlCreDtTm": "2024-09-05T11:42:30",
"stsRsnInf": [
{
"orgtr": {
"nm": "test@stsdigital.io"
}
}
]
},
"orgnlPmtInfAndSts": [
{
"orgnlPmtInfId": "105aa8b6-caa5-4744-bc4b-11e127466c1c",
"orgnlNbOfTxs": "1",
"txInfAndSts": [
{
"txSts": "ACCC",
"stsRsnInf": [
{
"rsn": {
"item": "BOOKED"
}
}
],
"chrgsInf": [
{
"amt": {}
}
],
"trckrData": {
"confdAmt": {
"ccy": "usdt"
}
},
"orgnlTxRef": {
"amt": {
"item": {
"amt": {
"value": 10
}
}
},
"dbtr": {
"item": {
"nm": "sts:Test Source Account"
}
},
"dbtrAcct": {
"id": {
"item": "00000000-0000-0000-0000-000000000000"
},
"ccy": "usdt"
},
"cdtr": {
"item": {
"nm": "sts:Test Destination Account"
}
},
"cdtrAcct": {
"id": {
"item": "00000000-0000-0000-0000-000000000000"
}
}
},
"splmtryData": [
{
"plcAndNm": "demo transfer internally"
}
]
}
]
}
]
},
{
"grpHdr": {
"msgId": "073394b3-a3c4-45c2-8f9d-13dc2ed8e644",
"creDtTm": "2024-09-05T11:41:02.3433698Z"
},
"orgnlGrpInfAndSts": {
"orgnlMsgId": "75f4c055-e7ca-4246-998c-0c83948e9006",
"orgnlCreDtTm": "2024-09-05T11:41:01",
"stsRsnInf": [
{
"orgtr": {
"nm": "test@stsdigital.io"
}
}
]
},
"orgnlPmtInfAndSts": [
{
"orgnlPmtInfId": "b6535335-57c1-4120-8ce2-2a044fdfd2a2",
"orgnlNbOfTxs": "1",
"txInfAndSts": [
{
"txSts": "RJCT",
"stsRsnInf": [
{
"rsn": {
"item": "FAILED-TIMEOUT"
}
}
],
"chrgsInf": [
{
"amt": {}
}
],
"trckrData": {
"confdAmt": {
"ccy": "USDC"
}
},
"orgnlTxRef": {
"amt": {
"item": {
"amt": {
"value": 10
}
}
},
"dbtr": {
"item": {
"nm": "sts:Test Source Account"
}
},
"dbtrAcct": {
"id": {
"item": "00000000-0000-0000-0000-000000000000"
},
"ccy": "USDC"
},
"cdtr": {
"item": {
"nm": "sts:Test Destination Account"
}
},
"cdtrAcct": {
"id": {
"item": "00000000-0000-0000-0000-000000000000"
}
}
},
"splmtryData": [
{
"plcAndNm": "demo transfer fireblocks"
}
]
}
]
}
]
}
]
Gets a list of all transfers. It can also get transfers for a specific account.
Our transfers object follows ISO20022 standards (CustomerPaymentStatusReportV14 / pain.002.001.14)
For more info, see the ISO 20022 message definitions.
Parameters (Query String):
| Parameter | Description | Required |
|---|---|---|
| accountId | The ID of the account for which to retrieve transfers. | Optional |
GET {baseUrl}/v1alpha/positions
curl --request GET \
--url https://tokyo.stsdigital.net/v1alpha/positions \
--header 'authorization: Bearer eyJhbGci…04Uv7sTg'
Example Response Array
<Position>
[
{
"accountId": "83b634ff-d606-4398-baae-bcd043c8e2a1",
"legalEntity": "Demo Customer",
"book": null,
"accountName": "Demo Customer - Spot Trading",
"venue": null,
"instrument": "BTC",
"spotPrice": 110826.27766725000000000000001,
"quantity": 0.325257308427638083,
"currentMarketValue": 36047.056777103791690648501885,
"deltaUsd": 36047.056777103791690648501885,
"gammaUsd": null,
"vegaUsd": null,
"vegaRTUsd": null,
"thetaUsd": null,
"rhoUsd": null,
"vannaUsd": null,
"volgaUsd": null,
"daysToExpiry": null,
"type": "Cash",
"currency": "BTC",
"delta": 36047.056777103791690648501885,
"text": null,
"isITM": null,
"instrumentDetails": null
},
{
"accountId": "55dcbd7e-d93e-451c-820f-464fc75a0507",
"legalEntity": "Demo Customer",
"book": null,
"accountName": "Demo Customer - Derivatives Trading",
"venue": "sts",
"instrument": "STS-SOL-USDT-PHYS-20250530-200.0-C",
"spotPrice": 178.87128548333333333333333335,
"quantity": 10.000000000000000000,
"currentMarketValue": 21.738477323048464784133406011,
"deltaUsd": 343.86561265684760000000000000,
"gammaUsd": 41.460863555005940000000000000,
"vegaUsd": 0.7185348148031538000000000000,
"vegaRTUsd": null,
"thetaUsd": -3.7415043732794210000000000000,
"rhoUsd": 0.0696958944783032750000000000,
"vannaUsd": 0.0601784182622281400000000000,
"volgaUsd": 0.0076916852783368130000000000,
"daysToExpiry": 7.8894795234537,
"type": "Option",
"currency": "SOL",
"delta": 343.86561265684760000000000000,
"text": null,
"isITM": false,
"instrumentDetails": {
"normalizedInstrumentCode": "STS-SOL-USDT-PHYS-20250530-200.0-C",
"baseCurrency": "SOL",
"quoteCurrency": "USDT",
"optionType": "C",
"settlementCurrency": "PHYS",
"strike": 200.0,
"expiry": "2025-05-30T08:00:00+00:00"
}
}
]
Gets a list of all open positions with STS. This endpoint will return an array of position with details regarding current market valuations for Cash/Spot positions and Derivatives positions
Derivatives positions will include details on the contract, such as greeks, strike, expiration, etc.
Parameters:
N/A: No parameters for this endpoint
FIX
All the message types currently used are FIX 4.4 convention, with additional custom fields, when integrating with STS we can provide our full DataDictionary fro deserialization.
Standard Messages
Establishing a connection
After opening a session, form and send a Logon msg using the client_id as Username and token you received the Authentication flow as Password. You should receive a Logon msg back and start receiving Heartbeat msgs right after we authenticate your session.
Market Data
STS Provides order book market data for many spot pairs available on many exchanges, please be aware that you will need a dedicated FIX session.
After sending a Market Data Request(V) if the request is successful, you will start receiving orderbooks in Market Data - Snapshot/Full Refresh(W) messages.
Market Data Request (V)
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 262 | MDReqID | Y | Must be unique when sending a subscription request. When cancelling a market data subscription, it should be the ID sent during subscription. | |
| 263 | SubscriptionRequestType | Y | 1 = Subscribe (Snapshot + Updates) 2 = Unsubscribe (Disable) |
|
| 264 | MarketDepth | Y | 0 | 0 = Full Book |
| 267 | NoMDEntryTypes | Y | 2 | Repeating Group Number of MDEntryType fields requested. Currently, an initiator should request both MDEntryType 0 (Bid) and 1 (Offer). |
| 269 | MDEntryType | Y | 0, 1 | 0 = Bid 1 = Offer |
| 146 | NoRelatedSym | Y | 1 | Number of Symbol fields requested. Currently, an initiator should only request a single Symbol per Market Data Request. |
| 55 | Symbol | Y | The symbol to send snapshots for. Supported symbols will be provided by STS Digital. | |
| - | Standard Trailer | Y |
Market Data Request Reject (Y)
If there is an error in the Market Data Request flow, STS Digital sends a Market Data Request Reject message.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 262 | MDReqID | Y | The ID of the Market Data Request that triggered this message. | |
| 281 | MDReqRejReason | N | 0, 1, 4 | 0 = Symbol is unknown or unsupported. 1 = MDReqID was not unique. 4 = An unsupported Message Type was received. |
| 58 | Text | Y | A descriptive string giving more information about the rejection. | |
| - | Standard Trailer | Y |
Market Data Snapshot / Full Refresh (W)
A Market Data Snapshot / Full Refresh message contains the following fields:
Each bid and ask is represented as a repeating group (tag 268) with the appropriate MDEntryType (0 for bid, 1 for ask), price (270), and size (271).
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 55 | Symbol | Y | e.g. "BTC-USD" | The symbol for the market data. |
| 262 | MDReqID | Y | String | The request ID for the market data snapshot. |
| 268 | NoMDEntries | Y | Integer | Number of MDEntry groups (bids + asks). |
| 269 | MDEntryType | Y | 0, 1 | 0 = Bid, 1 = Ask. |
| 270 | MDEntryPx | Y | Price | Price level for the entry. |
| 271 | MDEntrySize | Y | Quantity | Quantity at the price level. |
| - | Standard Trailer | Y |
RFS
STS provides streamed option prices on request, please be aware that you will need a dedicated FIX session.
We currently only stream single leg vanilla options for BTC-USD and ETH-USD by default. Other pairs are by negotiation.
A simplified Quote Request(R) is used both to start streaming and cancel it. After sending a Quote Request(R) to the rfs endpoint you will start receiving Mass Quotes(i) messages if the request is successful.
Note: The RFS flow has an agreed max trade value in the contract, the price returned is technically indicative but should be accepted for any quantity less than or equal to that max trade quantity; this means quantity only needs to be specified at time of trade. Quotes expire after a fixed period and are subject to a final economic check so acceptance of a quote is not guarunteed to lead to execution.
Quote Request (R) - Start
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 131 | QuoteReqId | Y | Unique ID for the quote request | |
| 146 | NoRelatedSym | Y | 1 | |
| Component Block |
||||
| 55 | Symbol | Y | 'N/A' | |
| 1 | Account | Y | Account identifier | |
| 711 | NoUnderlyings | Y | 1 | Number of Underlying Symbols (Currently only 1 supported) |
| Component Block |
||||
| 311 | UnderlyingSymbol | Y | BTC-USD, ETH-USD | |
| 60 | TransactTime | Y | The time from the initiator that the order was initiated. | |
| - | Standard Trailer | Y |
Quote Request (R) - Stop
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 131 | QuoteReqId | Y | Unique ID from quote request start | |
| 263 | SubscriptionRequestType | Y | 2 | DISABLE_PREVIOUS_SNAPSHOT_PLUS_UPDATE_REQUEST |
| 146 | NoRelatedSym | Y | 1 | |
| Component Block |
||||
| 55 | Symbol | Y | 'N/A' | |
| 1 | Account | Y | Account identifier | |
| 60 | TransactTime | Y | The time from the initiator that the order was initiated. | |
| - | Standard Trailer | Y |
Mass Quote (i) - Acknowledgement
As soon as the Quote Request is received a small mass Quote message will be returned to acknowledge it.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 1 | Account | Y | Account identifier | |
| 131 | QuoteReqId | Y | Unique ID from the quote request | |
| 117 | QuoteID | Y | Unique ID for this mass quote | |
| 537 | QuoteType | Y | 0 | INDICATIVE |
| 296 | NoQuoteSets | Y | 1 | |
| Component Block |
||||
| 302 | QuoteSetID | Y | 1 | |
| 311 | UnderlyingSymbol | Y | BTC-USD, ETH-USD | |
| 304 | TotNoQuoteEntries | Y | 0 | |
| - | Standard Trailer | Y |
Mass Quote (i) - Error
If an error occurs that prevents any quotes from being returned a small Mass Quote will be sent.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 1 | Account | Y | Account identifier | |
| 131 | QuoteReqId | Y | Unique ID from the quote request | |
| 117 | QuoteID | Y | Unique ID for this mass quote | |
| 8205 | MassQuoteErrorCode | N | Error Code (Dictionary to be defined) | |
| 537 | QuoteType | Y | 0 | INDICATIVE |
| 296 | NoQuoteSets | Y | 0 | |
| 304 | TotNoQuoteEntries | Y | 0 | |
| - | Standard Trailer | Y |
Mass Quote (i) - Prices
As soon as the Quote Request is received a small mass Quote message will be returned to acknowledge it.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 1 | Account | Y | Account identifier | |
| 131 | QuoteReqId | Y | Unique ID from the quote request | |
| 117 | QuoteID | Y | Unique ID for this mass quote | |
| 537 | QuoteType | Y | 0 | INDICATIVE |
| 296 | NoQuoteSets | Y | 1 | |
| Component Block |
||||
| 302 | QuoteSetID | Y | 1 | |
| 311 | UnderlyingSymbol | Y | BTC-USD, ETH-USD | |
| 810 | UnderlyingPx | Y | The spot price of the underlying | |
| 8205 | MassQuoteErrorCode | N | Error Code | Dictionary to be defined |
| 304 | TotNoQuoteEntries | Y | 0-N | Number of prices being returned |
| Component Block |
||||
| 299 | QuoteEntryID | Y | Unique ID for the quote entry | |
| 55 | Symbol | Y | Symbol for the quoted instrument (e.g STS-BTC-USD-PHYS-20260109-89500-P-E-V) | |
| 541 | MaturityDate | Y | Date formatted as YYYYMMDD | |
| 461 | CFICode | Y | CFICode for the leg (OPECCS, OCECCS, OPECCN, OCECCN) Char 2 = C/P (Call/Put), Char 6 = S/N (Standardized/Non-Standardized) ISO_10962 |
|
| 202 | StrikePrice | N | Strike Price for this quote entry | |
| 132 | LegBidPx | N | Price per Unit returned if SELL requested | |
| 133 | LegOfferPx | N | Price per Unit rReturned if BUY requested (not currently available) | |
| 62 | ValidUntilTime | N | DateTime quote is valid until | |
| 8205 | MassQuoteErrorCode | N | Error Code for this Entry | Dictionary to be defined |
| - | Standard Trailer | Y |
Trading
New Order Single (D)
STS Supports Spot Trading and RFQ trading.
For both spot and rfq orders, there are a few custom fields not part of FIX 4.4 standard message types. Where possible we try to follow the Fix Community User Defined Fields conventions.
Please find described bellow the fields supported on a NewOrderSingle, and feel free to contact the development team for inquiries or doubts.
Ps. For RFQ orders, QuoteId is a mandatory field.
Example NewOrderSingle Payload:
8=FIX.4.49=19235=D49=SENDER-TARGET52=20250522-10:02:43.82956=STS1={accId}11={clid}38=39740=244=0.5323742554=255={SYMBOL}59=360=20250522-10:02:43.703100=sts847=100010=175
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 11 | ClOrdID | Y | A unique identifier provided for each order by the initiator. Should be unique across all sessions. | |
| 1 | Account | Y | STS Digital will provide a Trading account identifier. | |
| 100 | ExDestination | Y | sts | Used to route the order within STS Digital. Must be set to "sts". |
| 55 | Symbol | Y | Supported symbols will be provided by STS Digital. | |
| 54 | Side | Y | 1, 2 | 1 = Buy 2 = Sell |
| 60 | TransactTime | Y | The time from the initiator that the order was initiated. | |
| 38 | OrderQty | Y | The quantity of the order. | |
| 40 | OrdType | Y | 2 | 2 = Limit |
| 44 | Price | Y | The limit price of the order. | |
| 59 | TimeInForce | Y | 1, 3, 6 | 1 = Good Till Cancel (Smart Post, Smart Stop, RFQ) 3 = Immediate Or Cancel (Sweep) 6 = Good Till Date (TWAP) |
| 18 | ExecInst | N | "6", "E" | 6 = Participant Don't Initiate (Smart Post, TWAP, Smart Stop) E = Reduce Only (Smart Post, Sweep) |
| 847 | TargetStrategy | N | 1000, 1001, 1002 | 1000 = Sweep order (IOC only) 1001 = Smart Post or TWAP (default) 1002 = Smart Stop |
| 5180 | CATStrategy | N | 2 | 2 = TWAP (if not passed, default is Smart Post) |
| 117 | QuoteId | N | QuoteId for Orders based on Quotes *Required for quoted orders |
|
| 494 | Designation | N | TxHash encoded signature | |
| 5622 | SweepType | N | 1, 2, 3 | 1 = Disabled 2 = Cheaper (default) 3 = Target Applied to Smart Post and TWAP |
| 836 | PegOffsetType | N | 2, 4 | 2 = Ticks 4 = Percentage Applied to Smart Post, TWAP and Smart Stop |
| 211 | PegOffsetValue | N | If PegOffsetType = Ticks: - 1 = Near Peg - 0 = Midpoint Peg - -1 = Far Peg If PegOffsetType = Percentage: - 25 = Passive - 50 = Neutral - 75 = Aggressive Default is Aggressive Applied to Smart Post, TWAP and Smart Stop |
|
| 848 | TargetStrategyParameters | N | auto | Only used if Peg Offset is not supplied. Uses dynamic peg offset. Applied to Smart Post, TWAP and Smart Stop |
| 849 | ParticipationRate | N | Limit to this percent of trading volume in each interval. Applied to Smart Post and TWAP |
|
| 5904 | Duration | N | Number of seconds in each interval. Applied to Smart Post and TWAP |
|
| 8200 | MaxPostSize | N | Maximum quantity to post on any exchange order; randomized. Applied to Smart Post and TWAP |
|
| 8201 | MinPostSize | N | Minimum quantity to post on any exchange order; randomized. Applied to Smart Post and TWAP |
|
| 6148 | ExpiryDuration | N | Order length in seconds. Applied to TWAP |
|
| 8203 | IntervalLength | N | Number of seconds per interval (used with ExpiryDuration). Applied to TWAP |
|
| 15 | Currency | N | The target currency from the pair in Symbol. Applied to TWAP and Smart Stop |
|
| 8204 | FullSize | N | Y, N | Send full order quantity to exchange at once. Applied to Smart Stop |
| 6307 | SweepPercentage | N | Used to calculate limit price for the sweep order. Applied to Smart Stop |
|
| - | Standard Trailer | Y |
RFS - New Order Single (D)
The RFS flow uses a minimal New Order Single message.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 11 | ClOrdID | Y | A unique identifier provided for each order by the initiator. Should be unique across all sessions. | |
| 1 | Account | Y | STS Digital will provide a Trading account identifier. | |
| 100 | ExDestination | Y | sts | Used to route the order within STS Digital. Must be set to "sts". |
| 15 | Currency | N | The unit of the OrderQty field. Can be the Base or Quote currency of the option. | |
| 55 | Symbol | Y | The Symbol from the MassQuote Entry corresponding to the QuoteId below. | |
| 54 | Side | Y | 2 | 2 = Sell |
| 60 | TransactTime | Y | The time from the initiator that the order was initiated. | |
| 38 | OrderQty | Y | The quantity of the order. See also Currency(15) | |
| 40 | OrdType | Y | 2 | 2 = Limit |
| 44 | Price | Y | The limit price per unit of the order in USD. Not subject to the Currency field (15) | |
| 59 | TimeInForce | Y | 1 | 1 = Good Till Cancel |
| 117 | QuoteId | Y | QuoteEntryId from the Quote Entry in the relevant Mass Quote. | |
| 583 | ClOrdLinkID | Y | QuoteRequestId from the Quote Request the Order is based on. | |
| - | Standard Trailer | Y |
Order Cancel Request (F)
For Good Till Cancel orders, a Cancel Request message must be sent with the order details to cancel that order; otherwise, it will remain in the book indefinitely.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 41 | OrigClOrdID | Y | Order ID to be cancelled | |
| 11 | ClOrdID | Y | Cancel Request ID | |
| 55 | Symbol | Y | Symbol on the order to be cancelled | |
| 54 | Side | Y | 1, 2 | 1 = Buy 2 = Sell |
| 60 | TransactTime | Y | DateTime of cancel request | |
| - | Standard Trailer | Y |
Execution Report (8)
An execution report is sent for all order state changes (except Pending New).
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 37 | OrderID | Y | The ID of the order within STS Digital's systems. | |
| 11 | ClOrdID | Y | The client order ID. | |
| 17 | ExecID | Y | The ID of the execution report. | |
| 150 | ExecType | Y | A, 8, 0, F, 4 | A = Pending New 8 = Rejected 0 = New F = Trade 4 = Canceled |
| 39 | OrdStatus | Y | A, 8, 0, 1, 2, 4 | A = Pending New 8 = Rejected 0 = New 1 = Partially filled 2 = Filled 4 = Canceled |
| 103 | OrdRejReason | N | If order was rejected. | |
| 58 | Text | N | Rejection reason description. | |
| 1 | Account | Y | Account of the order. | |
| 55 | Symbol | Y | Order symbol. | |
| 54 | Side | Y | 1, 2 | 1 = Buy 2 = Sell |
| 38 | OrderQty | N | Original order quantity. Units mirror NewOrderSingle message contents | |
| 40 | OrdType | N | 2 | 2 = Limit |
| 44 | Price | N | Original limit price. | |
| 59 | TimeInForce | N | 3, 4 | 3 = ImmediateOrCancel 4 = FillOrKill |
| 32 | LastQty | N | Trade quantity (if ExecType = Trade). | |
| 31 | LastPx | N | Trade price (if ExecType = Trade). | |
| 151 | LeavesQty | Y | Quantity still open. | |
| 14 | CumQty | Y | Total traded quantity. Units mirror NewOrderSingle message contents | |
| 6 | AvgPx | Y | Average trade price. | |
| 60 | TransactTime | Y | Execution report timestamp. | |
| - | Standard Trailer | Y |
RFQ
Quote Request (R)
STS supports Quote requests for Options trading.
The following table specifies the fields needed to send on the Quote Request (MsgType R). The main component is the repeated group NoRelatedSymbol, where information regarding the symbol, account, currency, etc. needs to be defined.
We aim to support Multi Leg quoting soon, so the structure already reflects that. Under the RelatedSymbol group, there is a NoLegs group where leg parameters (Strike, Side, Maturity, Qty) must be specified.
Important Notes:
LegQtyon the quote request is the Notional Amount for the operation, denominated in Currency (15).- The
LegQtyreceived in the Quote response (S) will be the number of contracts matching the Bid or Offer price for that notional. - For non-standard options, only Barrier style is supported. To request a Barrier, the Barrier Style and all related fields (marked as not required) must be present in the request.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 131 | QuoteReqId | Y | Unique ID for the quote request | |
| 146 | NoRelatedSym | Y | Number of related symbols to the quote | |
| Component Block |
||||
| 55 | Symbol | Y | Symbol for the quote (set to 'N/A' if unknown) | |
| 1 | Account | Y | Account identifier | |
| 54 | Side | Y | 1 = Buy / 2 = Sell | |
| 15 | Currency | Y | Currency of the quote | |
| 120 | SettlCurrency | Y | Settlement Currency of the quote, PHYS if physical settlement is desired | |
| 711 | NoUnderlyings | Y | 1 | Number of Underlying Symbols (Currently only 1 supported) |
| 555 | NoLegs | Y | Number of legs in the request | |
| Component Block |
||||
| 624 | LegSide | Y | 1 = Buy, 2 = Sell (The LegSide must always be Buy for single leg RFQs) | |
| 612 | LegStrikePrice | Y | The strike price for the leg | |
| 687 | LegQty | Y | Quantity of the leg in nominal currency value | |
| 611 | LegMaturityDate | Y | Date formatted as YYYYMMDD | |
| 608 | LegCFICode | Y | CFICode for the leg (OPECCS, OCECCS, OPECCN, OCECCN) Char 2 = C/P (Call/Put), Char 6 = S/N (Standardized/Non-Standardized) ISO_10962 (CFICode standard) |
|
| 600 | LegSymbol | Y | Should always be 'N/A', the symbol will be built and returned in the Quote message | |
| 9130 | Barrier Style | N | 1, 2 | 1 = In, 2 = Out |
| 9131 | Barrier Level | N | Required if solved for level | |
| 9132 | Barrier Direction | N | 1, 2 | 1 = Up, 2 = Down |
| 9135 | Barrier Rebate | N | Rebate on barrier option | |
| 9187 | TouchType | N | 1, 2, 3 | 3 = Pay at Expiry |
| 9655 | LegYield | N | Required if solved for yield | |
| 9656 | CustomLegPriceType | N | 1, 2 | 1 = Price, 2 = Yield |
| Component Block |
||||
| 311 | UnderlyingSymbol | Y | e.g. "SOL-USDT" | |
| - | Standard Trailer | Y |
Quote (S)
A quote response is sent for successful quote requests. The QuoteId must be included on the NewOrderSingle if the quote is accepted.
Quote Validity: Quotes are valid for 5 minutes by default from the request time. They are tradeable only once during validity.
Bid/Offer Rules:
If the quote requested is a SELL, a BidPx is returned. If a BUY, an OfferPx is returned.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 117 | QuoteId | Y | Unique ID for the quote | |
| 131 | QuoteReqId | Y | ID of the request | |
| 55 | Symbol | Y | "N/A" | Symbol is required but not applicable; each leg returns its symbol |
| 62 | ValidUntilTime | Y | DateTime quote is valid until | |
| 60 | TransactTime | Y | DateTime quote was created | |
| Component Block |
||||
| 1 | Account | Y | Account identifier | |
| 54 | Side | Y | 1 = Buy / 2 = Sell | |
| 15 | Currency | Y | Currency of the quote | |
| 711 | NoUnderlyings | Y | 1 | Number of underlying symbols |
| 555 | NoLegs | Y | ||
| Component Block |
||||
| 624 | LegSide | Y | 1 = Buy / 2 = Sell (The LegSide must always be Buy for single leg RFQs) | |
| 612 | LegStrikePrice | Y | Example = 120 | |
| 687 | LegQty | Y | Example = 10,000 | |
| 611 | LegMaturityDate | Y | e.g. 20241030 | |
| 608 | LegCFICode | Y | CFICode for the leg (OPECCS, OCECCS, OPECCN, OCECCN) Char 2 = C/P (Call/Put), Char 6 = S/N (Standardized/Non-Standardized) ISO_10962 (CFICode standard) |
|
| 681 | LegBidPx | N | Returned if SELL requested | |
| 684 | LegOfferPx | N | Returned if BUY requested | |
| 9130 | Barrier Style | N | 1, 2 | |
| 9131 | Barrier Level | N | ||
| 9132 | Barrier Direction | N | 1, 2 | |
| 9135 | Barrier Rebate | N | ||
| 9187 | TouchType | N | 3 | 3 = Pay at Expiry |
| 9655 | LegYield | N | ||
| 9656 | CustomLegPriceType | N | 1, 2 | 1 = Price / 2 = Yield |
| Component Block |
||||
| 311 | UnderlyingSymbol | Y | e.g. "SOL-USDT" | |
| 810 | UnderlyingPx | Y | Used as reference for quote | |
| - | Standard Trailer | Y |
Quote Request Reject
In case of failure or impossibility to generate a quote based on the parameters of the request, a Quote Request Reject msg will be sent back to the caller, with the Text reason for it. The rejection may also be due to market variance on which STS cannot provide a price quote.
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 131 | QuoteReqId | Y | ID of the request | |
| 658 | QuoteRequestRejectReason | Y | 99 | Reason of rejection |
| 58 | Text | Y | Description of rejection | |
| 146 | NoRelatedSym | Y | Related symbol | |
| Component Block |
||||
| 55 | Symbol | Y | "N/A" | Required FIX field, always "N/A" |
| - | Standard Trailer | Y |
Fix Reference
This document is not intended as a comprehensive guide for session management or the FIX protocol generally. For more information on the FIX protocol, visit the FIX Trading Community.
There are several well-known libraries for working with FIX connections. While we do not provide any specific recommendations, if you're new to FIX, QuickFix is a free, open-source library which can provide a good starting point to bootstrap implementation. QuickFix is available in multiple languages with code samples for creating FIX clients/initiators. Many such libraries provide 'out-of-the-box' session management and boilerplate functionality (such as handling Heartbeat messages, message body length/checksum calculation).
Another useful tool is the FIX Parser Fix Parser which can be used during development to see the content of FIX messages.
Standard messages
Header
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| 8 | BeginString | Y | FIX.4.4 | |
| 9 | BodyLength | Y | ||
| 35 | MsgType | Y | Supported Types: - A = Logon - 5 = Logout - 0 = Heartbeat - 3 = Reject - j = BusinessMessageReject - V = MarketDataRequest - Y = MarketDataRequestReject - W = MarketDataSnapshot - i = Mass Quote - D = NewOrderSingle - 8 = ExecutionReport - R = QuoteRequest - S = Quote - AG = QuoteRequestReject |
|
| 49 | SenderCompID | Y | STS Digital will provide a client ID which must be set. When sending messages to the FIX API, the SenderCompId should be the provided client ID and the TargetCompId should be "STS". Messages from STS will reverse these fields. |
|
| 56 | TargetCompID | Y | See above. | |
| 34 | MsgSeqNum | Y | ||
| 52 | SendingTime | Y |
Trailer
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| 10 | CheckSum | Y |
Session Messages
Logon (A)
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 98 | EncryptMethod | Y | 0 | TBD |
| 108 | HeartBeatInt | Y | 30 | The frequency at which Heartbeat messages shall be sent, in seconds. |
| 141 | ResetSeqNumFlag | Y | Y | If a connection to the FIX API is lost, the sequence numbers should be reset. STS Digital does not provide recovery of previous sessions. |
| 553 | Username | Y | STS Digital will provide a client_id. | |
| 554 | Password | Y | access_token retrieved from Auth0. | |
| - | Standard Trailer | Y |
Logout (5)
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 58 | Text | N | If logon fails during session creation, the acceptor will respond with a Logout message containing additional information in the Text field. | |
| - | Standard Trailer | Y |
Heartbeat (0)
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| - | Standard Trailer | Y |
Reject (3)
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 45 | RefSeqNum | Y | MsgSeqNum of the rejected message. | |
| 373 | SessionRejectReason | N | Indicates the reason for the rejection. | |
| 58 | Text | N | Additional information regarding the reason for the rejection. | |
| - | Standard Trailer | Y |
Application Messages
Business Message Reject (j)
| Tag | Name | Req'd | Values | Notes |
|---|---|---|---|---|
| - | Standard Header | Y | ||
| 45 | RefSeqNum | Y | The message sequence number of the original message. | |
| 372 | RefMsgType | Y | The message type which is not supported for the session. | |
| 380 | BusinessRejectReason | Y | 6 | The reason why the message was rejected. 6 = Not Authorized |
| 58 | Text | Y | An explanation of why the message was rejected. | |
| - | Standard Trailer | Y |
Order State Changes
This section illustrates the sequence of expected messages. Note that no execution report is sent for Pending New events.
FillOrKill
| # | Received | Sent | ExecType | OrdStatus | OrderQty | CumQty | LeavesQty | LastQty | Notes |
|---|---|---|---|---|---|---|---|---|---|
| 1 | NewOrderSingle | 10000 | |||||||
| 2 | ExecutionReport | Rejected | Rejected | 10000 | 0 | 0 | 0 | An order may be rejected immediately if checks fail, e.g. insufficient balance. | |
| 3 | ExecutionReport | New | New | 10000 | 0 | 10000 | 0 | ||
| 4 | ExecutionReport | Canceled | Canceled | 10000 | 0 | 0 | 0 | A FillOrKill order will be canceled if it cannot be executed immediately, in full. | |
| 5 | ExecutionReport | Trade | Partially Filled | 10000 | 2000 | 8000 | 2000 | Trade of 2000 | |
| 6 | ExecutionReport | Trade | Partially Filled | 10000 | 5000 | 5000 | 3000 | Trade of 3000 | |
| 7 | ExecutionReport | Trade | Filled | 10000 | 10000 | 0 | 5000 | Trade of 5000 |
ImmediateOrCancel order that can be completely filled
| # | Received | Sent | ExecType | OrdStatus | OrderQty | CumQty | LeavesQty | LastQty | Notes |
|---|---|---|---|---|---|---|---|---|---|
| 1 | NewOrderSingle | 10000 | |||||||
| 2 | ExecutionReport | Rejected | Rejected | 10000 | 0 | 0 | 0 | An order may be rejected immediately if checks fail, e.g. insufficient balance. | |
| 3 | ExecutionReport | New | New | 10000 | 0 | 10000 | 0 | ||
| 4 | ExecutionReport | Trade | Partially Filled | 10000 | 2000 | 8000 | 2000 | Trade of 2000 | |
| 5 | ExecutionReport | Trade | Filled | 10000 | 10000 | 0 | 8000 | Trade of 8000 |
ImmediateOrCancel order that cannot be completely filled
| # | Received | Sent | ExecType | OrdStatus | OrderQty | CumQty | LeavesQty | LastQty | Notes |
|---|---|---|---|---|---|---|---|---|---|
| 1 | NewOrderSingle | 10000 | |||||||
| 2 | ExecutionReport | Rejected | Rejected | 10000 | 0 | 0 | 0 | An order may be rejected immediately if checks fail, e.g. insufficient balance. | |
| 3 | ExecutionReport | New | New | 10000 | 0 | 10000 | 0 | ||
| 4 | ExecutionReport | Trade | Partially Filled | 10000 | 2000 | 8000 | 2000 | Trade of 2000 | |
| 5 | ExecutionReport | Canceled | Canceled | 10000 | 2000 | 0 | 0 | An ImmediateOrCancel order will be partially filled and the |