mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-09 08:18:07 +00:00
285 lines
9.8 KiB
Markdown
285 lines
9.8 KiB
Markdown
# Events
|
|
|
|
## **Order Update**
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type": "order_update",
|
|
// timestamp of the event in nanoseconds
|
|
"timestamp": "1695081920633151000",
|
|
"product_id": 1,
|
|
// order digest
|
|
"digest": "0xf7712b63ccf70358db8f201e9bf33977423e7a63f6a16f6dab180bdd580f7c6c",
|
|
// remaining amount to be filled.
|
|
// will be `0` if the order is either fully filled or cancelled.
|
|
"amount": "82000000000000000",
|
|
// any of: "filled", "cancelled", "placed"
|
|
"reason": "filled",
|
|
// an optional `order id` that can be provided when placing an order
|
|
"id": 100
|
|
}
|
|
```
|
|
|
|
### Example Scenarios:
|
|
|
|
Let's assume your initial order amount is 100 units and each match occurs for an amount of 10 units.
|
|
|
|
{% hint style="info" %}
|
|
**Note**: The following events only include <mark style="color:red;">`amount`</mark> and <mark style="color:red;">`reason`</mark> for simplicity.
|
|
{% endhint %}
|
|
|
|
#### Scenario 1: Limit Order Partially Fills and Gets Placed
|
|
|
|
Your limit order matches against existing orders in the book.
|
|
|
|
You will receive the following events over websocket, each with the same timestamp but in sequential order:
|
|
|
|
* Event 1: `(90, "filled")` — 10 units of your order are filled.
|
|
* Event 2: `(80, "filled")` — Another 10 units are filled.
|
|
* Event 3: `(80, "placed")` — The remaining 80 units are placed on the book.
|
|
|
|
#### Scenario 2: Immediate-Or-Cancel (IOC) Order Partially Fills
|
|
|
|
Your IOC order matches against existing orders but is not completely filled.
|
|
|
|
The events you will receive are as follows:
|
|
|
|
* Event 1: `(90, "filled")` — 10 units are filled.
|
|
* Event 2: `(80, "filled")` — Another 10 units are filled.
|
|
* Event 3: `(0, "cancelled")` — The remaining order is cancelled. **Note**: If your IOC order is fully filled, the last event you will receive is `(0, "filled")`.
|
|
|
|
#### Scenario 3: Resting Limit Order Gets Matched
|
|
|
|
Your existing, or "resting," limit order matches against an incoming order.
|
|
|
|
You will receive the following event: `(90, "filled")` — 10 units of your resting limit order are filled.
|
|
|
|
#### Scenario 4: Resting Limit Order Gets Cancelled
|
|
|
|
Your resting limit order could be cancelled for various reasons, such as manual cancellation, expiration, failing health checks, or self-trade prevention.
|
|
|
|
In any of these cases, you will receive: `(0, "cancelled")`
|
|
|
|
#### **Scenario 5: IOC order doesn't cross the book or FOK order fails to be entirely filled**
|
|
|
|
In any of these cases, you will receive: `(0, "cancelled")`
|
|
|
|
## **Trade**
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type": "trade",
|
|
"timestamp": "1676151190656903000", // timestamp of the event in nanoseconds
|
|
"product_id": 1,
|
|
"price": "1000", // price the trade happened at, multiplied by 1e18
|
|
// both taker_qty and maker_qty have the same value;
|
|
// set to filled amount (min amount of taker and maker) when matching against book
|
|
"taker_qty": "1000",
|
|
"maker_qty": "1000",
|
|
"is_taker_buyer": true
|
|
}
|
|
```
|
|
|
|
## **Best Bid Offer**
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type": "best_bid_offer",
|
|
"timestamp": "1676151190656903000", // timestamp of the event in nanoseconds
|
|
"product_id": 1,
|
|
"bid_price": "1000", // the highest bid price, multiplied by 1e18
|
|
"bid_qty": "1000", // quantity at the highest bid, multiplied by 1e18.
|
|
// i.e. if this is USDT0 with 6 decimals, one USDT0
|
|
// would be 1e12
|
|
"ask_price": "1000", // lowest ask price
|
|
"ask_qty": "1000" // quantity at the lowest ask
|
|
}
|
|
```
|
|
|
|
## **Fill**
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type": "fill",
|
|
"timestamp": "1676151190656903000", // timestamp of the event in nanoseconds
|
|
"product_id": 1,
|
|
// the subaccount that placed this order
|
|
"subaccount": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
|
|
// hash of the order that uniquely identifies it
|
|
"order_digest": "0xf4f7a8767faf0c7f72251a1f9e5da590f708fd9842bf8fcdeacbaa0237958fff",
|
|
// order appendix containing execution type, reduce-only flag, etc.
|
|
"appendix": "4096",
|
|
// the amount filled, multiplied by 1e18
|
|
"filled_qty": "1000",
|
|
// the amount outstanding unfilled, multiplied by 1e18
|
|
"remaining_qty": "2000",
|
|
// the original order amount, multiplied by 1e18
|
|
"original_qty": "3000",
|
|
// fill price
|
|
"price": "24991000000000000000000",
|
|
// true for `taker`, false for `maker`
|
|
"is_taker": true,
|
|
"is_bid": true,
|
|
// the amount of fee paid, multiplied by 1e18
|
|
"fee": "100",
|
|
// the submission_idx of the transaction (n_submissions - 1)
|
|
// can use to map `fills` to historical `matches`.
|
|
"submission_idx": 100,
|
|
// an optional `order id` that can be provided when placing an order
|
|
"id": 100
|
|
}
|
|
```
|
|
|
|
## **Position Change**
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type":"position_change",
|
|
"timestamp": "1676151190656903000", // timestamp of event in nanoseconds
|
|
"product_id":1,
|
|
// subaccount who's position changed
|
|
"subaccount":"0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43706d00000000000000000000",
|
|
// whether this position change is for an isolated margin position
|
|
"isolated": false,
|
|
// new amount for this product
|
|
"amount":"51007390115411548",
|
|
// new quote balance for this product; zero for everything except non lp perps
|
|
// the negative of the entry cost of the perp
|
|
"v_quote_amount":"0",
|
|
// any of: "deposit_collateral", "match_orders", "withdraw_collateral", "transfer_quote", "settle_pnl", "mint_nlp", "burn_nlp", "liquidate_subaccount"
|
|
"reason": "deposit_collateral"
|
|
}
|
|
```
|
|
|
|
{% hint style="info" %}
|
|
**Note:** that it is possible that back to back <mark style="color:red;">`position_change`</mark> events have the same fields except for <mark style="color:red;">`timestamp`</mark>. Additionally, <mark style="color:red;">`position_change`</mark> events are not sent on interest and funding payments, and also are not sent on actions done through slow mode (except deposits). The full list of actions that will trigger a <mark style="color:red;">`PositionChange`</mark> event are:
|
|
|
|
* Minting or burning NLP tokens
|
|
* Liquidating a subaccount
|
|
* Matching orders
|
|
* Depositing or withdrawing spot
|
|
* Settling PNL
|
|
{% endhint %}
|
|
|
|
## **Book Depth**
|
|
|
|
**Update speed: once every 50ms**
|
|
|
|
```json
|
|
{
|
|
"type":"book_depth",
|
|
// book depth aggregates a number of events once every 50ms
|
|
// these are the minimum and maximum timestamps from
|
|
// events that contributed to this response
|
|
"min_timestamp": "1683805381879572835",
|
|
"max_timestamp": "1683805381879572835",
|
|
// the max_timestamp of the last book_depth event for this product
|
|
"last_max_timestamp": "1683805381771464799",
|
|
"product_id":1,
|
|
// changes to the bid side of the book in the form of [[price, new_qty]]
|
|
"bids":[["21594490000000000000000","51007390115411548"]],
|
|
// changes to the ask side of the book in the form of [[price, new_qty]]
|
|
"asks":[["21694490000000000000000","0"],["21695050000000000000000","0"]]
|
|
}
|
|
```
|
|
|
|
{% hint style="info" %}
|
|
**Note**: To keep an updated local orderbook, do the following:
|
|
|
|
1. Subscribe to the `book_depth` stream and queue up events.
|
|
2. Get a market data snapshot by calling [MarketLiquidity](https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/market-liquidity). The snapshot contains a `timestamp` in the response.
|
|
3. Apply events with `max_timestamp` > snapshot `timestamp`.
|
|
4. When you receive an event where its `last_max_timestamp` is not equal to the `max_timestamp` of the last event you've received, it means some events were lost and you should repeat 1-3 again.
|
|
{% endhint %}
|
|
|
|
## **Liquidation**
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type": "liquidation",
|
|
"timestamp": "1234567890000", // timestamp of the event in nanoseconds
|
|
// single element for regular liquidations, two elements for spread liquidations (spot_id, perp_id)
|
|
"product_ids": [1],
|
|
// liquidator subaccount (32 bytes)
|
|
"liquidator": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
|
|
// liquidatee subaccount (32 bytes)
|
|
"liquidatee": "0x8b6fd3859f7065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
|
|
// amount liquidated (positive for long, negative for short)
|
|
"amount": "1000000000000000000",
|
|
// price at which liquidation occurred
|
|
"price": "50000000000000000000"
|
|
}
|
|
```
|
|
|
|
## Latest Candlestick
|
|
|
|
**Update speed: real-time**
|
|
|
|
```json
|
|
{
|
|
"type": "latest_candlestick",
|
|
"timestamp": 1234567890000,
|
|
"product_id": 1,
|
|
"granularity": 60,
|
|
"open_x18": "50000000000000000000",
|
|
"high_x18": "51000000000000000000",
|
|
"low_x18": "49000000000000000000",
|
|
"close_x18": "50500000000000000000",
|
|
"volume": "1000000000000000000"
|
|
}
|
|
```
|
|
|
|
## Funding Payment
|
|
|
|
**Update speed: real-time at the time of payment (payments happen hourly).**
|
|
|
|
```json
|
|
{
|
|
"type": "funding_payment",
|
|
"timestamp": 1234567890000,
|
|
"product_id": 1,
|
|
// funding payment amount (positive = receive, negative = pay)
|
|
"payment_amount": "1000000000000000000",
|
|
// open interest at time of funding
|
|
"open_interest": "50000000000000000000",
|
|
// cumulative funding values, multiplied by 1e18
|
|
"cumulative_funding_long_x18": "100000000000000000",
|
|
"cumulative_funding_short_x18": "-100000000000000000",
|
|
// time delta over which the funding payment was calculated
|
|
"dt": 3600000
|
|
}
|
|
```
|
|
|
|
## Funding Rate
|
|
|
|
**Update speed: real-time (updates occur every 20 seconds).**
|
|
|
|
{% hint style="info" %}
|
|
**Note**: The `funding_rate_x18` and `update_time` values are identical to those returned by the [Funding Rate](https://docs.nado.xyz/developer-resources/api/archive-indexer/funding-rate) indexer endpoint.
|
|
{% endhint %}
|
|
|
|
```json
|
|
{
|
|
"type": "funding_rate",
|
|
// timestamp when the event was generated, in nanoseconds
|
|
"timestamp": "1234567890123456789",
|
|
"product_id": 1,
|
|
// latest 24hr funding rate, multiplied by 1e18
|
|
"funding_rate_x18": "50000000000000000",
|
|
// timestamp when the funding rate was updated, in seconds
|
|
"update_time": "1234567890"
|
|
}
|
|
```
|