nautilus_okx/common/
enums.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 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 mapping OKX concepts onto idiomatic Nautilus variants.
17
18use nautilus_model::enums::{
19    AggressorSide, LiquiditySide, OptionKind, OrderSide, OrderStatus, OrderType, PositionSide,
20    TriggerType,
21};
22use serde::{Deserialize, Serialize};
23use strum::{AsRefStr, Display, EnumIter, EnumString};
24
25use crate::common::consts::OKX_CONDITIONAL_ORDER_TYPES;
26
27/// Represents the type of book action.
28#[derive(
29    Copy,
30    Clone,
31    Debug,
32    Display,
33    PartialEq,
34    Eq,
35    Hash,
36    AsRefStr,
37    EnumIter,
38    EnumString,
39    Serialize,
40    Deserialize,
41)]
42#[serde(rename_all = "lowercase")]
43pub enum OKXBookAction {
44    /// Incremental update.
45    Update,
46    /// Full snapshot.
47    Snapshot,
48}
49
50/// Represents the possible states of an order throughout its lifecycle.
51#[derive(
52    Copy,
53    Clone,
54    Debug,
55    Display,
56    PartialEq,
57    Eq,
58    Hash,
59    AsRefStr,
60    EnumIter,
61    EnumString,
62    Serialize,
63    Deserialize,
64)]
65pub enum OKXCandleConfirm {
66    /// K-line is incomplete.
67    #[serde(rename = "0")]
68    Partial,
69    /// K-line is completed.
70    #[serde(rename = "1")]
71    Closed,
72}
73
74/// Represents the side of an order or trade (Buy/Sell).
75#[derive(
76    Copy,
77    Clone,
78    Debug,
79    Display,
80    PartialEq,
81    Eq,
82    Hash,
83    AsRefStr,
84    EnumIter,
85    EnumString,
86    Serialize,
87    Deserialize,
88)]
89#[serde(rename_all = "snake_case")]
90pub enum OKXSide {
91    /// Buy side of a trade or order.
92    Buy,
93    /// Sell side of a trade or order.
94    Sell,
95}
96
97impl From<OrderSide> for OKXSide {
98    fn from(value: OrderSide) -> Self {
99        match value {
100            OrderSide::Buy => Self::Buy,
101            OrderSide::Sell => Self::Sell,
102            _ => panic!("Invalid `OrderSide`"),
103        }
104    }
105}
106
107impl From<OKXSide> for AggressorSide {
108    fn from(value: OKXSide) -> Self {
109        match value {
110            OKXSide::Buy => Self::Buyer,
111            OKXSide::Sell => Self::Seller,
112        }
113    }
114}
115
116/// Represents the available order types on OKX.
117#[derive(
118    Copy,
119    Clone,
120    Debug,
121    Display,
122    PartialEq,
123    Eq,
124    Hash,
125    AsRefStr,
126    EnumIter,
127    EnumString,
128    Serialize,
129    Deserialize,
130)]
131#[serde(rename_all = "snake_case")]
132pub enum OKXOrderType {
133    /// Market order, executed immediately at current market price.
134    Market,
135    /// Limit order, executed only at specified price or better.
136    Limit,
137    PostOnly,        // limit only, requires "px" to be provided
138    Fok,             // Market order if "px" is not provided, otherwise limit order
139    Ioc,             // Market order if "px" is not provided, otherwise limit order
140    OptimalLimitIoc, // Market order with immediate-or-cancel order
141    Mmp,             // Market Maker Protection (only applicable to Option in Portfolio Margin mode)
142    MmpAndPostOnly, // Market Maker Protection and Post-only order(only applicable to Option in Portfolio Margin mode)
143    Trigger,        // Conditional/algo order (stop orders, etc.)
144}
145
146/// Represents the possible states of an order throughout its lifecycle.
147#[derive(
148    Copy,
149    Clone,
150    Debug,
151    Display,
152    PartialEq,
153    Eq,
154    Hash,
155    AsRefStr,
156    EnumIter,
157    EnumString,
158    Serialize,
159    Deserialize,
160)]
161#[serde(rename_all = "snake_case")]
162#[cfg_attr(
163    feature = "python",
164    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
165)]
166pub enum OKXOrderStatus {
167    Canceled,
168    Live,
169    Effective,
170    PartiallyFilled,
171    Filled,
172    MmpCanceled,
173    OrderPlaced,
174}
175
176impl From<OrderStatus> for OKXOrderStatus {
177    fn from(value: OrderStatus) -> Self {
178        match value {
179            OrderStatus::Canceled => Self::Canceled,
180            OrderStatus::Accepted => Self::Live,
181            OrderStatus::PartiallyFilled => Self::PartiallyFilled,
182            OrderStatus::Filled => Self::Filled,
183            _ => panic!("Invalid `OrderStatus`"),
184        }
185    }
186}
187
188/// Represents the type of execution that generated a trade.
189#[derive(
190    Copy,
191    Clone,
192    Debug,
193    Default,
194    Display,
195    PartialEq,
196    Eq,
197    Hash,
198    AsRefStr,
199    EnumIter,
200    EnumString,
201    Serialize,
202    Deserialize,
203)]
204pub enum OKXExecType {
205    #[serde(rename = "")]
206    #[default]
207    None,
208    #[serde(rename = "T")]
209    Taker,
210    #[serde(rename = "M")]
211    Maker,
212}
213
214impl From<LiquiditySide> for OKXExecType {
215    fn from(value: LiquiditySide) -> Self {
216        match value {
217            LiquiditySide::NoLiquiditySide => Self::None,
218            LiquiditySide::Taker => Self::Taker,
219            LiquiditySide::Maker => Self::Maker,
220        }
221    }
222}
223
224/// Represents instrument types on OKX.
225#[derive(
226    Copy,
227    Clone,
228    Debug,
229    Display,
230    Default,
231    PartialEq,
232    Eq,
233    Hash,
234    AsRefStr,
235    EnumIter,
236    EnumString,
237    Serialize,
238    Deserialize,
239)]
240#[serde(rename_all = "UPPERCASE")]
241#[cfg_attr(
242    feature = "python",
243    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
244)]
245pub enum OKXInstrumentType {
246    #[default]
247    Any,
248    /// Spot products.
249    Spot,
250    /// Margin products.
251    Margin,
252    /// Swap products.
253    Swap,
254    /// Futures products.
255    Futures,
256    /// Option products.
257    Option,
258}
259
260/// Represents an instrument status on OKX.
261#[derive(
262    Copy,
263    Clone,
264    Debug,
265    Display,
266    PartialEq,
267    Eq,
268    Hash,
269    AsRefStr,
270    EnumIter,
271    EnumString,
272    Serialize,
273    Deserialize,
274)]
275#[serde(rename_all = "snake_case")]
276pub enum OKXInstrumentStatus {
277    Live,
278    Suspend,
279    Preopen,
280    Test,
281}
282
283/// Represents an instrument contract type on OKX.
284#[derive(
285    Copy,
286    Clone,
287    Default,
288    Debug,
289    Display,
290    PartialEq,
291    Eq,
292    Hash,
293    AsRefStr,
294    EnumIter,
295    EnumString,
296    Serialize,
297    Deserialize,
298)]
299#[serde(rename_all = "snake_case")]
300#[cfg_attr(
301    feature = "python",
302    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
303)]
304pub enum OKXContractType {
305    #[serde(rename = "")]
306    #[default]
307    None,
308    Linear,
309    Inverse,
310}
311
312/// Represents an option type on OKX.
313#[derive(
314    Copy,
315    Clone,
316    Debug,
317    Display,
318    PartialEq,
319    Eq,
320    Hash,
321    AsRefStr,
322    EnumIter,
323    EnumString,
324    Serialize,
325    Deserialize,
326)]
327pub enum OKXOptionType {
328    #[serde(rename = "")]
329    None,
330    #[serde(rename = "C")]
331    Call,
332    #[serde(rename = "P")]
333    Put,
334}
335
336impl From<OKXOptionType> for OptionKind {
337    fn from(option_type: OKXOptionType) -> Self {
338        match option_type {
339            OKXOptionType::Call => OptionKind::Call,
340            OKXOptionType::Put => OptionKind::Put,
341            _ => panic!("Invalid `option_type`, was None"),
342        }
343    }
344}
345
346/// Represents the trading mode for OKX orders.
347#[derive(
348    Copy,
349    Clone,
350    Debug,
351    Display,
352    Default,
353    PartialEq,
354    Eq,
355    Hash,
356    AsRefStr,
357    EnumIter,
358    EnumString,
359    Serialize,
360    Deserialize,
361)]
362#[serde(rename_all = "snake_case")]
363#[strum(ascii_case_insensitive)]
364#[cfg_attr(
365    feature = "python",
366    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
367)]
368pub enum OKXTradeMode {
369    #[default]
370    Cash,
371    Isolated,
372    Cross,
373    #[strum(serialize = "spot_isolated")]
374    SpotIsolated,
375}
376
377/// Represents an OKX account mode.
378///
379/// # References
380///
381/// <https://www.okx.com/docs-v5/en/#overview-account-mode>
382#[derive(
383    Copy,
384    Clone,
385    Debug,
386    Display,
387    PartialEq,
388    Eq,
389    Hash,
390    AsRefStr,
391    EnumIter,
392    EnumString,
393    Serialize,
394    Deserialize,
395)]
396pub enum OKXAccountMode {
397    #[serde(rename = "Spot mode")]
398    Spot,
399    #[serde(rename = "Spot and futures mode")]
400    SpotAndFutures,
401    #[serde(rename = "Multi-currency margin mode")]
402    MultiCurrencyMarginMode,
403    #[serde(rename = "Portfolio margin mode")]
404    PortfolioMarginMode,
405}
406
407/// Represents the margin mode for OKX accounts.
408///
409/// # Reference
410///
411/// - <https://www.okx.com/en-au/help/iv-isolated-margin-mode>
412/// - <https://www.okx.com/en-au/help/iii-single-currency-margin-cross-margin-trading>
413/// - <https://www.okx.com/en-au/help/iv-multi-currency-margin-mode-cross-margin-trading>
414#[derive(
415    Copy,
416    Clone,
417    Default,
418    Debug,
419    Display,
420    PartialEq,
421    Eq,
422    Hash,
423    AsRefStr,
424    EnumIter,
425    EnumString,
426    Serialize,
427    Deserialize,
428)]
429#[serde(rename_all = "snake_case")]
430#[cfg_attr(
431    feature = "python",
432    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
433)]
434pub enum OKXMarginMode {
435    #[serde(rename = "")]
436    #[default]
437    None,
438    Isolated,
439    Cross,
440}
441
442/// Represents the position mode for OKX accounts.
443///
444/// # References
445///
446/// <https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-position-mode>
447#[derive(
448    Copy,
449    Clone,
450    Default,
451    Debug,
452    Display,
453    PartialEq,
454    Eq,
455    Hash,
456    AsRefStr,
457    EnumIter,
458    EnumString,
459    Serialize,
460    Deserialize,
461)]
462#[cfg_attr(
463    feature = "python",
464    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
465)]
466pub enum OKXPositionMode {
467    #[default]
468    #[serde(rename = "net_mode")]
469    NetMode,
470    #[serde(rename = "long_short_mode")]
471    LongShortMode,
472}
473
474#[derive(
475    Copy,
476    Clone,
477    Debug,
478    Display,
479    PartialEq,
480    Eq,
481    Hash,
482    AsRefStr,
483    EnumIter,
484    EnumString,
485    Serialize,
486    Deserialize,
487)]
488#[serde(rename_all = "snake_case")]
489pub enum OKXPositionSide {
490    #[serde(rename = "")]
491    None,
492    Net,
493    Long,
494    Short,
495}
496
497#[derive(
498    Copy,
499    Clone,
500    Debug,
501    Display,
502    PartialEq,
503    Eq,
504    Hash,
505    AsRefStr,
506    EnumIter,
507    EnumString,
508    Serialize,
509    Deserialize,
510)]
511#[serde(rename_all = "snake_case")]
512pub enum OKXSelfTradePreventionMode {
513    #[serde(rename = "")]
514    None,
515    CancelMaker,
516    CancelTaker,
517    CancelBoth,
518}
519
520#[derive(
521    Copy,
522    Clone,
523    Debug,
524    Display,
525    PartialEq,
526    Eq,
527    Hash,
528    AsRefStr,
529    EnumIter,
530    EnumString,
531    Serialize,
532    Deserialize,
533)]
534#[serde(rename_all = "snake_case")]
535pub enum OKXTakeProfitKind {
536    #[serde(rename = "")]
537    None,
538    Condition,
539    Limit,
540}
541
542#[derive(
543    Copy,
544    Clone,
545    Debug,
546    Display,
547    PartialEq,
548    Eq,
549    Hash,
550    AsRefStr,
551    EnumIter,
552    EnumString,
553    Serialize,
554    Deserialize,
555)]
556#[serde(rename_all = "snake_case")]
557pub enum OKXTriggerType {
558    #[serde(rename = "")]
559    None,
560    Last,
561    Index,
562    Mark,
563}
564
565impl From<TriggerType> for OKXTriggerType {
566    fn from(value: TriggerType) -> Self {
567        match value {
568            TriggerType::LastPrice => Self::Last,
569            TriggerType::MarkPrice => Self::Mark,
570            TriggerType::IndexPrice => Self::Index,
571            _ => Self::Last,
572        }
573    }
574}
575
576/// Represents an OKX order book channel.
577#[derive(Copy, Clone, Debug, PartialEq, Eq)]
578pub enum OKXBookChannel {
579    /// Standard depth-first book channel (`books`).
580    Book,
581    /// Low-latency 400-depth channel (`books-l2-tbt`).
582    BookL2Tbt,
583    /// Low-latency 50-depth channel (`books50-l2-tbt`).
584    Books50L2Tbt,
585}
586
587/// Represents OKX VIP level tiers for trading fee structure and API limits.
588///
589/// VIP levels determine:
590/// - Trading fee discounts.
591/// - API rate limits.
592/// - Access to advanced order book channels (L2/L3 depth).
593///
594/// Higher VIP levels (VIP4+) get access to:
595/// - "books50-l2-tbt" channel (50 depth, 10ms updates).
596/// - "bbo-tbt" channel (1 depth, 10ms updates).
597///
598/// VIP5+ get access to:
599/// - "books-l2-tbt" channel (400 depth, 10ms updates).
600#[derive(
601    Copy,
602    Clone,
603    Debug,
604    Display,
605    PartialEq,
606    Eq,
607    PartialOrd,
608    Ord,
609    Hash,
610    AsRefStr,
611    EnumIter,
612    EnumString,
613    Serialize,
614    Deserialize,
615)]
616#[cfg_attr(
617    feature = "python",
618    pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.adapters")
619)]
620pub enum OKXVipLevel {
621    /// VIP level 0 (default tier).
622    #[serde(rename = "0")]
623    #[strum(serialize = "0")]
624    Vip0 = 0,
625    /// VIP level 1.
626    #[serde(rename = "1")]
627    #[strum(serialize = "1")]
628    Vip1 = 1,
629    /// VIP level 2.
630    #[serde(rename = "2")]
631    #[strum(serialize = "2")]
632    Vip2 = 2,
633    /// VIP level 3.
634    #[serde(rename = "3")]
635    #[strum(serialize = "3")]
636    Vip3 = 3,
637    /// VIP level 4 (can access books50-l2-tbt channel).
638    #[serde(rename = "4")]
639    #[strum(serialize = "4")]
640    Vip4 = 4,
641    /// VIP level 5 (can access books-l2-tbt channel).
642    #[serde(rename = "5")]
643    #[strum(serialize = "5")]
644    Vip5 = 5,
645    /// VIP level 6.
646    #[serde(rename = "6")]
647    #[strum(serialize = "6")]
648    Vip6 = 6,
649    /// VIP level 7.
650    #[serde(rename = "7")]
651    #[strum(serialize = "7")]
652    Vip7 = 7,
653    /// VIP level 8.
654    #[serde(rename = "8")]
655    #[strum(serialize = "8")]
656    Vip8 = 8,
657    /// VIP level 9 (highest tier).
658    #[serde(rename = "9")]
659    #[strum(serialize = "9")]
660    Vip9 = 9,
661}
662
663impl From<u8> for OKXVipLevel {
664    fn from(value: u8) -> Self {
665        match value {
666            0 => Self::Vip0,
667            1 => Self::Vip1,
668            2 => Self::Vip2,
669            3 => Self::Vip3,
670            4 => Self::Vip4,
671            5 => Self::Vip5,
672            6 => Self::Vip6,
673            7 => Self::Vip7,
674            8 => Self::Vip8,
675            9 => Self::Vip9,
676            _ => {
677                tracing::warn!("Invalid VIP level {value}, defaulting to Vip0");
678                Self::Vip0
679            }
680        }
681    }
682}
683
684impl From<OKXSide> for OrderSide {
685    fn from(side: OKXSide) -> Self {
686        match side {
687            OKXSide::Buy => Self::Buy,
688            OKXSide::Sell => Self::Sell,
689        }
690    }
691}
692
693impl From<OKXExecType> for LiquiditySide {
694    fn from(exec: OKXExecType) -> Self {
695        match exec {
696            OKXExecType::Maker => Self::Maker,
697            OKXExecType::Taker => Self::Taker,
698            OKXExecType::None => Self::NoLiquiditySide,
699        }
700    }
701}
702
703impl From<OKXPositionSide> for PositionSide {
704    fn from(side: OKXPositionSide) -> Self {
705        match side {
706            OKXPositionSide::Long => Self::Long,
707            OKXPositionSide::Short => Self::Short,
708            _ => Self::Flat,
709        }
710    }
711}
712
713impl From<OKXOrderStatus> for OrderStatus {
714    fn from(status: OKXOrderStatus) -> Self {
715        match status {
716            OKXOrderStatus::Live => Self::Accepted,
717            OKXOrderStatus::Effective => Self::Triggered,
718            OKXOrderStatus::PartiallyFilled => Self::PartiallyFilled,
719            OKXOrderStatus::Filled => Self::Filled,
720            OKXOrderStatus::Canceled | OKXOrderStatus::MmpCanceled => Self::Canceled,
721            OKXOrderStatus::OrderPlaced => Self::Triggered,
722        }
723    }
724}
725
726impl From<OKXOrderType> for OrderType {
727    fn from(ord_type: OKXOrderType) -> Self {
728        match ord_type {
729            OKXOrderType::Market => Self::Market,
730            OKXOrderType::Limit
731            | OKXOrderType::PostOnly
732            | OKXOrderType::OptimalLimitIoc
733            | OKXOrderType::Mmp
734            | OKXOrderType::MmpAndPostOnly => Self::Limit,
735            OKXOrderType::Fok | OKXOrderType::Ioc => Self::MarketToLimit,
736            OKXOrderType::Trigger => Self::StopMarket,
737        }
738    }
739}
740
741impl From<OrderType> for OKXOrderType {
742    fn from(value: OrderType) -> Self {
743        match value {
744            OrderType::Market => Self::Market,
745            OrderType::Limit => Self::Limit,
746            OrderType::MarketToLimit => Self::Ioc,
747            // Conditional orders will be handled separately via algo orders
748            OrderType::StopMarket
749            | OrderType::StopLimit
750            | OrderType::MarketIfTouched
751            | OrderType::LimitIfTouched => {
752                panic!("Conditional order types must use OKXAlgoOrderType")
753            }
754            _ => panic!("Invalid `OrderType` cannot be represented on OKX"),
755        }
756    }
757}
758
759impl From<PositionSide> for OKXPositionSide {
760    fn from(value: PositionSide) -> Self {
761        match value {
762            PositionSide::Long => Self::Long,
763            PositionSide::Short => Self::Short,
764            _ => Self::None,
765        }
766    }
767}
768
769#[derive(
770    Copy,
771    Clone,
772    Debug,
773    Display,
774    PartialEq,
775    Eq,
776    Hash,
777    AsRefStr,
778    EnumIter,
779    EnumString,
780    Serialize,
781    Deserialize,
782)]
783#[serde(rename_all = "snake_case")]
784pub enum OKXAlgoOrderType {
785    Conditional,
786    Oco,
787    Trigger,
788    MoveOrderStop,
789    Iceberg,
790    Twap,
791}
792
793/// Helper to determine if an order type requires algo order handling.
794pub fn is_conditional_order(order_type: OrderType) -> bool {
795    OKX_CONDITIONAL_ORDER_TYPES.contains(&order_type)
796}
797
798/// Converts Nautilus conditional order types to OKX algo order type.
799///
800/// # Errors
801///
802/// Returns an error if the provided `order_type` is not a conditional order type.
803pub fn conditional_order_to_algo_type(order_type: OrderType) -> anyhow::Result<OKXAlgoOrderType> {
804    match order_type {
805        OrderType::StopMarket
806        | OrderType::StopLimit
807        | OrderType::MarketIfTouched
808        | OrderType::LimitIfTouched => Ok(OKXAlgoOrderType::Trigger),
809        _ => anyhow::bail!("Not a conditional order type: {order_type:?}"),
810    }
811}
812
813#[derive(
814    Copy,
815    Clone,
816    Debug,
817    Display,
818    PartialEq,
819    Eq,
820    Hash,
821    AsRefStr,
822    EnumIter,
823    EnumString,
824    Serialize,
825    Deserialize,
826)]
827#[serde(rename_all = "snake_case")]
828pub enum OKXAlgoOrderStatus {
829    Live,
830    Pause,
831    PartiallyEffective,
832    Effective,
833    Canceled,
834    OrderFailed,
835    PartiallyFailed,
836}
837
838#[derive(
839    Copy,
840    Clone,
841    Debug,
842    Display,
843    PartialEq,
844    Eq,
845    Hash,
846    AsRefStr,
847    EnumIter,
848    EnumString,
849    Serialize,
850    Deserialize,
851)]
852pub enum OKXTransactionType {
853    #[serde(rename = "1")]
854    Buy,
855    #[serde(rename = "2")]
856    Sell,
857    #[serde(rename = "3")]
858    OpenLong,
859    #[serde(rename = "4")]
860    OpenShort,
861    #[serde(rename = "5")]
862    CloseLong,
863    #[serde(rename = "6")]
864    CloseShort,
865    #[serde(rename = "100")]
866    PartialLiquidationCloseLong,
867    #[serde(rename = "101")]
868    PartialLiquidationCloseShort,
869    #[serde(rename = "102")]
870    PartialLiquidationBuy,
871    #[serde(rename = "103")]
872    PartialLiquidationSell,
873    #[serde(rename = "104")]
874    LiquidationLong,
875    #[serde(rename = "105")]
876    LiquidationShort,
877    #[serde(rename = "106")]
878    LiquidationBuy,
879    #[serde(rename = "107")]
880    LiquidationSell,
881    #[serde(rename = "110")]
882    LiquidationTransferIn,
883    #[serde(rename = "111")]
884    LiquidationTransferOut,
885    #[serde(rename = "118")]
886    SystemTokenConversionTransferIn,
887    #[serde(rename = "119")]
888    SystemTokenConversionTransferOut,
889    #[serde(rename = "125")]
890    AdlCloseLong,
891    #[serde(rename = "126")]
892    AdlCloseShort,
893    #[serde(rename = "127")]
894    AdlBuy,
895    #[serde(rename = "128")]
896    AdlSell,
897    #[serde(rename = "212")]
898    AutoBorrowOfQuickMargin,
899    #[serde(rename = "213")]
900    AutoRepayOfQuickMargin,
901    #[serde(rename = "204")]
902    BlockTradeBuy,
903    #[serde(rename = "205")]
904    BlockTradeSell,
905    #[serde(rename = "206")]
906    BlockTradeOpenLong,
907    #[serde(rename = "207")]
908    BlockTradeOpenShort,
909    #[serde(rename = "208")]
910    BlockTradeCloseOpen,
911    #[serde(rename = "209")]
912    BlockTradeCloseShort,
913    #[serde(rename = "270")]
914    SpreadTradingBuy,
915    #[serde(rename = "271")]
916    SpreadTradingSell,
917    #[serde(rename = "272")]
918    SpreadTradingOpenLong,
919    #[serde(rename = "273")]
920    SpreadTradingOpenShort,
921    #[serde(rename = "274")]
922    SpreadTradingCloseLong,
923    #[serde(rename = "275")]
924    SpreadTradingCloseShort,
925}
926
927#[derive(
928    Copy,
929    Clone,
930    Debug,
931    Display,
932    PartialEq,
933    Eq,
934    Hash,
935    AsRefStr,
936    EnumIter,
937    EnumString,
938    Serialize,
939    Deserialize,
940)]
941pub enum OKXBarSize {
942    #[serde(rename = "1s")]
943    Second1,
944    #[serde(rename = "1m")]
945    Minute1,
946    #[serde(rename = "3m")]
947    Minute3,
948    #[serde(rename = "5m")]
949    Minute5,
950    #[serde(rename = "15m")]
951    Minute15,
952    #[serde(rename = "30m")]
953    Minute30,
954    #[serde(rename = "1H")]
955    Hour1,
956    #[serde(rename = "2H")]
957    Hour2,
958    #[serde(rename = "4H")]
959    Hour4,
960    #[serde(rename = "6H")]
961    Hour6,
962    #[serde(rename = "12H")]
963    Hour12,
964    #[serde(rename = "1D")]
965    Day1,
966    #[serde(rename = "2D")]
967    Day2,
968    #[serde(rename = "3D")]
969    Day3,
970    #[serde(rename = "5D")]
971    Day5,
972    #[serde(rename = "1W")]
973    Week1,
974    #[serde(rename = "1M")]
975    Month1,
976    #[serde(rename = "3M")]
977    Month3,
978}