1use std::{str::FromStr, sync::OnceLock};
19
20use ahash::AHashSet;
21use serde::{Deserialize, Deserializer, Serialize, Serializer};
22use strum::{AsRefStr, Display, EnumIter, EnumString, FromRepr};
23
24use crate::enum_strum_serde;
25
26pub trait FromU8 {
28 fn from_u8(value: u8) -> Option<Self>
32 where
33 Self: Sized;
34}
35
36pub trait FromU16 {
38 fn from_u16(value: u16) -> Option<Self>
42 where
43 Self: Sized;
44}
45
46#[repr(C)]
48#[derive(
49 Copy,
50 Clone,
51 Debug,
52 Display,
53 Hash,
54 PartialEq,
55 Eq,
56 PartialOrd,
57 Ord,
58 AsRefStr,
59 FromRepr,
60 EnumIter,
61 EnumString,
62)]
63#[strum(ascii_case_insensitive)]
64#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
65#[cfg_attr(
66 feature = "python",
67 pyo3::pyclass(
68 frozen,
69 eq,
70 eq_int,
71 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
72 from_py_object,
73 rename_all = "SCREAMING_SNAKE_CASE",
74 )
75)]
76#[cfg_attr(
77 feature = "python",
78 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
79)]
80pub enum AccountType {
81 Cash = 1,
83 Margin = 2,
85 Betting = 3,
87 Wallet = 4,
89}
90
91#[repr(C)]
93#[derive(
94 Copy,
95 Clone,
96 Debug,
97 Display,
98 Hash,
99 PartialEq,
100 Eq,
101 PartialOrd,
102 Ord,
103 AsRefStr,
104 FromRepr,
105 EnumIter,
106 EnumString,
107)]
108#[strum(ascii_case_insensitive)]
109#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
110#[cfg_attr(
111 feature = "python",
112 pyo3::pyclass(
113 frozen,
114 eq,
115 eq_int,
116 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
117 from_py_object,
118 rename_all = "SCREAMING_SNAKE_CASE",
119 )
120)]
121#[cfg_attr(
122 feature = "python",
123 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
124)]
125pub enum AggregationSource {
126 External = 1,
128 Internal = 2,
130}
131
132#[repr(C)]
134#[derive(
135 Copy,
136 Clone,
137 Debug,
138 Default,
139 Display,
140 Hash,
141 PartialEq,
142 Eq,
143 PartialOrd,
144 Ord,
145 AsRefStr,
146 FromRepr,
147 EnumIter,
148 EnumString,
149)]
150#[strum(ascii_case_insensitive)]
151#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
152#[cfg_attr(
153 feature = "python",
154 pyo3::pyclass(
155 frozen,
156 eq,
157 eq_int,
158 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
159 from_py_object,
160 rename_all = "SCREAMING_SNAKE_CASE",
161 )
162)]
163#[cfg_attr(
164 feature = "python",
165 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
166)]
167pub enum AggressorSide {
168 #[default]
170 NoAggressor = 0,
171 Buyer = 1,
173 Seller = 2,
175}
176
177impl FromU8 for AggressorSide {
178 fn from_u8(value: u8) -> Option<Self> {
179 match value {
180 0 => Some(Self::NoAggressor),
181 1 => Some(Self::Buyer),
182 2 => Some(Self::Seller),
183 _ => None,
184 }
185 }
186}
187
188#[repr(C)]
190#[derive(
191 Copy,
192 Clone,
193 Debug,
194 Display,
195 Hash,
196 PartialEq,
197 Eq,
198 PartialOrd,
199 Ord,
200 AsRefStr,
201 FromRepr,
202 EnumIter,
203 EnumString,
204)]
205#[strum(ascii_case_insensitive)]
206#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
207#[cfg_attr(
208 feature = "python",
209 pyo3::pyclass(
210 frozen,
211 eq,
212 eq_int,
213 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
214 from_py_object,
215 rename_all = "SCREAMING_SNAKE_CASE",
216 )
217)]
218#[cfg_attr(
219 feature = "python",
220 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
221)]
222#[allow(non_camel_case_types)]
223pub enum AssetClass {
224 FX = 1,
226 Equity = 2,
228 Commodity = 3,
230 Debt = 4,
232 Index = 5,
234 Cryptocurrency = 6,
236 Alternative = 7,
238}
239
240impl FromU8 for AssetClass {
241 fn from_u8(value: u8) -> Option<Self> {
242 match value {
243 1 => Some(Self::FX),
244 2 => Some(Self::Equity),
245 3 => Some(Self::Commodity),
246 4 => Some(Self::Debt),
247 5 => Some(Self::Index),
248 6 => Some(Self::Cryptocurrency),
249 7 => Some(Self::Alternative),
250 _ => None,
251 }
252 }
253}
254
255#[repr(C)]
257#[derive(
258 Copy,
259 Clone,
260 Debug,
261 Display,
262 Hash,
263 PartialEq,
264 Eq,
265 PartialOrd,
266 Ord,
267 AsRefStr,
268 FromRepr,
269 EnumIter,
270 EnumString,
271)]
272#[strum(ascii_case_insensitive)]
273#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
274#[cfg_attr(
275 feature = "python",
276 pyo3::pyclass(
277 frozen,
278 eq,
279 eq_int,
280 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
281 from_py_object,
282 rename_all = "SCREAMING_SNAKE_CASE",
283 )
284)]
285#[cfg_attr(
286 feature = "python",
287 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
288)]
289pub enum BarAggregation {
290 Tick = 1,
292 TickImbalance = 2,
294 TickRuns = 3,
296 Volume = 4,
298 VolumeImbalance = 5,
300 VolumeRuns = 6,
302 Value = 7,
304 ValueImbalance = 8,
306 ValueRuns = 9,
308 Millisecond = 10,
310 Second = 11,
312 Minute = 12,
314 Hour = 13,
316 Day = 14,
318 Week = 15,
320 Month = 16,
322 Year = 17,
324 Renko = 18,
326}
327
328#[repr(C)]
330#[derive(
331 Copy,
332 Clone,
333 Debug,
334 Default,
335 Display,
336 Hash,
337 PartialEq,
338 Eq,
339 PartialOrd,
340 Ord,
341 AsRefStr,
342 FromRepr,
343 EnumIter,
344 EnumString,
345)]
346#[strum(ascii_case_insensitive)]
347#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
348#[cfg_attr(
349 feature = "python",
350 pyo3::pyclass(
351 frozen,
352 eq,
353 eq_int,
354 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
355 from_py_object,
356 rename_all = "SCREAMING_SNAKE_CASE",
357 )
358)]
359#[cfg_attr(
360 feature = "python",
361 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
362)]
363pub enum BarIntervalType {
364 #[default]
366 LeftOpen = 1,
367 RightOpen = 2,
369}
370
371#[repr(C)]
373#[derive(
374 Copy,
375 Clone,
376 Debug,
377 Display,
378 Hash,
379 PartialEq,
380 Eq,
381 PartialOrd,
382 Ord,
383 AsRefStr,
384 FromRepr,
385 EnumIter,
386 EnumString,
387)]
388#[strum(ascii_case_insensitive)]
389#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
390#[cfg_attr(
391 feature = "python",
392 pyo3::pyclass(
393 frozen,
394 eq,
395 eq_int,
396 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
397 from_py_object,
398 rename_all = "SCREAMING_SNAKE_CASE",
399 )
400)]
401#[cfg_attr(
402 feature = "python",
403 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
404)]
405pub enum BetSide {
406 Back = 1,
408 Lay = 2,
410}
411
412impl BetSide {
413 #[must_use]
415 pub fn opposite(&self) -> Self {
416 match self {
417 Self::Back => Self::Lay,
418 Self::Lay => Self::Back,
419 }
420 }
421}
422
423impl From<OrderSide> for BetSide {
424 fn from(side: OrderSide) -> Self {
430 match side {
431 OrderSide::Buy => Self::Back,
432 OrderSide::Sell => Self::Lay,
433 OrderSide::NoOrderSide => panic!("Invalid `OrderSide` for `BetSide`, was {side}"),
434 }
435 }
436}
437
438#[repr(C)]
440#[derive(
441 Copy,
442 Clone,
443 Debug,
444 Display,
445 Hash,
446 PartialEq,
447 Eq,
448 PartialOrd,
449 Ord,
450 AsRefStr,
451 FromRepr,
452 EnumIter,
453 EnumString,
454)]
455#[strum(ascii_case_insensitive)]
456#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
457#[cfg_attr(
458 feature = "python",
459 pyo3::pyclass(
460 frozen,
461 eq,
462 eq_int,
463 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
464 from_py_object,
465 rename_all = "SCREAMING_SNAKE_CASE",
466 )
467)]
468#[cfg_attr(
469 feature = "python",
470 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
471)]
472pub enum BookAction {
473 Add = 1,
475 Update = 2,
477 Delete = 3,
479 Clear = 4,
481}
482
483impl FromU8 for BookAction {
484 fn from_u8(value: u8) -> Option<Self> {
485 match value {
486 1 => Some(Self::Add),
487 2 => Some(Self::Update),
488 3 => Some(Self::Delete),
489 4 => Some(Self::Clear),
490 _ => None,
491 }
492 }
493}
494
495#[repr(C)]
497#[derive(
498 Copy,
499 Clone,
500 Debug,
501 Display,
502 Hash,
503 PartialEq,
504 Eq,
505 PartialOrd,
506 Ord,
507 AsRefStr,
508 FromRepr,
509 EnumIter,
510 EnumString,
511)]
512#[strum(ascii_case_insensitive)]
513#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
514#[cfg_attr(
515 feature = "python",
516 pyo3::pyclass(
517 frozen,
518 eq,
519 eq_int,
520 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
521 from_py_object,
522 rename_all = "SCREAMING_SNAKE_CASE",
523 )
524)]
525#[cfg_attr(
526 feature = "python",
527 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
528)]
529#[allow(non_camel_case_types)]
530pub enum BookType {
531 L1_MBP = 1,
533 L2_MBP = 2,
535 L3_MBO = 3,
537}
538
539impl FromU8 for BookType {
540 fn from_u8(value: u8) -> Option<Self> {
541 match value {
542 1 => Some(Self::L1_MBP),
543 2 => Some(Self::L2_MBP),
544 3 => Some(Self::L3_MBO),
545 _ => None,
546 }
547 }
548}
549
550#[repr(C)]
554#[derive(
555 Copy,
556 Clone,
557 Debug,
558 Default,
559 Display,
560 Hash,
561 PartialEq,
562 Eq,
563 PartialOrd,
564 Ord,
565 AsRefStr,
566 FromRepr,
567 EnumIter,
568 EnumString,
569)]
570#[strum(ascii_case_insensitive)]
571#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
572#[cfg_attr(
573 feature = "python",
574 pyo3::pyclass(
575 frozen,
576 eq,
577 eq_int,
578 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
579 from_py_object,
580 rename_all = "SCREAMING_SNAKE_CASE",
581 )
582)]
583#[cfg_attr(
584 feature = "python",
585 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
586)]
587pub enum ContingencyType {
588 #[default]
590 NoContingency = 0,
591 Oco = 1,
593 Oto = 2,
595 Ouo = 3,
597}
598
599#[repr(C)]
601#[derive(
602 Copy,
603 Clone,
604 Debug,
605 Display,
606 Hash,
607 PartialEq,
608 Eq,
609 PartialOrd,
610 Ord,
611 AsRefStr,
612 FromRepr,
613 EnumIter,
614 EnumString,
615)]
616#[strum(ascii_case_insensitive)]
617#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
618#[cfg_attr(
619 feature = "python",
620 pyo3::pyclass(
621 frozen,
622 eq,
623 eq_int,
624 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
625 from_py_object,
626 rename_all = "SCREAMING_SNAKE_CASE",
627 )
628)]
629#[cfg_attr(
630 feature = "python",
631 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
632)]
633pub enum CurrencyType {
634 Crypto = 1,
636 Fiat = 2,
638 CommodityBacked = 3,
640}
641
642#[repr(C)]
644#[derive(
645 Copy,
646 Clone,
647 Debug,
648 Display,
649 Hash,
650 PartialEq,
651 Eq,
652 PartialOrd,
653 Ord,
654 AsRefStr,
655 FromRepr,
656 EnumIter,
657 EnumString,
658)]
659#[strum(ascii_case_insensitive)]
660#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
661#[cfg_attr(
662 feature = "python",
663 pyo3::pyclass(
664 frozen,
665 eq,
666 eq_int,
667 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
668 from_py_object,
669 rename_all = "SCREAMING_SNAKE_CASE",
670 )
671)]
672#[cfg_attr(
673 feature = "python",
674 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
675)]
676pub enum InstrumentClass {
677 Spot = 1,
679 Swap = 2,
681 Future = 3,
683 FuturesSpread = 4,
685 Forward = 5,
687 Cfd = 6,
689 Bond = 7,
691 Option = 8,
693 OptionSpread = 9,
695 Warrant = 10,
697 SportsBetting = 11,
699 BinaryOption = 12,
701}
702
703impl InstrumentClass {
704 #[must_use]
706 pub const fn has_expiration(&self) -> bool {
707 matches!(
708 self,
709 Self::Future | Self::FuturesSpread | Self::Option | Self::OptionSpread
710 )
711 }
712
713 #[must_use]
715 pub const fn allows_negative_price(&self) -> bool {
716 matches!(
717 self,
718 Self::Option | Self::FuturesSpread | Self::OptionSpread
719 )
720 }
721}
722
723#[repr(C)]
725#[derive(
726 Copy,
727 Clone,
728 Debug,
729 Display,
730 Hash,
731 PartialEq,
732 Eq,
733 PartialOrd,
734 Ord,
735 AsRefStr,
736 FromRepr,
737 EnumIter,
738 EnumString,
739)]
740#[strum(ascii_case_insensitive)]
741#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
742#[cfg_attr(
743 feature = "python",
744 pyo3::pyclass(
745 frozen,
746 eq,
747 eq_int,
748 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
749 from_py_object,
750 rename_all = "SCREAMING_SNAKE_CASE",
751 )
752)]
753#[cfg_attr(
754 feature = "python",
755 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
756)]
757pub enum InstrumentCloseType {
758 EndOfSession = 1,
760 ContractExpired = 2,
762}
763
764impl FromU8 for InstrumentCloseType {
766 fn from_u8(value: u8) -> Option<Self> {
767 match value {
768 1 => Some(Self::EndOfSession),
769 2 => Some(Self::ContractExpired),
770 _ => None,
771 }
772 }
773}
774
775#[repr(C)]
777#[derive(
778 Copy,
779 Clone,
780 Debug,
781 Display,
782 Hash,
783 PartialEq,
784 Eq,
785 PartialOrd,
786 Ord,
787 AsRefStr,
788 FromRepr,
789 EnumIter,
790 EnumString,
791)]
792#[strum(ascii_case_insensitive)]
793#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
794#[cfg_attr(
795 feature = "python",
796 pyo3::pyclass(
797 frozen,
798 eq,
799 eq_int,
800 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
801 from_py_object,
802 rename_all = "SCREAMING_SNAKE_CASE",
803 )
804)]
805#[cfg_attr(
806 feature = "python",
807 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
808)]
809pub enum LiquiditySide {
810 NoLiquiditySide = 0,
812 Maker = 1,
814 Taker = 2,
816}
817
818#[repr(C)]
820#[derive(
821 Copy,
822 Clone,
823 Debug,
824 Display,
825 Hash,
826 PartialEq,
827 Eq,
828 PartialOrd,
829 Ord,
830 AsRefStr,
831 FromRepr,
832 EnumIter,
833 EnumString,
834)]
835#[strum(ascii_case_insensitive)]
836#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
837#[cfg_attr(
838 feature = "python",
839 pyo3::pyclass(
840 frozen,
841 eq,
842 eq_int,
843 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
844 from_py_object,
845 rename_all = "SCREAMING_SNAKE_CASE",
846 )
847)]
848#[cfg_attr(
849 feature = "python",
850 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
851)]
852pub enum MarketStatus {
853 Open = 1,
855 Closed = 2,
857 Paused = 3,
859 Suspended = 5,
863 NotAvailable = 6,
865}
866
867#[repr(C)]
869#[derive(
870 Copy,
871 Clone,
872 Debug,
873 Display,
874 Hash,
875 PartialEq,
876 Eq,
877 PartialOrd,
878 Ord,
879 AsRefStr,
880 FromRepr,
881 EnumIter,
882 EnumString,
883)]
884#[strum(ascii_case_insensitive)]
885#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
886#[cfg_attr(
887 feature = "python",
888 pyo3::pyclass(
889 frozen,
890 eq,
891 eq_int,
892 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
893 from_py_object,
894 rename_all = "SCREAMING_SNAKE_CASE",
895 )
896)]
897#[cfg_attr(
898 feature = "python",
899 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
900)]
901pub enum MarketStatusAction {
902 None = 0,
904 PreOpen = 1,
906 PreCross = 2,
908 Quoting = 3,
910 Cross = 4,
912 Rotation = 5,
914 NewPriceIndication = 6,
916 Trading = 7,
918 Halt = 8,
920 Pause = 9,
922 Suspend = 10,
924 PreClose = 11,
926 Close = 12,
928 PostClose = 13,
930 ShortSellRestrictionChange = 14,
932 NotAvailableForTrading = 15,
934}
935
936impl FromU16 for MarketStatusAction {
938 fn from_u16(value: u16) -> Option<Self> {
939 match value {
940 0 => Some(Self::None),
941 1 => Some(Self::PreOpen),
942 2 => Some(Self::PreCross),
943 3 => Some(Self::Quoting),
944 4 => Some(Self::Cross),
945 5 => Some(Self::Rotation),
946 6 => Some(Self::NewPriceIndication),
947 7 => Some(Self::Trading),
948 8 => Some(Self::Halt),
949 9 => Some(Self::Pause),
950 10 => Some(Self::Suspend),
951 11 => Some(Self::PreClose),
952 12 => Some(Self::Close),
953 13 => Some(Self::PostClose),
954 14 => Some(Self::ShortSellRestrictionChange),
955 15 => Some(Self::NotAvailableForTrading),
956 _ => None,
957 }
958 }
959}
960
961#[repr(C)]
963#[derive(
964 Copy,
965 Clone,
966 Debug,
967 Default,
968 Display,
969 Hash,
970 PartialEq,
971 Eq,
972 PartialOrd,
973 Ord,
974 AsRefStr,
975 FromRepr,
976 EnumIter,
977 EnumString,
978)]
979#[strum(ascii_case_insensitive)]
980#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
981#[cfg_attr(
982 feature = "python",
983 pyo3::pyclass(
984 frozen,
985 eq,
986 eq_int,
987 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
988 from_py_object,
989 rename_all = "SCREAMING_SNAKE_CASE",
990 )
991)]
992#[cfg_attr(
993 feature = "python",
994 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
995)]
996pub enum OmsType {
997 #[default]
999 Unspecified = 0,
1000 Netting = 1,
1002 Hedging = 2,
1006}
1007
1008#[repr(C)]
1010#[derive(
1011 Copy,
1012 Clone,
1013 Debug,
1014 Display,
1015 Hash,
1016 PartialEq,
1017 Eq,
1018 PartialOrd,
1019 Ord,
1020 AsRefStr,
1021 FromRepr,
1022 EnumIter,
1023 EnumString,
1024)]
1025#[strum(ascii_case_insensitive)]
1026#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1027#[cfg_attr(
1028 feature = "python",
1029 pyo3::pyclass(
1030 frozen,
1031 eq,
1032 eq_int,
1033 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1034 from_py_object,
1035 rename_all = "SCREAMING_SNAKE_CASE",
1036 )
1037)]
1038#[cfg_attr(
1039 feature = "python",
1040 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1041)]
1042pub enum OptionKind {
1043 Call = 1,
1045 Put = 2,
1047}
1048
1049#[repr(C)]
1061#[derive(
1062 Copy,
1063 Clone,
1064 Debug,
1065 Default,
1066 Display,
1067 Hash,
1068 PartialEq,
1069 Eq,
1070 PartialOrd,
1071 Ord,
1072 AsRefStr,
1073 FromRepr,
1074 EnumIter,
1075 EnumString,
1076)]
1077#[strum(ascii_case_insensitive)]
1078#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1079#[cfg_attr(
1080 feature = "python",
1081 pyo3::pyclass(
1082 frozen,
1083 eq,
1084 eq_int,
1085 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1086 from_py_object,
1087 rename_all = "SCREAMING_SNAKE_CASE",
1088 )
1089)]
1090#[cfg_attr(
1091 feature = "python",
1092 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1093)]
1094pub enum GreeksConvention {
1095 #[default]
1097 BlackScholes = 1,
1098 PriceAdjusted = 2,
1100}
1101
1102#[repr(C)]
1104#[derive(
1105 Copy,
1106 Clone,
1107 Debug,
1108 Default,
1109 Display,
1110 Hash,
1111 PartialEq,
1112 Eq,
1113 PartialOrd,
1114 Ord,
1115 AsRefStr,
1116 FromRepr,
1117 EnumIter,
1118 EnumString,
1119)]
1120#[strum(ascii_case_insensitive)]
1121#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1122#[cfg_attr(
1123 feature = "python",
1124 pyo3::pyclass(
1125 frozen,
1126 eq,
1127 eq_int,
1128 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1129 from_py_object,
1130 rename_all = "SCREAMING_SNAKE_CASE",
1131 )
1132)]
1133#[cfg_attr(
1134 feature = "python",
1135 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1136)]
1137pub enum OtoTriggerMode {
1138 #[default]
1140 Partial = 0,
1141 Full = 1,
1143}
1144
1145#[repr(C)]
1147#[derive(
1148 Copy,
1149 Clone,
1150 Debug,
1151 Default,
1152 Display,
1153 Hash,
1154 PartialEq,
1155 Eq,
1156 PartialOrd,
1157 Ord,
1158 AsRefStr,
1159 FromRepr,
1160 EnumIter,
1161 EnumString,
1162)]
1163#[strum(ascii_case_insensitive)]
1164#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1165#[cfg_attr(
1166 feature = "python",
1167 pyo3::pyclass(
1168 frozen,
1169 eq,
1170 eq_int,
1171 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1172 from_py_object,
1173 rename_all = "SCREAMING_SNAKE_CASE",
1174 )
1175)]
1176#[cfg_attr(
1177 feature = "python",
1178 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1179)]
1180pub enum OrderSide {
1181 #[default]
1183 NoOrderSide = 0,
1184 Buy = 1,
1186 Sell = 2,
1188}
1189
1190impl OrderSide {
1191 #[must_use]
1197 pub fn as_specified(&self) -> OrderSideSpecified {
1198 match &self {
1199 Self::Buy => OrderSideSpecified::Buy,
1200 Self::Sell => OrderSideSpecified::Sell,
1201 Self::NoOrderSide => panic!("Order invariant failed: side must be `Buy` or `Sell`"),
1202 }
1203 }
1204}
1205
1206impl FromU8 for OrderSide {
1208 fn from_u8(value: u8) -> Option<Self> {
1209 match value {
1210 0 => Some(Self::NoOrderSide),
1211 1 => Some(Self::Buy),
1212 2 => Some(Self::Sell),
1213 _ => None,
1214 }
1215 }
1216}
1217
1218#[repr(C)]
1220#[derive(
1221 Copy,
1222 Clone,
1223 Debug,
1224 Display,
1225 Hash,
1226 PartialEq,
1227 Eq,
1228 PartialOrd,
1229 Ord,
1230 AsRefStr,
1231 FromRepr,
1232 EnumIter,
1233 EnumString,
1234)]
1235#[strum(ascii_case_insensitive)]
1236#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1237pub enum OrderSideSpecified {
1238 Buy = 1,
1240 Sell = 2,
1242}
1243
1244impl OrderSideSpecified {
1245 #[must_use]
1247 pub fn opposite(&self) -> Self {
1248 match &self {
1249 Self::Buy => Self::Sell,
1250 Self::Sell => Self::Buy,
1251 }
1252 }
1253
1254 #[must_use]
1256 pub fn as_order_side(&self) -> OrderSide {
1257 match &self {
1258 Self::Buy => OrderSide::Buy,
1259 Self::Sell => OrderSide::Sell,
1260 }
1261 }
1262}
1263
1264#[repr(C)]
1285#[derive(
1286 Copy,
1287 Clone,
1288 Debug,
1289 Display,
1290 Hash,
1291 PartialEq,
1292 Eq,
1293 PartialOrd,
1294 Ord,
1295 AsRefStr,
1296 FromRepr,
1297 EnumIter,
1298 EnumString,
1299)]
1300#[strum(ascii_case_insensitive)]
1301#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1302#[cfg_attr(
1303 feature = "python",
1304 pyo3::pyclass(
1305 frozen,
1306 eq,
1307 eq_int,
1308 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1309 from_py_object,
1310 rename_all = "SCREAMING_SNAKE_CASE",
1311 )
1312)]
1313#[cfg_attr(
1314 feature = "python",
1315 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1316)]
1317pub enum OrderStatus {
1318 Initialized = 1,
1320 Denied = 2,
1322 Emulated = 3,
1324 Released = 4,
1326 Submitted = 5,
1328 Accepted = 6,
1330 Rejected = 7,
1332 Canceled = 8,
1334 Expired = 9,
1336 Triggered = 10,
1338 PendingUpdate = 11,
1340 PendingCancel = 12,
1342 PartiallyFilled = 13,
1344 Filled = 14,
1346}
1347
1348impl OrderStatus {
1349 #[must_use]
1351 pub const fn is_open(self) -> bool {
1352 matches!(
1353 self,
1354 Self::Submitted
1355 | Self::Accepted
1356 | Self::Triggered
1357 | Self::PendingUpdate
1358 | Self::PendingCancel
1359 | Self::PartiallyFilled
1360 )
1361 }
1362
1363 #[must_use]
1365 pub const fn is_closed(self) -> bool {
1366 matches!(
1367 self,
1368 Self::Denied | Self::Rejected | Self::Canceled | Self::Expired | Self::Filled
1369 )
1370 }
1371
1372 #[must_use]
1374 pub const fn is_cancellable(self) -> bool {
1375 matches!(
1376 self,
1377 Self::Accepted | Self::Triggered | Self::PendingUpdate | Self::PartiallyFilled
1378 )
1379 }
1380
1381 #[must_use]
1396 pub fn cancellable_statuses_set() -> &'static AHashSet<Self> {
1397 static CANCELLABLE_SET: OnceLock<AHashSet<OrderStatus>> = OnceLock::new();
1398 CANCELLABLE_SET.get_or_init(|| {
1399 AHashSet::from_iter([
1400 Self::Accepted,
1401 Self::Triggered,
1402 Self::PendingUpdate,
1403 Self::PartiallyFilled,
1404 ])
1405 })
1406 }
1407}
1408
1409#[repr(C)]
1411#[derive(
1412 Copy,
1413 Clone,
1414 Debug,
1415 Display,
1416 Hash,
1417 PartialEq,
1418 Eq,
1419 PartialOrd,
1420 Ord,
1421 AsRefStr,
1422 FromRepr,
1423 EnumIter,
1424 EnumString,
1425)]
1426#[strum(ascii_case_insensitive)]
1427#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1428#[cfg_attr(
1429 feature = "python",
1430 pyo3::pyclass(
1431 frozen,
1432 eq,
1433 eq_int,
1434 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1435 from_py_object,
1436 rename_all = "SCREAMING_SNAKE_CASE",
1437 )
1438)]
1439#[cfg_attr(
1440 feature = "python",
1441 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1442)]
1443pub enum OrderType {
1444 Market = 1,
1446 Limit = 2,
1448 StopMarket = 3,
1450 StopLimit = 4,
1452 MarketToLimit = 5,
1454 MarketIfTouched = 6,
1456 LimitIfTouched = 7,
1458 TrailingStopMarket = 8,
1460 TrailingStopLimit = 9,
1462}
1463
1464#[repr(C)]
1466#[derive(
1467 Copy,
1468 Clone,
1469 Debug,
1470 Display,
1471 Hash,
1472 PartialEq,
1473 Eq,
1474 PartialOrd,
1475 Ord,
1476 AsRefStr,
1477 FromRepr,
1478 EnumIter,
1479 EnumString,
1480)]
1481#[strum(ascii_case_insensitive)]
1482#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1483#[cfg_attr(
1484 feature = "python",
1485 pyo3::pyclass(
1486 frozen,
1487 eq,
1488 eq_int,
1489 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1490 from_py_object,
1491 rename_all = "SCREAMING_SNAKE_CASE",
1492 )
1493)]
1494#[cfg_attr(
1495 feature = "python",
1496 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1497)]
1498pub enum PositionAdjustmentType {
1499 Commission = 1,
1501 Funding = 2,
1503}
1504
1505impl FromU8 for PositionAdjustmentType {
1506 fn from_u8(value: u8) -> Option<Self> {
1507 match value {
1508 1 => Some(Self::Commission),
1509 2 => Some(Self::Funding),
1510 _ => None,
1511 }
1512 }
1513}
1514
1515#[repr(C)]
1517#[derive(
1518 Copy,
1519 Clone,
1520 Debug,
1521 Default,
1522 Display,
1523 Hash,
1524 PartialEq,
1525 Eq,
1526 PartialOrd,
1527 Ord,
1528 AsRefStr,
1529 FromRepr,
1530 EnumIter,
1531 EnumString,
1532)]
1533#[strum(ascii_case_insensitive)]
1534#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1535#[cfg_attr(
1536 feature = "python",
1537 pyo3::pyclass(
1538 frozen,
1539 eq,
1540 eq_int,
1541 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1542 from_py_object,
1543 rename_all = "SCREAMING_SNAKE_CASE",
1544 )
1545)]
1546#[cfg_attr(
1547 feature = "python",
1548 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1549)]
1550pub enum PositionSide {
1551 #[default]
1553 NoPositionSide = 0,
1554 Flat = 1,
1556 Long = 2,
1558 Short = 3,
1560}
1561
1562impl PositionSide {
1563 #[must_use]
1569 pub fn as_specified(&self) -> PositionSideSpecified {
1570 match &self {
1571 Self::Long => PositionSideSpecified::Long,
1572 Self::Short => PositionSideSpecified::Short,
1573 Self::Flat => PositionSideSpecified::Flat,
1574 Self::NoPositionSide => {
1575 panic!("Position invariant failed: side must be `Long`, `Short`, or `Flat`")
1576 }
1577 }
1578 }
1579}
1580
1581#[repr(C)]
1583#[derive(
1584 Copy,
1585 Clone,
1586 Debug,
1587 Display,
1588 Hash,
1589 PartialEq,
1590 Eq,
1591 PartialOrd,
1592 Ord,
1593 AsRefStr,
1594 FromRepr,
1595 EnumIter,
1596 EnumString,
1597)]
1598#[strum(ascii_case_insensitive)]
1599#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1600#[cfg_attr(
1601 feature = "python",
1602 pyo3::pyclass(
1603 frozen,
1604 eq,
1605 eq_int,
1606 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1607 from_py_object,
1608 rename_all = "SCREAMING_SNAKE_CASE",
1609 )
1610)]
1611#[cfg_attr(
1612 feature = "python",
1613 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1614)]
1615pub enum PositionSideSpecified {
1616 Flat = 1,
1618 Long = 2,
1620 Short = 3,
1622}
1623
1624impl PositionSideSpecified {
1625 #[must_use]
1627 pub fn as_position_side(&self) -> PositionSide {
1628 match &self {
1629 Self::Long => PositionSide::Long,
1630 Self::Short => PositionSide::Short,
1631 Self::Flat => PositionSide::Flat,
1632 }
1633 }
1634}
1635
1636#[repr(C)]
1638#[derive(
1639 Copy,
1640 Clone,
1641 Debug,
1642 Display,
1643 Hash,
1644 PartialEq,
1645 Eq,
1646 PartialOrd,
1647 Ord,
1648 AsRefStr,
1649 FromRepr,
1650 EnumIter,
1651 EnumString,
1652)]
1653#[strum(ascii_case_insensitive)]
1654#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1655#[cfg_attr(
1656 feature = "python",
1657 pyo3::pyclass(
1658 frozen,
1659 eq,
1660 eq_int,
1661 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1662 from_py_object,
1663 rename_all = "SCREAMING_SNAKE_CASE",
1664 )
1665)]
1666#[cfg_attr(
1667 feature = "python",
1668 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1669)]
1670pub enum PriceType {
1671 Bid = 1,
1674 Ask = 2,
1677 Mid = 3,
1679 Last = 4,
1681 Mark = 5,
1684}
1685
1686#[repr(C)]
1688#[derive(
1689 Copy,
1690 Clone,
1691 Debug,
1692 Display,
1693 Hash,
1694 PartialEq,
1695 Eq,
1696 PartialOrd,
1697 Ord,
1698 AsRefStr,
1699 FromRepr,
1700 EnumIter,
1701 EnumString,
1702)]
1703#[strum(ascii_case_insensitive)]
1704#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1705#[cfg_attr(
1706 feature = "python",
1707 pyo3::pyclass(
1708 frozen,
1709 eq,
1710 eq_int,
1711 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1712 from_py_object,
1713 rename_all = "SCREAMING_SNAKE_CASE",
1714 )
1715)]
1716#[cfg_attr(
1717 feature = "python",
1718 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1719)]
1720#[allow(non_camel_case_types)]
1721pub enum RecordFlag {
1722 F_LAST = 1 << 7, F_TOB = 1 << 6, F_SNAPSHOT = 1 << 5, F_MBP = 1 << 4, RESERVED_2 = 1 << 3, RESERVED_1 = 1 << 2, }
1735
1736impl RecordFlag {
1737 #[must_use]
1739 pub fn matches(self, value: u8) -> bool {
1740 (self as u8) & value != 0
1741 }
1742}
1743
1744#[repr(C)]
1746#[derive(
1747 Copy,
1748 Clone,
1749 Debug,
1750 Display,
1751 Hash,
1752 PartialEq,
1753 Eq,
1754 PartialOrd,
1755 Ord,
1756 AsRefStr,
1757 FromRepr,
1758 EnumIter,
1759 EnumString,
1760)]
1761#[strum(ascii_case_insensitive)]
1762#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1763#[cfg_attr(
1764 feature = "python",
1765 pyo3::pyclass(
1766 frozen,
1767 eq,
1768 eq_int,
1769 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1770 from_py_object,
1771 rename_all = "SCREAMING_SNAKE_CASE",
1772 )
1773)]
1774#[cfg_attr(
1775 feature = "python",
1776 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1777)]
1778pub enum TimeInForce {
1779 Gtc = 1,
1781 Ioc = 2,
1783 Fok = 3,
1785 Gtd = 4,
1787 Day = 5,
1789 AtTheOpen = 6,
1791 AtTheClose = 7,
1793}
1794
1795#[repr(C)]
1797#[derive(
1798 Copy,
1799 Clone,
1800 Debug,
1801 Display,
1802 Hash,
1803 PartialEq,
1804 Eq,
1805 PartialOrd,
1806 Ord,
1807 AsRefStr,
1808 FromRepr,
1809 EnumIter,
1810 EnumString,
1811)]
1812#[strum(ascii_case_insensitive)]
1813#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1814#[cfg_attr(
1815 feature = "python",
1816 pyo3::pyclass(
1817 frozen,
1818 eq,
1819 eq_int,
1820 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1821 from_py_object,
1822 rename_all = "SCREAMING_SNAKE_CASE",
1823 )
1824)]
1825#[cfg_attr(
1826 feature = "python",
1827 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1828)]
1829pub enum TradingState {
1830 Active = 1,
1832 Halted = 2,
1834 Reducing = 3,
1836}
1837
1838#[repr(C)]
1840#[derive(
1841 Copy,
1842 Clone,
1843 Debug,
1844 Default,
1845 Display,
1846 Hash,
1847 PartialEq,
1848 Eq,
1849 PartialOrd,
1850 Ord,
1851 AsRefStr,
1852 FromRepr,
1853 EnumIter,
1854 EnumString,
1855)]
1856#[strum(ascii_case_insensitive)]
1857#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1858#[cfg_attr(
1859 feature = "python",
1860 pyo3::pyclass(
1861 frozen,
1862 eq,
1863 eq_int,
1864 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1865 from_py_object,
1866 rename_all = "SCREAMING_SNAKE_CASE",
1867 )
1868)]
1869#[cfg_attr(
1870 feature = "python",
1871 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1872)]
1873pub enum TrailingOffsetType {
1874 #[default]
1876 NoTrailingOffset = 0,
1877 Price = 1,
1879 BasisPoints = 2,
1881 Ticks = 3,
1883 PriceTier = 4,
1885}
1886
1887#[repr(C)]
1889#[derive(
1890 Copy,
1891 Clone,
1892 Debug,
1893 Default,
1894 Display,
1895 Hash,
1896 PartialEq,
1897 Eq,
1898 PartialOrd,
1899 Ord,
1900 AsRefStr,
1901 FromRepr,
1902 EnumIter,
1903 EnumString,
1904)]
1905#[strum(ascii_case_insensitive)]
1906#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1907#[cfg_attr(
1908 feature = "python",
1909 pyo3::pyclass(
1910 frozen,
1911 eq,
1912 eq_int,
1913 module = "nautilus_trader.core.nautilus_pyo3.model.enums",
1914 from_py_object,
1915 rename_all = "SCREAMING_SNAKE_CASE",
1916 )
1917)]
1918#[cfg_attr(
1919 feature = "python",
1920 pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.model")
1921)]
1922pub enum TriggerType {
1923 #[default]
1925 NoTrigger = 0,
1926 Default = 1,
1928 LastPrice = 2,
1930 MarkPrice = 3,
1932 IndexPrice = 4,
1934 BidAsk = 5,
1936 DoubleLast = 6,
1938 DoubleBidAsk = 7,
1940 LastOrBidAsk = 8,
1942 MidPoint = 9,
1944}
1945
1946enum_strum_serde!(AccountType);
1947enum_strum_serde!(AggregationSource);
1948enum_strum_serde!(AggressorSide);
1949enum_strum_serde!(AssetClass);
1950enum_strum_serde!(BarAggregation);
1951enum_strum_serde!(BarIntervalType);
1952enum_strum_serde!(BookAction);
1953enum_strum_serde!(BookType);
1954enum_strum_serde!(ContingencyType);
1955enum_strum_serde!(CurrencyType);
1956enum_strum_serde!(GreeksConvention);
1957enum_strum_serde!(InstrumentClass);
1958enum_strum_serde!(InstrumentCloseType);
1959enum_strum_serde!(LiquiditySide);
1960enum_strum_serde!(MarketStatus);
1961enum_strum_serde!(MarketStatusAction);
1962enum_strum_serde!(OmsType);
1963enum_strum_serde!(OptionKind);
1964enum_strum_serde!(OrderSide);
1965enum_strum_serde!(OrderSideSpecified);
1966enum_strum_serde!(OrderStatus);
1967enum_strum_serde!(OrderType);
1968enum_strum_serde!(PositionAdjustmentType);
1969enum_strum_serde!(PositionSide);
1970enum_strum_serde!(PositionSideSpecified);
1971enum_strum_serde!(PriceType);
1972enum_strum_serde!(RecordFlag);
1973enum_strum_serde!(TimeInForce);
1974enum_strum_serde!(TradingState);
1975enum_strum_serde!(TrailingOffsetType);
1976enum_strum_serde!(TriggerType);
1977
1978#[cfg(test)]
1979mod tests {
1980 use rstest::rstest;
1981
1982 use super::*;
1983
1984 #[rstest]
1985 #[case::no_aggressor(0, Some(AggressorSide::NoAggressor))]
1986 #[case::buyer(1, Some(AggressorSide::Buyer))]
1987 #[case::seller(2, Some(AggressorSide::Seller))]
1988 #[case::invalid(3, None)]
1989 #[case::max_u8(255, None)]
1990 fn test_aggressor_side_from_u8(#[case] value: u8, #[case] expected: Option<AggressorSide>) {
1991 assert_eq!(AggressorSide::from_u8(value), expected);
1992 }
1993
1994 #[rstest]
1995 #[case(GreeksConvention::BlackScholes, "\"BLACK_SCHOLES\"")]
1996 #[case(GreeksConvention::PriceAdjusted, "\"PRICE_ADJUSTED\"")]
1997 fn test_greeks_convention_serde_roundtrip(
1998 #[case] input: GreeksConvention,
1999 #[case] expected: &str,
2000 ) {
2001 let json = serde_json::to_string(&input).unwrap();
2002 assert_eq!(json, expected);
2003 let parsed: GreeksConvention = serde_json::from_str(expected).unwrap();
2004 assert_eq!(parsed, input);
2005 }
2006
2007 #[rstest]
2008 fn test_greeks_convention_default_is_black_scholes() {
2009 assert_eq!(GreeksConvention::default(), GreeksConvention::BlackScholes);
2010 }
2011}