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
16use nautilus_model::enums::{
17    AggressorSide, LiquiditySide, OptionKind, OrderSide, OrderStatus, OrderType, PositionSide,
18};
19use serde::{Deserialize, Serialize};
20use strum::{AsRefStr, Display, EnumIter, EnumString};
21
22/// Represents the type of book action.
23#[derive(
24    Copy,
25    Clone,
26    Debug,
27    Display,
28    PartialEq,
29    Eq,
30    Hash,
31    AsRefStr,
32    EnumIter,
33    EnumString,
34    Serialize,
35    Deserialize,
36)]
37#[serde(rename_all = "lowercase")]
38pub enum OKXBookAction {
39    /// Incremental update.
40    Update,
41    /// Full snapshot.
42    Snapshot,
43}
44
45/// Represents the possible states of an order throughout its lifecycle.
46#[derive(
47    Copy,
48    Clone,
49    Debug,
50    Display,
51    PartialEq,
52    Eq,
53    Hash,
54    AsRefStr,
55    EnumIter,
56    EnumString,
57    Serialize,
58    Deserialize,
59)]
60pub enum OKXCandleConfirm {
61    /// K-line is incomplete.
62    #[serde(rename = "0")]
63    Partial,
64    /// K-line is completed.
65    #[serde(rename = "1")]
66    Closed,
67}
68
69/// Represents the side of an order or trade (Buy/Sell).
70#[derive(
71    Copy,
72    Clone,
73    Debug,
74    Display,
75    PartialEq,
76    Eq,
77    Hash,
78    AsRefStr,
79    EnumIter,
80    EnumString,
81    Serialize,
82    Deserialize,
83)]
84#[serde(rename_all = "snake_case")]
85pub enum OKXSide {
86    /// Buy side of a trade or order.
87    Buy,
88    /// Sell side of a trade or order.
89    Sell,
90}
91
92impl From<OrderSide> for OKXSide {
93    fn from(value: OrderSide) -> Self {
94        match value {
95            OrderSide::Buy => Self::Buy,
96            OrderSide::Sell => Self::Sell,
97            _ => panic!("Invalid `OrderSide`"),
98        }
99    }
100}
101
102impl From<OKXSide> for AggressorSide {
103    fn from(value: OKXSide) -> Self {
104        match value {
105            OKXSide::Buy => Self::Buyer,
106            OKXSide::Sell => Self::Seller,
107        }
108    }
109}
110
111/// Represents the available order types on OKX.
112#[derive(
113    Copy,
114    Clone,
115    Debug,
116    Display,
117    PartialEq,
118    Eq,
119    Hash,
120    AsRefStr,
121    EnumIter,
122    EnumString,
123    Serialize,
124    Deserialize,
125)]
126#[serde(rename_all = "snake_case")]
127pub enum OKXOrderType {
128    /// Market order, executed immediately at current market price.
129    Market,
130    /// Limit order, executed only at specified price or better.
131    Limit,
132    PostOnly,        // limit only, requires "px" to be provided
133    Fok,             // Market order if "px" is not provided, otherwise limit order
134    Ioc,             // Market order if "px" is not provided, otherwise limit order
135    OptimalLimitIoc, // Market order with immediate-or-cancel order
136    Mmp,             // Market Maker Protection (only applicable to Option in Portfolio Margin mode)
137    MmpAndPostOnly, // Market Maker Protection and Post-only order(only applicable to Option in Portfolio Margin mode)
138}
139
140/// Represents the possible states of an order throughout its lifecycle.
141#[derive(
142    Copy,
143    Clone,
144    Debug,
145    Display,
146    PartialEq,
147    Eq,
148    Hash,
149    AsRefStr,
150    EnumIter,
151    EnumString,
152    Serialize,
153    Deserialize,
154)]
155#[serde(rename_all = "snake_case")]
156pub enum OKXOrderStatus {
157    /// Order has been canceled by user or system.
158    Canceled,
159    Live,
160    PartiallyFilled,
161    Filled,
162    MmpCanceled,
163}
164
165impl From<OrderStatus> for OKXOrderStatus {
166    fn from(value: OrderStatus) -> Self {
167        match value {
168            OrderStatus::Canceled => Self::Canceled,
169            OrderStatus::Accepted => Self::Live,
170            OrderStatus::PartiallyFilled => Self::PartiallyFilled,
171            OrderStatus::Filled => Self::Filled,
172            _ => panic!("Invalid `OrderStatus`"),
173        }
174    }
175}
176
177/// Represents the type of execution that generated a trade.
178#[derive(
179    Copy,
180    Clone,
181    Debug,
182    Default,
183    Display,
184    PartialEq,
185    Eq,
186    Hash,
187    AsRefStr,
188    EnumIter,
189    EnumString,
190    Serialize,
191    Deserialize,
192)]
193pub enum OKXExecType {
194    #[serde(rename = "")]
195    #[default]
196    None,
197    #[serde(rename = "T")]
198    Taker,
199    #[serde(rename = "M")]
200    Maker,
201}
202
203impl From<LiquiditySide> for OKXExecType {
204    fn from(value: LiquiditySide) -> Self {
205        match value {
206            LiquiditySide::NoLiquiditySide => Self::None,
207            LiquiditySide::Taker => Self::Taker,
208            LiquiditySide::Maker => Self::Maker,
209        }
210    }
211}
212
213/// Represents instrument types on OKX.
214#[derive(
215    Copy,
216    Clone,
217    Debug,
218    Display,
219    Default,
220    PartialEq,
221    Eq,
222    Hash,
223    AsRefStr,
224    EnumIter,
225    EnumString,
226    Serialize,
227    Deserialize,
228)]
229#[serde(rename_all = "UPPERCASE")]
230#[cfg_attr(
231    feature = "python",
232    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
233)]
234pub enum OKXInstrumentType {
235    #[default]
236    Any,
237    /// Spot products.
238    Spot,
239    /// Margin products.
240    Margin,
241    /// Swap products.
242    Swap,
243    /// Futures products.
244    Futures,
245    /// Option products.
246    Option,
247}
248
249/// Represents an instrument status on OKX.
250#[derive(
251    Copy,
252    Clone,
253    Debug,
254    Display,
255    PartialEq,
256    Eq,
257    Hash,
258    AsRefStr,
259    EnumIter,
260    EnumString,
261    Serialize,
262    Deserialize,
263)]
264#[serde(rename_all = "snake_case")]
265pub enum OKXInstrumentStatus {
266    Live,
267    Suspend,
268    Preopen,
269    Test,
270}
271
272/// Represents an instrument contract type on OKX.
273#[derive(
274    Copy,
275    Clone,
276    Default,
277    Debug,
278    Display,
279    PartialEq,
280    Eq,
281    Hash,
282    AsRefStr,
283    EnumIter,
284    EnumString,
285    Serialize,
286    Deserialize,
287)]
288#[serde(rename_all = "snake_case")]
289#[cfg_attr(
290    feature = "python",
291    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
292)]
293pub enum OKXContractType {
294    #[serde(rename = "")]
295    #[default]
296    None,
297    Linear,
298    Inverse,
299}
300
301/// Represents an option type on OKX.
302#[derive(
303    Copy,
304    Clone,
305    Debug,
306    Display,
307    PartialEq,
308    Eq,
309    Hash,
310    AsRefStr,
311    EnumIter,
312    EnumString,
313    Serialize,
314    Deserialize,
315)]
316pub enum OKXOptionType {
317    #[serde(rename = "")]
318    None,
319    #[serde(rename = "C")]
320    Call,
321    #[serde(rename = "P")]
322    Put,
323}
324
325impl From<OKXOptionType> for OptionKind {
326    fn from(option_type: OKXOptionType) -> Self {
327        match option_type {
328            OKXOptionType::Call => OptionKind::Call,
329            OKXOptionType::Put => OptionKind::Put,
330            _ => panic!("Invalid `option_type`, was None"),
331        }
332    }
333}
334
335/// Represents the trading mode for OKX orders.
336#[derive(
337    Copy,
338    Clone,
339    Debug,
340    Display,
341    Default,
342    PartialEq,
343    Eq,
344    Hash,
345    AsRefStr,
346    EnumIter,
347    EnumString,
348    Serialize,
349    Deserialize,
350)]
351#[serde(rename_all = "snake_case")]
352#[cfg_attr(
353    feature = "python",
354    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
355)]
356pub enum OKXTradeMode {
357    #[default]
358    Cash,
359    Isolated,
360    Cross,
361    SpotIsolated,
362}
363
364/// Represents an OKX account mode.
365///
366/// # References
367///
368/// <https://www.okx.com/docs-v5/en/#overview-account-mode>
369#[derive(
370    Copy,
371    Clone,
372    Debug,
373    Display,
374    PartialEq,
375    Eq,
376    Hash,
377    AsRefStr,
378    EnumIter,
379    EnumString,
380    Serialize,
381    Deserialize,
382)]
383pub enum OKXAccountMode {
384    #[serde(rename = "Spot mode")]
385    Spot,
386    #[serde(rename = "Spot and futures mode")]
387    SpotAndFutures,
388    #[serde(rename = "Multi-currency margin mode")]
389    MultiCurrencyMarginMode,
390    #[serde(rename = "Portfolio margin mode")]
391    PortfolioMarginMode,
392}
393
394/// Represents the margin mode for OKX accounts.
395///
396/// # Reference
397///
398/// - <https://www.okx.com/en-au/help/iv-isolated-margin-mode>
399/// - <https://www.okx.com/en-au/help/iii-single-currency-margin-cross-margin-trading>
400/// - <https://www.okx.com/en-au/help/iv-multi-currency-margin-mode-cross-margin-trading>
401#[derive(
402    Copy,
403    Clone,
404    Default,
405    Debug,
406    Display,
407    PartialEq,
408    Eq,
409    Hash,
410    AsRefStr,
411    EnumIter,
412    EnumString,
413    Serialize,
414    Deserialize,
415)]
416#[serde(rename_all = "snake_case")]
417#[cfg_attr(
418    feature = "python",
419    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
420)]
421pub enum OKXMarginMode {
422    #[serde(rename = "")]
423    #[default]
424    None,
425    Isolated,
426    Cross,
427}
428
429/// Represents the position mode for OKX accounts.
430///
431/// # References
432///
433/// <https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-position-mode>
434#[derive(
435    Copy,
436    Clone,
437    Default,
438    Debug,
439    Display,
440    PartialEq,
441    Eq,
442    Hash,
443    AsRefStr,
444    EnumIter,
445    EnumString,
446    Serialize,
447    Deserialize,
448)]
449#[cfg_attr(
450    feature = "python",
451    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.okx")
452)]
453pub enum OKXPositionMode {
454    #[default]
455    #[serde(rename = "net_mode")]
456    NetMode,
457    #[serde(rename = "long_short_mode")]
458    LongShortMode,
459}
460
461#[derive(
462    Copy,
463    Clone,
464    Debug,
465    Display,
466    PartialEq,
467    Eq,
468    Hash,
469    AsRefStr,
470    EnumIter,
471    EnumString,
472    Serialize,
473    Deserialize,
474)]
475#[serde(rename_all = "snake_case")]
476pub enum OKXPositionSide {
477    #[serde(rename = "")]
478    None,
479    Net,
480    Long,
481    Short,
482}
483
484#[derive(
485    Copy,
486    Clone,
487    Debug,
488    Display,
489    PartialEq,
490    Eq,
491    Hash,
492    AsRefStr,
493    EnumIter,
494    EnumString,
495    Serialize,
496    Deserialize,
497)]
498#[serde(rename_all = "snake_case")]
499pub enum OKXSelfTradePreventionMode {
500    #[serde(rename = "")]
501    None,
502    CancelMaker,
503    CancelTaker,
504    CancelBoth,
505}
506
507#[derive(
508    Copy,
509    Clone,
510    Debug,
511    Display,
512    PartialEq,
513    Eq,
514    Hash,
515    AsRefStr,
516    EnumIter,
517    EnumString,
518    Serialize,
519    Deserialize,
520)]
521#[serde(rename_all = "snake_case")]
522pub enum OKXTakeProfitKind {
523    #[serde(rename = "")]
524    None,
525    Condition,
526    Limit,
527}
528
529#[derive(
530    Copy,
531    Clone,
532    Debug,
533    Display,
534    PartialEq,
535    Eq,
536    Hash,
537    AsRefStr,
538    EnumIter,
539    EnumString,
540    Serialize,
541    Deserialize,
542)]
543#[serde(rename_all = "snake_case")]
544pub enum OKXTriggerType {
545    #[serde(rename = "")]
546    None,
547    Last,
548    Index,
549    Mark,
550}
551
552impl From<OKXSide> for OrderSide {
553    fn from(side: OKXSide) -> Self {
554        match side {
555            OKXSide::Buy => Self::Buy,
556            OKXSide::Sell => Self::Sell,
557        }
558    }
559}
560
561impl From<OKXExecType> for LiquiditySide {
562    fn from(exec: OKXExecType) -> Self {
563        match exec {
564            OKXExecType::Maker => Self::Maker,
565            OKXExecType::Taker => Self::Taker,
566            OKXExecType::None => Self::NoLiquiditySide,
567        }
568    }
569}
570
571impl From<OKXPositionSide> for PositionSide {
572    fn from(side: OKXPositionSide) -> Self {
573        match side {
574            OKXPositionSide::Long => Self::Long,
575            OKXPositionSide::Short => Self::Short,
576            _ => Self::Flat,
577        }
578    }
579}
580
581impl From<OKXOrderStatus> for OrderStatus {
582    fn from(status: OKXOrderStatus) -> Self {
583        match status {
584            OKXOrderStatus::Live => Self::Accepted,
585            OKXOrderStatus::PartiallyFilled => Self::PartiallyFilled,
586            OKXOrderStatus::Filled => Self::Filled,
587            OKXOrderStatus::Canceled | OKXOrderStatus::MmpCanceled => Self::Canceled,
588        }
589    }
590}
591
592impl From<OKXOrderType> for OrderType {
593    fn from(ord_type: OKXOrderType) -> Self {
594        match ord_type {
595            OKXOrderType::Market => Self::Market,
596            OKXOrderType::Limit
597            | OKXOrderType::PostOnly
598            | OKXOrderType::OptimalLimitIoc
599            | OKXOrderType::Mmp
600            | OKXOrderType::MmpAndPostOnly => Self::Limit,
601            OKXOrderType::Fok | OKXOrderType::Ioc => Self::MarketToLimit,
602        }
603    }
604}
605
606impl From<OrderType> for OKXOrderType {
607    fn from(value: OrderType) -> Self {
608        match value {
609            OrderType::Market => Self::Market,
610            OrderType::Limit => Self::Limit,
611            OrderType::MarketToLimit => Self::Ioc,
612            _ => panic!("Invalid `OrderType` cannot be represented on OKX"),
613        }
614    }
615}
616
617impl From<PositionSide> for OKXPositionSide {
618    fn from(value: PositionSide) -> Self {
619        match value {
620            PositionSide::Long => Self::Long,
621            PositionSide::Short => Self::Short,
622            _ => Self::None,
623        }
624    }
625}
626
627#[derive(
628    Copy,
629    Clone,
630    Debug,
631    Display,
632    PartialEq,
633    Eq,
634    Hash,
635    AsRefStr,
636    EnumIter,
637    EnumString,
638    Serialize,
639    Deserialize,
640)]
641#[serde(rename_all = "snake_case")]
642pub enum OKXAlgoOrderType {
643    Conditional,
644    Oco,
645    Trigger,
646    MoveOrderStop,
647    Iceberg,
648    Twap,
649}
650
651#[derive(
652    Copy,
653    Clone,
654    Debug,
655    Display,
656    PartialEq,
657    Eq,
658    Hash,
659    AsRefStr,
660    EnumIter,
661    EnumString,
662    Serialize,
663    Deserialize,
664)]
665#[serde(rename_all = "snake_case")]
666pub enum OKXAlgoOrderStatus {
667    Live,
668    Pause,
669    PartiallyEffective,
670    Effective,
671    Canceled,
672    OrderFailed,
673    PartiallyFailed,
674}
675
676#[derive(
677    Copy,
678    Clone,
679    Debug,
680    Display,
681    PartialEq,
682    Eq,
683    Hash,
684    AsRefStr,
685    EnumIter,
686    EnumString,
687    Serialize,
688    Deserialize,
689)]
690pub enum OKXTransactionType {
691    #[serde(rename = "1")]
692    Buy,
693    #[serde(rename = "2")]
694    Sell,
695    #[serde(rename = "3")]
696    OpenLong,
697    #[serde(rename = "4")]
698    OpenShort,
699    #[serde(rename = "5")]
700    CloseLong,
701    #[serde(rename = "6")]
702    CloseShort,
703    #[serde(rename = "100")]
704    PartialLiquidationCloseLong,
705    #[serde(rename = "101")]
706    PartialLiquidationCloseShort,
707    #[serde(rename = "102")]
708    PartialLiquidationBuy,
709    #[serde(rename = "103")]
710    PartialLiquidationSell,
711    #[serde(rename = "104")]
712    LiquidationLong,
713    #[serde(rename = "105")]
714    LiquidationShort,
715    #[serde(rename = "106")]
716    LiquidationBuy,
717    #[serde(rename = "107")]
718    LiquidationSell,
719    #[serde(rename = "110")]
720    LiquidationTransferIn,
721    #[serde(rename = "111")]
722    LiquidationTransferOut,
723    #[serde(rename = "118")]
724    SystemTokenConversionTransferIn,
725    #[serde(rename = "119")]
726    SystemTokenConversionTransferOut,
727    #[serde(rename = "125")]
728    AdlCloseLong,
729    #[serde(rename = "126")]
730    AdlCloseShort,
731    #[serde(rename = "127")]
732    AdlBuy,
733    #[serde(rename = "128")]
734    AdlSell,
735    #[serde(rename = "212")]
736    AutoBorrowOfQuickMargin,
737    #[serde(rename = "213")]
738    AutoRepayOfQuickMargin,
739    #[serde(rename = "204")]
740    BlockTradeBuy,
741    #[serde(rename = "205")]
742    BlockTradeSell,
743    #[serde(rename = "206")]
744    BlockTradeOpenLong,
745    #[serde(rename = "207")]
746    BlockTradeOpenShort,
747    #[serde(rename = "208")]
748    BlockTradeCloseOpen,
749    #[serde(rename = "209")]
750    BlockTradeCloseShort,
751    #[serde(rename = "270")]
752    SpreadTradingBuy,
753    #[serde(rename = "271")]
754    SpreadTradingSell,
755    #[serde(rename = "272")]
756    SpreadTradingOpenLong,
757    #[serde(rename = "273")]
758    SpreadTradingOpenShort,
759    #[serde(rename = "274")]
760    SpreadTradingCloseLong,
761    #[serde(rename = "275")]
762    SpreadTradingCloseShort,
763}
764
765#[derive(
766    Copy,
767    Clone,
768    Debug,
769    Display,
770    PartialEq,
771    Eq,
772    Hash,
773    AsRefStr,
774    EnumIter,
775    EnumString,
776    Serialize,
777    Deserialize,
778)]
779pub enum OKXBarSize {
780    #[serde(rename = "1s")]
781    Second1,
782    #[serde(rename = "1m")]
783    Minute1,
784    #[serde(rename = "3m")]
785    Minute3,
786    #[serde(rename = "5m")]
787    Minute5,
788    #[serde(rename = "15m")]
789    Minute15,
790    #[serde(rename = "30m")]
791    Minute30,
792    #[serde(rename = "1H")]
793    Hour1,
794    #[serde(rename = "2H")]
795    Hour2,
796    #[serde(rename = "4H")]
797    Hour4,
798    #[serde(rename = "6H")]
799    Hour6,
800    #[serde(rename = "12H")]
801    Hour12,
802    #[serde(rename = "1D")]
803    Day1,
804    #[serde(rename = "2D")]
805    Day2,
806    #[serde(rename = "3D")]
807    Day3,
808    #[serde(rename = "5D")]
809    Day5,
810    #[serde(rename = "1W")]
811    Week1,
812    #[serde(rename = "1M")]
813    Month1,
814    #[serde(rename = "3M")]
815    Month3,
816}