Skip to main content

nautilus_okx/websocket/
enums.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Enumerations representing OKX WebSocket message metadata and codes.
17
18use serde::{Deserialize, Serialize};
19use strum::{AsRefStr, Display, EnumIter, EnumString};
20
21/// Error types that can be returned by the WebSocket API.
22#[derive(
23    Clone,
24    Debug,
25    Display,
26    PartialEq,
27    Eq,
28    Hash,
29    AsRefStr,
30    EnumIter,
31    EnumString,
32    Serialize,
33    Deserialize,
34)]
35#[serde(rename_all = "camelCase")]
36pub enum OKXWsErrorType {
37    /// General error.
38    Error,
39    /// Error during subscription.
40    SubscriptionError,
41    /// Error during unsubscription.
42    UnsubscriptionError,
43    /// Authentication failure.
44    AuthenticationError,
45    /// Rate limit exceeded.
46    RateLimit,
47}
48
49/// Operation type for WebSocket commands.
50#[derive(
51    Clone,
52    Debug,
53    Display,
54    PartialEq,
55    Eq,
56    Hash,
57    AsRefStr,
58    EnumIter,
59    EnumString,
60    Serialize,
61    Deserialize,
62)]
63#[serde(rename_all = "kebab-case")]
64pub enum OKXWsOperation {
65    /// Subscribes to one or more topics.
66    Subscribe,
67    /// Unsubscribe from one or more topics.
68    Unsubscribe,
69    /// Place a new order.
70    Order,
71    /// Cancel an existing order.
72    CancelOrder,
73    /// Amend an existing order.
74    AmendOrder,
75    /// Place multiple orders.
76    BatchOrders,
77    /// Cancel multiple orders.
78    BatchCancelOrders,
79    /// Amend multiple orders.
80    BatchAmendOrders,
81    /// Mass cancel all orders for an instrument.
82    MassCancel,
83    /// Place a new algo order.
84    OrderAlgo,
85    /// Cancel algo orders.
86    CancelAlgos,
87}
88
89#[derive(
90    Clone,
91    Debug,
92    Display,
93    PartialEq,
94    Eq,
95    Hash,
96    AsRefStr,
97    EnumIter,
98    EnumString,
99    Serialize,
100    Deserialize,
101)]
102#[serde(rename_all = "camelCase")]
103pub enum OKXSubscriptionEvent {
104    Subscribe,
105    Unsubscribe,
106}
107
108#[derive(
109    Clone,
110    Debug,
111    Display,
112    PartialEq,
113    Eq,
114    Hash,
115    AsRefStr,
116    EnumIter,
117    EnumString,
118    Serialize,
119    Deserialize,
120)]
121pub enum OKXWsChannel {
122    // Public Channels
123    #[serde(rename = "instruments")]
124    Instruments,
125    #[serde(rename = "tickers")]
126    Tickers,
127    #[serde(rename = "open-interest")]
128    OpenInterest,
129    #[serde(rename = "trades")]
130    Trades,
131    #[serde(rename = "trades-all")]
132    TradesAll,
133    #[serde(rename = "estimated-price")]
134    EstimatedPrice,
135    #[serde(rename = "mark-price")]
136    MarkPrice,
137    #[serde(rename = "price-limit")]
138    PriceLimit,
139    #[serde(rename = "books")]
140    Books, // Default depth
141    #[serde(rename = "books5")]
142    Books5,
143    #[serde(rename = "books50-l2-tbt")]
144    Books50Tbt,
145    #[serde(rename = "books-l2-tbt")]
146    BooksTbt,
147    #[serde(rename = "books-rpi")]
148    BooksRpi,
149    #[serde(rename = "bbo-tbt")]
150    BboTbt,
151    #[serde(rename = "opt-summary")]
152    OptionSummary,
153    #[serde(rename = "funding-rate")]
154    FundingRate,
155    #[serde(rename = "event-contract-markets")]
156    EventContractMarkets,
157    #[serde(rename = "index-tickers")]
158    IndexTickers,
159    #[serde(rename = "status")]
160    Status,
161    // Private Channels
162    #[serde(rename = "account")]
163    Account,
164    #[serde(rename = "positions")]
165    Positions,
166    // #[display(fmt = "balance_and_position")]
167    // BalanceAndPosition,
168    #[serde(rename = "orders")]
169    Orders,
170    #[serde(rename = "sprd-orders")]
171    SprdOrders,
172    #[serde(rename = "sprd-bbo-tbt")]
173    SprdBboTbt,
174    #[serde(rename = "sprd-books5")]
175    SprdBooks5,
176    #[serde(rename = "sprd-public-trades")]
177    SprdPublicTrades,
178    #[serde(rename = "liquidation-warning")]
179    LiquidationWarning,
180    #[serde(rename = "orders-algo")]
181    OrdersAlgo,
182    #[serde(rename = "algo-advance")]
183    AlgoAdvance,
184    // #[display(fmt = "liquidation-warning")]
185    // LiquidationWarning,
186    // #[display(fmt = "account-greeks")]
187    // AccountGreeks,
188    // #[display(fmt = "rfqs")]
189    // Rfqs,
190    // #[serde(rename = "quotes")]
191    // Quotes,
192    // #[display(fmt = "structure-block-trades")]
193    // StructuredBlock,
194    // #[display(fmt = "spreads")]
195    // Spreads,
196    //
197    // // Trading Channels
198    // #[display(fmt = "orders-spot-margin")]
199    // SpotMarginOrders,
200    // #[display(fmt = "orders-futures")]
201    // FuturesOrders,
202    // #[display(fmt = "orders-swap")]
203    // SwapOrders,
204    // #[display(fmt = "orders-option")]
205    // OptionOrders,
206    //
207    // // Business Channels
208    // #[display(fmt = "deposit-info")]
209    // DepositInfo,
210    // #[display(fmt = "withdrawal-info")]
211    // WithdrawalInfo,
212
213    // Candlesticks
214    #[serde(rename = "candle1s")]
215    Candle1Second,
216    #[serde(rename = "candle1m")]
217    Candle1Minute,
218    #[serde(rename = "candle3m")]
219    Candle3Minute,
220    #[serde(rename = "candle5m")]
221    Candle5Minute,
222    #[serde(rename = "candle15m")]
223    Candle15Minute,
224    #[serde(rename = "candle30m")]
225    Candle30Minute,
226    #[serde(rename = "candle1H")]
227    Candle1Hour,
228    #[serde(rename = "candle2H")]
229    Candle2Hour,
230    #[serde(rename = "candle4H")]
231    Candle4Hour,
232    #[serde(rename = "candle6H")]
233    Candle6Hour,
234    #[serde(rename = "candle12H")]
235    Candle12Hour,
236    #[serde(rename = "candle1D")]
237    Candle1Day,
238    #[serde(rename = "candle2D")]
239    Candle2Day,
240    #[serde(rename = "candle3D")]
241    Candle3Day,
242    #[serde(rename = "candle5D")]
243    Candle5Day,
244    #[serde(rename = "candle1W")]
245    Candle1Week,
246    #[serde(rename = "candle1M")]
247    Candle1Month,
248    #[serde(rename = "candle3M")]
249    Candle3Month,
250    #[serde(rename = "candle6M")]
251    Candle6Month,
252    #[serde(rename = "candle1Y")]
253    Candle1Year,
254
255    // Mark Price Candlesticks
256    #[serde(rename = "mark-price-candle1s")]
257    MarkPriceCandle1Second,
258    #[serde(rename = "mark-price-candle1m")]
259    MarkPriceCandle1Minute,
260    #[serde(rename = "mark-price-candle3m")]
261    MarkPriceCandle3Minute,
262    #[serde(rename = "mark-price-candle5m")]
263    MarkPriceCandle5Minute,
264    #[serde(rename = "mark-price-candle15m")]
265    MarkPriceCandle15Minute,
266    #[serde(rename = "mark-price-candle30m")]
267    MarkPriceCandle30Minute,
268    #[serde(rename = "mark-price-candle1H")]
269    MarkPriceCandle1Hour,
270    #[serde(rename = "mark-price-candle2H")]
271    MarkPriceCandle2Hour,
272    #[serde(rename = "mark-price-candle4H")]
273    MarkPriceCandle4Hour,
274    #[serde(rename = "mark-price-candle6H")]
275    MarkPriceCandle6Hour,
276    #[serde(rename = "mark-price-candle12H")]
277    MarkPriceCandle12Hour,
278    #[serde(rename = "mark-price-candle1D")]
279    MarkPriceCandle1Day,
280    #[serde(rename = "mark-price-candle2D")]
281    MarkPriceCandle2Day,
282    #[serde(rename = "mark-price-candle3D")]
283    MarkPriceCandle3Day,
284    #[serde(rename = "mark-price-candle5D")]
285    MarkPriceCandle5Day,
286    #[serde(rename = "mark-price-candle1W")]
287    MarkPriceCandle1Week,
288    #[serde(rename = "mark-price-candle1M")]
289    MarkPriceCandle1Month,
290    #[serde(rename = "mark-price-candle3M")]
291    MarkPriceCandle3Month,
292}
293
294impl OKXWsChannel {
295    /// Returns `true` for OKX Nitro spread channels, which key on `sprdId`
296    /// rather than `instId` and are served on the business WebSocket.
297    #[must_use]
298    pub const fn is_spread(&self) -> bool {
299        matches!(
300            self,
301            Self::SprdOrders | Self::SprdBboTbt | Self::SprdBooks5 | Self::SprdPublicTrades
302        )
303    }
304
305    /// Returns `true` for channels that feed the adapter's order book
306    /// subscription bookkeeping.
307    #[must_use]
308    pub const fn is_book(&self) -> bool {
309        matches!(
310            self,
311            Self::Books
312                | Self::Books5
313                | Self::Books50Tbt
314                | Self::BooksTbt
315                | Self::BooksRpi
316                | Self::SprdBooks5
317        )
318    }
319}