⚡Websocket
Graphql websocket API will allow to subscribe to stream of data using graphql subscription format
To connect with Websocket API, simply connect to this graphql url
wss://dev.api.avantis.finance/v1/websocket/graphql
or you can use playground to play around with data first
https://dev.api.avantis.finance/playground/websocket/playground
Available Subscriptions
GraphQL Schema
type SubscriptionRoot {
stockPrice(stockIdIn: [Int!]!): StockPrice!
bidOffer(stockIdIn: [Int!]!): BidOffer!
}
type StockPrice {
stockId: Int!
executePrice: BigDecimal!
exchangeId: Int!
accVolume: Int!
accValue: Int!
highestPrice: BigDecimal!
lowestPrice: BigDecimal!
lastOpenPrice: BigDecimal!
settradeDateTime: DateTime!
volume: Int!
value: BigDecimal!
bidside: Boolean!
isBid: Boolean!
offerside: Boolean!
lastClosePrice: BigDecimal!
lastCloseDate: DateTime!
rowNo: Int!
}
type BidOffer {
stockId: Int!
action: String!
bids: [[String!]!]!
offers: [[String!]!]!
snapshotChecksum: String!
}Subscribe to get real time Stock Price
this subscription should get the stream of the results. where stockIdIn can be get from profile api
example of query
subscription stock {
# PTTEP: 236032
# KBANK: 15594
stockPrice(stockIdIn: [236032, 15594]) {
stockId
executePrice
exchangeId
accVolume
accValue
highestPrice
lastOpenPrice
settradeDateTime
volume
bidside
isBid
offerside
lastClosePrice
lastCloseDate
rowNo
}
}example of the results (1)
{
"data": {
"stockPrice": {
"stockId": 236032,
"executePrice": "157",
"exchangeId": 4,
"accVolume": 4120100,
"accValue": 645879,
"highestPrice": "158",
"lastOpenPrice": "157.5",
"settradeDateTime": "2022-05-18T11:14:53Z",
"volume": 400,
"bidside": true,
"isBid": true,
"offerside": false,
"lastClosePrice": "157.5000",
"lastCloseDate": "2022-05-17T00:00:00Z",
"rowNo": 2385568
}
}
}example of the results (2)
{
"data": {
"stockPrice": {
"stockId": 236032,
"executePrice": "156.5",
"exchangeId": 4,
"accVolume": 4122400,
"accValue": 646240,
"highestPrice": "158",
"lastOpenPrice": "157.5",
"settradeDateTime": "2022-05-18T11:15:22Z",
"volume": 100,
"bidside": false,
"isBid": false,
"offerside": true,
"lastClosePrice": "157.5000",
"lastCloseDate": "2022-05-17T00:00:00Z",
"rowNo": 2391183
}
}
}Subscribe to get real time stock Bid/Offer
this subscription should get the stream of the results. where stockIdIn can be get from profile api
example of query
subscription bidoffer {
# PTTEP: 236032
# KBANK: 15594
bidOffer(stockIdIn: [15594]) {
stockId
action
bids
offers
snapshotChecksum
}
}Result will have 2 types:
initial message
action: S (Snapshot)
contains 5 elements of bid and offer data on each side.
update message
action: I (Insert), D (Delete), U (Update)
contains only changed value of bid or offer
example of result - Initial message
{
"data": {
"bidOffer": {
"stockId": 15594,
"action": "S",
"bids": [
[
"B:ATO",
"30100"
],
[
"152.5",
"600"
],
[
"150.5",
"9900"
],
[
"148.5",
"4300"
],
[
"147.5",
"1000"
]
],
"offers": [
[
"O:ATO",
"9400"
],
[
"138.5",
"2400"
],
[
"139",
"19400"
],
[
"142",
"3000"
],
[
"144",
"9000"
]
],
"snapshotChecksum": "3023434458"
}
}
}example of result - Update message
{
"data": {
"bidOffer": {
"stockId": 15594,
"action": "U",
"bids": [
[
"B:ATO",
"50100"
]
],
"offers": [],
"snapshotChecksum": "2263682656"
}
}
}checksum
Every message contains an unsigned 32-bit integer checksum of the bid/offer. You can run the same checksum on your client bid/offer state and compare it to checksum field. If they are the same, your client's state is correct. If not, you have likely lost or mishandled a packet and should re-subscribe to receive the initial snapshot.
The checksum operates on a string that represents the first 10 orders on the bid/offer sorted by highest to lowest price. The format of the string is:
{best_price}|{side}:{volume},{second_price}|{side}:{volume},...
If message contains ATO or ATC, the format will be as follows:
{side}:{ATO,ATC}|{side}:{volume},{best_price}|{side}:{volume},{second_price}|{side}:{volume},...
The final checksum is the crc32 value of this string
reference: ftx
Initial message
When client received message from the websocket with following example, then calculate with the string format in the previous section. And the message also contains checksum value for validate state between client and server in next message.
...
"action": "S",
"bids": [
[
"B:ATO",
"30100"
],
[
"152.5",
"600"
],
[
"150.5",
"9900"
],
[
"148.5",
"4300"
],
[
"147.5",
"1000"
]
],
"offers": [
[
"O:ATO",
"9400"
],
[
"138.5",
"2400"
],
[
"139",
"19400"
],
[
"142",
"3000"
],
[
"144",
"9000"
]
],
"snapshotChecksum": "3023434458"
...The example of formatted string of initial snapshot message,
O:ATO|O:9400,B:ATO|B:30100,152.5|B:600,150.5|B:9900,148.5|B:4300,147.5|B:1000,144|O:9000,142|O:3000,139|O:19400,138.5|O:2400
Update message
...
"action": "U",
"bids": [
[
"B:ATO",
"50100"
]
],
...After received the update message, then change current value with new value
For example, the bid side at B:ATO changed to 50100, the value of B:ATO in the string from initial snapshot state should be B:ATO|50100
New string should be like this example : O:ATO|O:9400,B:ATO|B:50100,152.5|B:600,150.5|B:9900,148.5|B:4300,147.5|B:1000,144|O:9000,142|O:3000,139|O:19400,138.5|O:2400
And calculate checksum to validate state between client and server.
Authentication
To connect with our websocket, we require the client to attach key-value of authentication header with connection initial payload.
Either x-api-key or authorization were required.
{
"type": "connection_init",
"payload": {
"x-api-key": "API_KEY"
}
}{
"type": "connection_init",
"payload": {
"authorization": "TOKEN"
}
}Or you can use graphql client apollo-link-ws by add authentication to connectionParams
Last updated