nautilus_model/
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 for the trading domain model.
17
18use 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
26/// Provides conversion from a `u8` value to an enum type.
27pub trait FromU8 {
28    /// Converts a `u8` value to the implementing type.
29    ///
30    /// Returns `None` if the value is not a valid representation.
31    fn from_u8(value: u8) -> Option<Self>
32    where
33        Self: Sized;
34}
35
36/// Provides conversion from a `u16` value to an enum type.
37pub trait FromU16 {
38    /// Converts a `u16` value to the implementing type.
39    ///
40    /// Returns `None` if the value is not a valid representation.
41    fn from_u16(value: u16) -> Option<Self>
42    where
43        Self: Sized;
44}
45
46/// An account type provided by a trading venue or broker.
47#[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        hash,
72        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
73    )
74)]
75pub enum AccountType {
76    /// An account with unleveraged cash assets only.
77    Cash = 1,
78    /// An account which facilitates trading on margin, using account assets as collateral.
79    Margin = 2,
80    /// An account specific to betting markets.
81    Betting = 3,
82    /// An account which represents a blockchain wallet,
83    Wallet = 4,
84}
85
86/// An aggregation source for derived data.
87#[repr(C)]
88#[derive(
89    Copy,
90    Clone,
91    Debug,
92    Display,
93    Hash,
94    PartialEq,
95    Eq,
96    PartialOrd,
97    Ord,
98    AsRefStr,
99    FromRepr,
100    EnumIter,
101    EnumString,
102)]
103#[strum(ascii_case_insensitive)]
104#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
105#[cfg_attr(
106    feature = "python",
107    pyo3::pyclass(
108        frozen,
109        eq,
110        eq_int,
111        hash,
112        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
113    )
114)]
115pub enum AggregationSource {
116    /// The data is externally aggregated (outside the Nautilus system boundary).
117    External = 1,
118    /// The data is internally aggregated (inside the Nautilus system boundary).
119    Internal = 2,
120}
121
122/// The side for the aggressing order of a trade in a market.
123#[repr(C)]
124#[derive(
125    Copy,
126    Clone,
127    Debug,
128    Default,
129    Display,
130    Hash,
131    PartialEq,
132    Eq,
133    PartialOrd,
134    Ord,
135    AsRefStr,
136    FromRepr,
137    EnumIter,
138    EnumString,
139)]
140#[strum(ascii_case_insensitive)]
141#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
142#[cfg_attr(
143    feature = "python",
144    pyo3::pyclass(
145        frozen,
146        eq,
147        eq_int,
148        hash,
149        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
150    )
151)]
152pub enum AggressorSide {
153    /// There was no specific aggressor for the trade.
154    #[default]
155    NoAggressor = 0,
156    /// The BUY order was the aggressor for the trade.
157    Buyer = 1,
158    /// The SELL order was the aggressor for the trade.
159    Seller = 2,
160}
161
162impl FromU8 for AggressorSide {
163    fn from_u8(value: u8) -> Option<Self> {
164        match value {
165            0 => Some(Self::NoAggressor),
166            1 => Some(Self::Buyer),
167            2 => Some(Self::Seller),
168            _ => None,
169        }
170    }
171}
172
173/// A broad financial market asset class.
174#[repr(C)]
175#[derive(
176    Copy,
177    Clone,
178    Debug,
179    Display,
180    Hash,
181    PartialEq,
182    Eq,
183    PartialOrd,
184    Ord,
185    AsRefStr,
186    FromRepr,
187    EnumIter,
188    EnumString,
189)]
190#[strum(ascii_case_insensitive)]
191#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
192#[cfg_attr(
193    feature = "python",
194    pyo3::pyclass(
195        frozen,
196        eq,
197        eq_int,
198        hash,
199        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
200    )
201)]
202#[allow(non_camel_case_types)]
203pub enum AssetClass {
204    /// Foreign exchange (FOREX) assets.
205    FX = 1,
206    /// Equity / stock assets.
207    Equity = 2,
208    /// Commodity assets.
209    Commodity = 3,
210    /// Debt based assets.
211    Debt = 4,
212    /// Index based assets (baskets).
213    Index = 5,
214    /// Cryptocurrency or crypto token assets.
215    Cryptocurrency = 6,
216    /// Alternative assets.
217    Alternative = 7,
218}
219
220impl FromU8 for AssetClass {
221    fn from_u8(value: u8) -> Option<Self> {
222        match value {
223            1 => Some(Self::FX),
224            2 => Some(Self::Equity),
225            3 => Some(Self::Commodity),
226            4 => Some(Self::Debt),
227            5 => Some(Self::Index),
228            6 => Some(Self::Cryptocurrency),
229            7 => Some(Self::Alternative),
230            _ => None,
231        }
232    }
233}
234
235/// The aggregation method through which a bar is generated and closed.
236#[repr(C)]
237#[derive(
238    Copy,
239    Clone,
240    Debug,
241    Display,
242    Hash,
243    PartialEq,
244    Eq,
245    PartialOrd,
246    Ord,
247    AsRefStr,
248    FromRepr,
249    EnumIter,
250    EnumString,
251)]
252#[strum(ascii_case_insensitive)]
253#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
254#[cfg_attr(
255    feature = "python",
256    pyo3::pyclass(
257        frozen,
258        eq,
259        eq_int,
260        hash,
261        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
262    )
263)]
264pub enum BarAggregation {
265    /// Based on a number of ticks.
266    Tick = 1,
267    /// Based on the buy/sell imbalance of ticks.
268    TickImbalance = 2,
269    /// Based on sequential buy/sell runs of ticks.
270    TickRuns = 3,
271    /// Based on traded volume.
272    Volume = 4,
273    /// Based on the buy/sell imbalance of traded volume.
274    VolumeImbalance = 5,
275    /// Based on sequential runs of buy/sell traded volume.
276    VolumeRuns = 6,
277    /// Based on the 'notional' value of the instrument.
278    Value = 7,
279    /// Based on the buy/sell imbalance of trading by notional value.
280    ValueImbalance = 8,
281    /// Based on sequential buy/sell runs of trading by notional value.
282    ValueRuns = 9,
283    /// Based on time intervals with millisecond granularity.
284    Millisecond = 10,
285    /// Based on time intervals with second granularity.
286    Second = 11,
287    /// Based on time intervals with minute granularity.
288    Minute = 12,
289    /// Based on time intervals with hour granularity.
290    Hour = 13,
291    /// Based on time intervals with day granularity.
292    Day = 14,
293    /// Based on time intervals with week granularity.
294    Week = 15,
295    /// Based on time intervals with month granularity.
296    Month = 16,
297    /// Based on time intervals with year granularity.
298    Year = 17,
299    /// Based on fixed price movements (brick size).
300    Renko = 18,
301}
302
303/// The interval type for bar aggregation.
304#[repr(C)]
305#[derive(
306    Copy,
307    Clone,
308    Debug,
309    Default,
310    Display,
311    Hash,
312    PartialEq,
313    Eq,
314    PartialOrd,
315    Ord,
316    AsRefStr,
317    FromRepr,
318    EnumIter,
319    EnumString,
320)]
321#[strum(ascii_case_insensitive)]
322#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
323#[cfg_attr(
324    feature = "python",
325    pyo3::pyclass(
326        frozen,
327        eq,
328        eq_int,
329        hash,
330        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
331    )
332)]
333pub enum BarIntervalType {
334    /// Left-open interval `(start, end]`: start is exclusive, end is inclusive (default).
335    #[default]
336    LeftOpen = 1,
337    /// Right-open interval `[start, end)`: start is inclusive, end is exclusive.
338    RightOpen = 2,
339}
340
341/// Represents the side of a bet in a betting market.
342#[repr(C)]
343#[derive(
344    Copy,
345    Clone,
346    Debug,
347    Display,
348    Hash,
349    PartialEq,
350    Eq,
351    PartialOrd,
352    Ord,
353    AsRefStr,
354    FromRepr,
355    EnumIter,
356    EnumString,
357)]
358#[strum(ascii_case_insensitive)]
359#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
360#[cfg_attr(
361    feature = "python",
362    pyo3::pyclass(
363        frozen,
364        eq,
365        eq_int,
366        hash,
367        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
368    )
369)]
370pub enum BetSide {
371    /// A "Back" bet signifies support for a specific outcome.
372    Back = 1,
373    /// A "Lay" bet signifies opposition to a specific outcome.
374    Lay = 2,
375}
376
377impl BetSide {
378    /// Returns the opposite betting side.
379    #[must_use]
380    pub fn opposite(&self) -> Self {
381        match self {
382            Self::Back => Self::Lay,
383            Self::Lay => Self::Back,
384        }
385    }
386}
387
388impl From<OrderSide> for BetSide {
389    /// Returns the equivalent [`BetSide`] for a given [`OrderSide`].
390    ///
391    /// # Panics
392    ///
393    /// Panics if `side` is [`OrderSide::NoOrderSide`].
394    fn from(side: OrderSide) -> Self {
395        match side {
396            OrderSide::Buy => Self::Back,
397            OrderSide::Sell => Self::Lay,
398            OrderSide::NoOrderSide => panic!("Invalid `OrderSide` for `BetSide`, was {side}"),
399        }
400    }
401}
402
403/// The type of order book action for an order book event.
404#[repr(C)]
405#[derive(
406    Copy,
407    Clone,
408    Debug,
409    Display,
410    Hash,
411    PartialEq,
412    Eq,
413    PartialOrd,
414    Ord,
415    AsRefStr,
416    FromRepr,
417    EnumIter,
418    EnumString,
419)]
420#[strum(ascii_case_insensitive)]
421#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
422#[cfg_attr(
423    feature = "python",
424    pyo3::pyclass(
425        frozen,
426        eq,
427        eq_int,
428        hash,
429        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
430    )
431)]
432pub enum BookAction {
433    /// An order is added to the book.
434    Add = 1,
435    /// An existing order in the book is updated/modified.
436    Update = 2,
437    /// An existing order in the book is deleted/canceled.
438    Delete = 3,
439    /// The state of the order book is cleared.
440    Clear = 4,
441}
442
443impl FromU8 for BookAction {
444    fn from_u8(value: u8) -> Option<Self> {
445        match value {
446            1 => Some(Self::Add),
447            2 => Some(Self::Update),
448            3 => Some(Self::Delete),
449            4 => Some(Self::Clear),
450            _ => None,
451        }
452    }
453}
454
455/// The order book type, representing the type of levels granularity and delta updating heuristics.
456#[repr(C)]
457#[derive(
458    Copy,
459    Clone,
460    Debug,
461    Display,
462    Hash,
463    PartialEq,
464    Eq,
465    PartialOrd,
466    Ord,
467    AsRefStr,
468    FromRepr,
469    EnumIter,
470    EnumString,
471)]
472#[strum(ascii_case_insensitive)]
473#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
474#[allow(non_camel_case_types)]
475#[cfg_attr(
476    feature = "python",
477    pyo3::pyclass(
478        frozen,
479        eq,
480        eq_int,
481        hash,
482        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
483    )
484)]
485pub enum BookType {
486    /// Top-of-book best bid/ask, one level per side.
487    L1_MBP = 1,
488    /// Market by price, one order per level (aggregated).
489    L2_MBP = 2,
490    /// Market by order, multiple orders per level (full granularity).
491    L3_MBO = 3,
492}
493
494impl FromU8 for BookType {
495    fn from_u8(value: u8) -> Option<Self> {
496        match value {
497            1 => Some(Self::L1_MBP),
498            2 => Some(Self::L2_MBP),
499            3 => Some(Self::L3_MBO),
500            _ => None,
501        }
502    }
503}
504
505/// The order contingency type which specifies the behavior of linked orders.
506///
507/// [FIX 5.0 SP2 : ContingencyType <1385> field](https://www.onixs.biz/fix-dictionary/5.0.sp2/tagnum_1385.html).
508#[repr(C)]
509#[derive(
510    Copy,
511    Clone,
512    Debug,
513    Default,
514    Display,
515    Hash,
516    PartialEq,
517    Eq,
518    PartialOrd,
519    Ord,
520    AsRefStr,
521    FromRepr,
522    EnumIter,
523    EnumString,
524)]
525#[strum(ascii_case_insensitive)]
526#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
527#[cfg_attr(
528    feature = "python",
529    pyo3::pyclass(
530        frozen,
531        eq,
532        eq_int,
533        hash,
534        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
535    )
536)]
537pub enum ContingencyType {
538    /// Not a contingent order.
539    #[default]
540    NoContingency = 0,
541    /// One-Cancels-the-Other.
542    Oco = 1,
543    /// One-Triggers-the-Other.
544    Oto = 2,
545    /// One-Updates-the-Other (by proportional quantity).
546    Ouo = 3,
547}
548
549/// The broad currency type.
550#[repr(C)]
551#[derive(
552    Copy,
553    Clone,
554    Debug,
555    Display,
556    Hash,
557    PartialEq,
558    Eq,
559    PartialOrd,
560    Ord,
561    AsRefStr,
562    FromRepr,
563    EnumIter,
564    EnumString,
565)]
566#[strum(ascii_case_insensitive)]
567#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
568#[cfg_attr(
569    feature = "python",
570    pyo3::pyclass(
571        frozen,
572        eq,
573        eq_int,
574        hash,
575        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
576    )
577)]
578pub enum CurrencyType {
579    /// A type of cryptocurrency or crypto token.
580    Crypto = 1,
581    /// A type of currency issued by governments which is not backed by a commodity.
582    Fiat = 2,
583    /// A type of currency that is based on the value of an underlying commodity.
584    CommodityBacked = 3,
585}
586
587/// The instrument class.
588#[repr(C)]
589#[derive(
590    Copy,
591    Clone,
592    Debug,
593    Display,
594    Hash,
595    PartialEq,
596    Eq,
597    PartialOrd,
598    Ord,
599    AsRefStr,
600    FromRepr,
601    EnumIter,
602    EnumString,
603)]
604#[strum(ascii_case_insensitive)]
605#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
606#[cfg_attr(
607    feature = "python",
608    pyo3::pyclass(
609        frozen,
610        eq,
611        eq_int,
612        hash,
613        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
614    )
615)]
616pub enum InstrumentClass {
617    /// A spot market instrument class. The current market price of an instrument that is bought or sold for immediate delivery and payment.
618    Spot = 1,
619    /// A swap instrument class. A derivative contract through which two parties exchange the cash flows or liabilities from two different financial instruments.
620    Swap = 2,
621    /// A futures contract instrument class. A legal agreement to buy or sell an asset at a predetermined price at a specified time in the future.
622    Future = 3,
623    /// A futures spread instrument class. A strategy involving the use of futures contracts to take advantage of price differentials between different contract months, underlying assets, or marketplaces.
624    FuturesSpread = 4,
625    /// A forward derivative instrument class. A customized contract between two parties to buy or sell an asset at a specified price on a future date.
626    Forward = 5,
627    /// A contract-for-difference (CFD) instrument class. A contract between an investor and a CFD broker to exchange the difference in the value of a financial product between the time the contract opens and closes.
628    Cfd = 6,
629    /// A bond instrument class. A type of debt investment where an investor loans money to an entity (typically corporate or governmental) which borrows the funds for a defined period of time at a variable or fixed interest rate.
630    Bond = 7,
631    /// An option contract instrument class. A type of derivative that gives the holder the right, but not the obligation, to buy or sell an underlying asset at a predetermined price before or at a certain future date.
632    Option = 8,
633    /// An option spread instrument class. A strategy involving the purchase and/or sale of multiple option contracts on the same underlying asset with different strike prices or expiration dates to hedge risk or speculate on price movements.
634    OptionSpread = 9,
635    /// A warrant instrument class. A derivative that gives the holder the right, but not the obligation, to buy or sell a security—most commonly an equity—at a certain price before expiration.
636    Warrant = 10,
637    /// A sports betting instrument class. A financialized derivative that allows wagering on the outcome of sports events using structured contracts or prediction markets.
638    SportsBetting = 11,
639    /// A binary option instrument class. A type of derivative where the payoff is either a fixed monetary amount or nothing, depending on whether the price of an underlying asset is above or below a predetermined level at expiration.
640    BinaryOption = 12,
641}
642
643/// The type of event for an instrument close.
644#[repr(C)]
645#[derive(
646    Copy,
647    Clone,
648    Debug,
649    Display,
650    Hash,
651    PartialEq,
652    Eq,
653    PartialOrd,
654    Ord,
655    AsRefStr,
656    FromRepr,
657    EnumIter,
658    EnumString,
659)]
660#[strum(ascii_case_insensitive)]
661#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
662#[cfg_attr(
663    feature = "python",
664    pyo3::pyclass(
665        frozen,
666        eq,
667        eq_int,
668        hash,
669        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
670    )
671)]
672pub enum InstrumentCloseType {
673    /// When the market session ended.
674    EndOfSession = 1,
675    /// When the instrument expiration was reached.
676    ContractExpired = 2,
677}
678
679/// Convert the given `value` to an [`InstrumentCloseType`].
680impl FromU8 for InstrumentCloseType {
681    fn from_u8(value: u8) -> Option<Self> {
682        match value {
683            1 => Some(Self::EndOfSession),
684            2 => Some(Self::ContractExpired),
685            _ => None,
686        }
687    }
688}
689
690/// The liquidity side for a trade.
691#[repr(C)]
692#[derive(
693    Copy,
694    Clone,
695    Debug,
696    Display,
697    Hash,
698    PartialEq,
699    Eq,
700    PartialOrd,
701    Ord,
702    AsRefStr,
703    FromRepr,
704    EnumIter,
705    EnumString,
706)]
707#[strum(ascii_case_insensitive)]
708#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
709#[cfg_attr(
710    feature = "python",
711    pyo3::pyclass(
712        frozen,
713        eq,
714        eq_int,
715        hash,
716        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
717    )
718)]
719#[allow(clippy::enum_variant_names)]
720pub enum LiquiditySide {
721    /// No liquidity side specified.
722    NoLiquiditySide = 0,
723    /// The order passively provided liquidity to the market to complete the trade (made a market).
724    Maker = 1,
725    /// The order aggressively took liquidity from the market to complete the trade.
726    Taker = 2,
727}
728
729/// The status of an individual market on a trading venue.
730#[repr(C)]
731#[derive(
732    Copy,
733    Clone,
734    Debug,
735    Display,
736    Hash,
737    PartialEq,
738    Eq,
739    PartialOrd,
740    Ord,
741    AsRefStr,
742    FromRepr,
743    EnumIter,
744    EnumString,
745)]
746#[strum(ascii_case_insensitive)]
747#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
748#[cfg_attr(
749    feature = "python",
750    pyo3::pyclass(
751        frozen,
752        eq,
753        eq_int,
754        hash,
755        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
756    )
757)]
758pub enum MarketStatus {
759    /// The instrument is trading.
760    Open = 1,
761    /// The instrument is in a pre-open period.
762    Closed = 2,
763    /// Trading in the instrument has been paused.
764    Paused = 3,
765    /// Trading in the instrument has been halted.
766    // Halted = 4,  # TODO: Unfortunately can't use this yet due to Cython (C enum namespacing)
767    /// Trading in the instrument has been suspended.
768    Suspended = 5,
769    /// Trading in the instrument is not available.
770    NotAvailable = 6,
771}
772
773/// An action affecting the status of an individual market on a trading venue.
774#[repr(C)]
775#[derive(
776    Copy,
777    Clone,
778    Debug,
779    Display,
780    Hash,
781    PartialEq,
782    Eq,
783    PartialOrd,
784    Ord,
785    AsRefStr,
786    FromRepr,
787    EnumIter,
788    EnumString,
789)]
790#[strum(ascii_case_insensitive)]
791#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
792#[cfg_attr(
793    feature = "python",
794    pyo3::pyclass(
795        frozen,
796        eq,
797        eq_int,
798        hash,
799        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
800    )
801)]
802pub enum MarketStatusAction {
803    /// No change.
804    None = 0,
805    /// The instrument is in a pre-open period.
806    PreOpen = 1,
807    /// The instrument is in a pre-cross period.
808    PreCross = 2,
809    /// The instrument is quoting but not trading.
810    Quoting = 3,
811    /// The instrument is in a cross/auction.
812    Cross = 4,
813    /// The instrument is being opened through a trading rotation.
814    Rotation = 5,
815    /// A new price indication is available for the instrument.
816    NewPriceIndication = 6,
817    /// The instrument is trading.
818    Trading = 7,
819    /// Trading in the instrument has been halted.
820    Halt = 8,
821    /// Trading in the instrument has been paused.
822    Pause = 9,
823    /// Trading in the instrument has been suspended.
824    Suspend = 10,
825    /// The instrument is in a pre-close period.
826    PreClose = 11,
827    /// Trading in the instrument has closed.
828    Close = 12,
829    /// The instrument is in a post-close period.
830    PostClose = 13,
831    /// A change in short-selling restrictions.
832    ShortSellRestrictionChange = 14,
833    /// The instrument is not available for trading, either trading has closed or been halted.
834    NotAvailableForTrading = 15,
835}
836
837/// Convert the given `value` to an [`OrderSide`].
838impl FromU16 for MarketStatusAction {
839    fn from_u16(value: u16) -> Option<Self> {
840        match value {
841            0 => Some(Self::None),
842            1 => Some(Self::PreOpen),
843            2 => Some(Self::PreCross),
844            3 => Some(Self::Quoting),
845            4 => Some(Self::Cross),
846            5 => Some(Self::Rotation),
847            6 => Some(Self::NewPriceIndication),
848            7 => Some(Self::Trading),
849            8 => Some(Self::Halt),
850            9 => Some(Self::Pause),
851            10 => Some(Self::Suspend),
852            11 => Some(Self::PreClose),
853            12 => Some(Self::Close),
854            13 => Some(Self::PostClose),
855            14 => Some(Self::ShortSellRestrictionChange),
856            15 => Some(Self::NotAvailableForTrading),
857            _ => None,
858        }
859    }
860}
861
862/// The order management system (OMS) type for a trading venue or trading strategy.
863#[repr(C)]
864#[derive(
865    Copy,
866    Clone,
867    Debug,
868    Default,
869    Display,
870    Hash,
871    PartialEq,
872    Eq,
873    PartialOrd,
874    Ord,
875    AsRefStr,
876    FromRepr,
877    EnumIter,
878    EnumString,
879)]
880#[strum(ascii_case_insensitive)]
881#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
882#[cfg_attr(
883    feature = "python",
884    pyo3::pyclass(
885        frozen,
886        eq,
887        eq_int,
888        hash,
889        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
890    )
891)]
892pub enum OmsType {
893    /// There is no specific type of order management specified (will defer to the venue OMS).
894    #[default]
895    Unspecified = 0,
896    /// The netting type where there is one position per instrument.
897    Netting = 1,
898    /// The hedging type where there can be multiple positions per instrument.
899    /// This can be in LONG/SHORT directions, by position/ticket ID, or tracked virtually by
900    /// Nautilus.
901    Hedging = 2,
902}
903
904/// The kind of option contract.
905#[repr(C)]
906#[derive(
907    Copy,
908    Clone,
909    Debug,
910    Display,
911    Hash,
912    PartialEq,
913    Eq,
914    PartialOrd,
915    Ord,
916    AsRefStr,
917    FromRepr,
918    EnumIter,
919    EnumString,
920)]
921#[strum(ascii_case_insensitive)]
922#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
923#[cfg_attr(
924    feature = "python",
925    pyo3::pyclass(
926        frozen,
927        eq,
928        eq_int,
929        hash,
930        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
931    )
932)]
933pub enum OptionKind {
934    /// A Call option gives the holder the right, but not the obligation, to buy an underlying asset at a specified strike price within a specified period of time.
935    Call = 1,
936    /// A Put option gives the holder the right, but not the obligation, to sell an underlying asset at a specified strike price within a specified period of time.
937    Put = 2,
938}
939
940/// The order side for a specific order, or action related to orders.
941#[repr(C)]
942#[derive(
943    Copy,
944    Clone,
945    Debug,
946    Default,
947    Display,
948    Hash,
949    PartialEq,
950    Eq,
951    PartialOrd,
952    Ord,
953    AsRefStr,
954    FromRepr,
955    EnumIter,
956    EnumString,
957)]
958#[strum(ascii_case_insensitive)]
959#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
960#[allow(clippy::enum_variant_names)]
961#[cfg_attr(
962    feature = "python",
963    pyo3::pyclass(
964        frozen,
965        eq,
966        eq_int,
967        hash,
968        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
969    )
970)]
971pub enum OrderSide {
972    /// No order side is specified.
973    #[default]
974    NoOrderSide = 0,
975    /// The order is a BUY.
976    Buy = 1,
977    /// The order is a SELL.
978    Sell = 2,
979}
980
981impl OrderSide {
982    /// Returns the specified [`OrderSideSpecified`] (BUY or SELL) for this side.
983    ///
984    /// # Panics
985    ///
986    /// Panics if `self` is [`OrderSide::NoOrderSide`].
987    #[must_use]
988    pub fn as_specified(&self) -> OrderSideSpecified {
989        match &self {
990            Self::Buy => OrderSideSpecified::Buy,
991            Self::Sell => OrderSideSpecified::Sell,
992            _ => panic!("Order invariant failed: side must be `Buy` or `Sell`"),
993        }
994    }
995}
996
997/// Convert the given `value` to an [`OrderSide`].
998impl FromU8 for OrderSide {
999    fn from_u8(value: u8) -> Option<Self> {
1000        match value {
1001            0 => Some(Self::NoOrderSide),
1002            1 => Some(Self::Buy),
1003            2 => Some(Self::Sell),
1004            _ => None,
1005        }
1006    }
1007}
1008
1009/// The specified order side (BUY or SELL).
1010#[repr(C)]
1011#[derive(
1012    Copy,
1013    Clone,
1014    Debug,
1015    Display,
1016    Hash,
1017    PartialEq,
1018    Eq,
1019    PartialOrd,
1020    Ord,
1021    AsRefStr,
1022    FromRepr,
1023    EnumIter,
1024    EnumString,
1025)]
1026#[strum(ascii_case_insensitive)]
1027#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1028#[allow(clippy::enum_variant_names)]
1029pub enum OrderSideSpecified {
1030    /// The order is a BUY.
1031    Buy = 1,
1032    /// The order is a SELL.
1033    Sell = 2,
1034}
1035
1036impl OrderSideSpecified {
1037    /// Returns the opposite order side.
1038    #[must_use]
1039    pub fn opposite(&self) -> Self {
1040        match &self {
1041            Self::Buy => Self::Sell,
1042            Self::Sell => Self::Buy,
1043        }
1044    }
1045
1046    /// Converts this specified side into an [`OrderSide`].
1047    #[must_use]
1048    pub fn as_order_side(&self) -> OrderSide {
1049        match &self {
1050            Self::Buy => OrderSide::Buy,
1051            Self::Sell => OrderSide::Sell,
1052        }
1053    }
1054}
1055
1056/// The status for a specific order.
1057///
1058/// An order is considered _open_ for the following status:
1059///  - `ACCEPTED`
1060///  - `TRIGGERED`
1061///  - `PENDING_UPDATE`
1062///  - `PENDING_CANCEL`
1063///  - `PARTIALLY_FILLED`
1064///
1065/// An order is considered _in-flight_ for the following status:
1066///  - `SUBMITTED`
1067///  - `PENDING_UPDATE`
1068///  - `PENDING_CANCEL`
1069///
1070/// An order is considered _closed_ for the following status:
1071///  - `DENIED`
1072///  - `REJECTED`
1073///  - `CANCELED`
1074///  - `EXPIRED`
1075///  - `FILLED`
1076#[repr(C)]
1077#[derive(
1078    Copy,
1079    Clone,
1080    Debug,
1081    Display,
1082    Hash,
1083    PartialEq,
1084    Eq,
1085    PartialOrd,
1086    Ord,
1087    AsRefStr,
1088    FromRepr,
1089    EnumIter,
1090    EnumString,
1091)]
1092#[strum(ascii_case_insensitive)]
1093#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1094#[cfg_attr(
1095    feature = "python",
1096    pyo3::pyclass(
1097        frozen,
1098        eq,
1099        eq_int,
1100        hash,
1101        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1102    )
1103)]
1104pub enum OrderStatus {
1105    /// The order is initialized (instantiated) within the Nautilus system.
1106    Initialized = 1,
1107    /// The order was denied by the Nautilus system, either for being invalid, unprocessable or exceeding a risk limit.
1108    Denied = 2,
1109    /// The order became emulated by the Nautilus system in the `OrderEmulator` component.
1110    Emulated = 3,
1111    /// The order was released by the Nautilus system from the `OrderEmulator` component.
1112    Released = 4,
1113    /// The order was submitted by the Nautilus system to the external service or trading venue (awaiting acknowledgement).
1114    Submitted = 5,
1115    /// The order was acknowledged by the trading venue as being received and valid (may now be working).
1116    Accepted = 6,
1117    /// The order was rejected by the trading venue.
1118    Rejected = 7,
1119    /// The order was canceled (closed/done).
1120    Canceled = 8,
1121    /// The order reached a GTD expiration (closed/done).
1122    Expired = 9,
1123    /// The order STOP price was triggered on a trading venue.
1124    Triggered = 10,
1125    /// The order is currently pending a request to modify on a trading venue.
1126    PendingUpdate = 11,
1127    /// The order is currently pending a request to cancel on a trading venue.
1128    PendingCancel = 12,
1129    /// The order has been partially filled on a trading venue.
1130    PartiallyFilled = 13,
1131    /// The order has been completely filled on a trading venue (closed/done).
1132    Filled = 14,
1133}
1134
1135impl OrderStatus {
1136    /// Returns a cached `AHashSet` of order statuses safe for cancellation queries.
1137    ///
1138    /// These are statuses where an order is working on the venue but not already
1139    /// in the process of being cancelled or updated. Including `PENDING_CANCEL`
1140    /// in cancellation filters can cause duplicate cancel attempts or incorrect open order counts.
1141    ///
1142    /// Returns:
1143    /// - `ACCEPTED`: Order is working on the venue.
1144    /// - `TRIGGERED`: Stop order has been triggered.
1145    /// - `PENDING_UPDATE`: Order being updated.
1146    /// - `PARTIALLY_FILLED`: Order is partially filled but still working.
1147    ///
1148    /// Excludes:
1149    /// - `PENDING_CANCEL`: Already being cancelled.
1150    #[must_use]
1151    pub fn cancellable_statuses_set() -> &'static AHashSet<Self> {
1152        static CANCELLABLE_SET: OnceLock<AHashSet<OrderStatus>> = OnceLock::new();
1153        CANCELLABLE_SET.get_or_init(|| {
1154            AHashSet::from_iter([
1155                Self::Accepted,
1156                Self::Triggered,
1157                Self::PendingUpdate,
1158                Self::PartiallyFilled,
1159            ])
1160        })
1161    }
1162
1163    /// Returns whether the order status represents an open/working order.
1164    #[must_use]
1165    pub const fn is_open(self) -> bool {
1166        matches!(
1167            self,
1168            Self::Submitted
1169                | Self::Accepted
1170                | Self::Triggered
1171                | Self::PendingUpdate
1172                | Self::PendingCancel
1173                | Self::PartiallyFilled
1174        )
1175    }
1176}
1177
1178/// The type of order.
1179#[repr(C)]
1180#[derive(
1181    Copy,
1182    Clone,
1183    Debug,
1184    Display,
1185    Hash,
1186    PartialEq,
1187    Eq,
1188    PartialOrd,
1189    Ord,
1190    AsRefStr,
1191    FromRepr,
1192    EnumIter,
1193    EnumString,
1194)]
1195#[strum(ascii_case_insensitive)]
1196#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1197#[cfg_attr(
1198    feature = "python",
1199    pyo3::pyclass(
1200        frozen,
1201        eq,
1202        eq_int,
1203        hash,
1204        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1205    )
1206)]
1207pub enum OrderType {
1208    /// A market order to buy or sell at the best available price in the current market.
1209    Market = 1,
1210    /// A limit order to buy or sell at a specific price or better.
1211    Limit = 2,
1212    /// A stop market order to buy or sell once the price reaches the specified stop/trigger price. When the stop price is reached, the order effectively becomes a market order.
1213    StopMarket = 3,
1214    /// A stop limit order to buy or sell which combines the features of a stop order and a limit order. Once the stop/trigger price is reached, a stop-limit order effectively becomes a limit order.
1215    StopLimit = 4,
1216    /// A market-to-limit order is a market order that is to be executed as a limit order at the current best market price after reaching the market.
1217    MarketToLimit = 5,
1218    /// A market-if-touched order effectively becomes a market order when the specified trigger price is reached.
1219    MarketIfTouched = 6,
1220    /// A limit-if-touched order effectively becomes a limit order when the specified trigger price is reached.
1221    LimitIfTouched = 7,
1222    /// A trailing stop market order sets the stop/trigger price at a fixed "trailing offset" amount from the market.
1223    TrailingStopMarket = 8,
1224    /// A trailing stop limit order combines the features of a trailing stop order with those of a limit order.
1225    TrailingStopLimit = 9,
1226}
1227
1228/// The type of position adjustment.
1229#[repr(C)]
1230#[derive(
1231    Copy,
1232    Clone,
1233    Debug,
1234    Display,
1235    Hash,
1236    PartialEq,
1237    Eq,
1238    PartialOrd,
1239    Ord,
1240    AsRefStr,
1241    FromRepr,
1242    EnumIter,
1243    EnumString,
1244)]
1245#[strum(ascii_case_insensitive)]
1246#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1247#[cfg_attr(
1248    feature = "python",
1249    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.model.enums")
1250)]
1251pub enum PositionAdjustmentType {
1252    /// Commission adjustment affecting position quantity.
1253    Commission = 1,
1254    /// Funding payment affecting position realized PnL.
1255    Funding = 2,
1256}
1257
1258impl FromU8 for PositionAdjustmentType {
1259    fn from_u8(value: u8) -> Option<Self> {
1260        match value {
1261            1 => Some(Self::Commission),
1262            2 => Some(Self::Funding),
1263            _ => None,
1264        }
1265    }
1266}
1267
1268/// The market side for a specific position, or action related to positions.
1269#[repr(C)]
1270#[derive(
1271    Copy,
1272    Clone,
1273    Debug,
1274    Default,
1275    Display,
1276    Hash,
1277    PartialEq,
1278    Eq,
1279    PartialOrd,
1280    Ord,
1281    AsRefStr,
1282    FromRepr,
1283    EnumIter,
1284    EnumString,
1285)]
1286#[strum(ascii_case_insensitive)]
1287#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1288#[allow(clippy::enum_variant_names)]
1289#[cfg_attr(
1290    feature = "python",
1291    pyo3::pyclass(
1292        frozen,
1293        eq,
1294        eq_int,
1295        hash,
1296        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1297    )
1298)]
1299pub enum PositionSide {
1300    /// No position side is specified (only valid in the context of a filter for actions involving positions).
1301    #[default]
1302    NoPositionSide = 0,
1303    /// A neural/flat position, where no position is currently held in the market.
1304    Flat = 1,
1305    /// A long position in the market, typically acquired through one or many BUY orders.
1306    Long = 2,
1307    /// A short position in the market, typically acquired through one or many SELL orders.
1308    Short = 3,
1309}
1310
1311impl PositionSide {
1312    /// Returns the specified [`PositionSideSpecified`] (`Long`, `Short`, or `Flat`) for this side.
1313    ///
1314    /// # Panics
1315    ///
1316    /// Panics if `self` is [`PositionSide::NoPositionSide`].
1317    #[must_use]
1318    pub fn as_specified(&self) -> PositionSideSpecified {
1319        match &self {
1320            Self::Long => PositionSideSpecified::Long,
1321            Self::Short => PositionSideSpecified::Short,
1322            Self::Flat => PositionSideSpecified::Flat,
1323            _ => panic!("Position invariant failed: side must be `Long`, `Short`, or `Flat`"),
1324        }
1325    }
1326}
1327
1328/// The market side for a specific position, or action related to positions.
1329#[repr(C)]
1330#[derive(
1331    Copy,
1332    Clone,
1333    Debug,
1334    Display,
1335    Hash,
1336    PartialEq,
1337    Eq,
1338    PartialOrd,
1339    Ord,
1340    AsRefStr,
1341    FromRepr,
1342    EnumIter,
1343    EnumString,
1344)]
1345#[strum(ascii_case_insensitive)]
1346#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1347#[allow(clippy::enum_variant_names)]
1348#[cfg_attr(
1349    feature = "python",
1350    pyo3::pyclass(
1351        frozen,
1352        eq,
1353        eq_int,
1354        hash,
1355        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1356    )
1357)]
1358pub enum PositionSideSpecified {
1359    /// A neural/flat position, where no position is currently held in the market.
1360    Flat = 1,
1361    /// A long position in the market, typically acquired through one or many BUY orders.
1362    Long = 2,
1363    /// A short position in the market, typically acquired through one or many SELL orders.
1364    Short = 3,
1365}
1366
1367impl PositionSideSpecified {
1368    /// Converts this specified side into a [`PositionSide`].
1369    #[must_use]
1370    pub fn as_position_side(&self) -> PositionSide {
1371        match &self {
1372            Self::Long => PositionSide::Long,
1373            Self::Short => PositionSide::Short,
1374            Self::Flat => PositionSide::Flat,
1375        }
1376    }
1377}
1378
1379/// The type of price for an instrument in a market.
1380#[repr(C)]
1381#[derive(
1382    Copy,
1383    Clone,
1384    Debug,
1385    Display,
1386    Hash,
1387    PartialEq,
1388    Eq,
1389    PartialOrd,
1390    Ord,
1391    AsRefStr,
1392    FromRepr,
1393    EnumIter,
1394    EnumString,
1395)]
1396#[strum(ascii_case_insensitive)]
1397#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1398#[cfg_attr(
1399    feature = "python",
1400    pyo3::pyclass(
1401        frozen,
1402        eq,
1403        eq_int,
1404        hash,
1405        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1406    )
1407)]
1408pub enum PriceType {
1409    /// The best quoted price at which buyers are willing to buy a quantity of an instrument.
1410    /// Often considered the best bid in the order book.
1411    Bid = 1,
1412    /// The best quoted price at which sellers are willing to sell a quantity of an instrument.
1413    /// Often considered the best ask in the order book.
1414    Ask = 2,
1415    /// The arithmetic midpoint between the best bid and ask quotes.
1416    Mid = 3,
1417    /// The price at which the last trade of an instrument was executed.
1418    Last = 4,
1419    /// A reference price reflecting an instrument's fair value, often used for portfolio
1420    /// calculations and risk management.
1421    Mark = 5,
1422}
1423
1424/// A record flag bit field, indicating event end and data information.
1425#[repr(C)]
1426#[derive(
1427    Copy,
1428    Clone,
1429    Debug,
1430    Display,
1431    Hash,
1432    PartialEq,
1433    Eq,
1434    PartialOrd,
1435    Ord,
1436    AsRefStr,
1437    FromRepr,
1438    EnumIter,
1439    EnumString,
1440)]
1441#[strum(ascii_case_insensitive)]
1442#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1443#[cfg_attr(
1444    feature = "python",
1445    pyo3::pyclass(
1446        frozen,
1447        eq,
1448        eq_int,
1449        hash,
1450        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1451    )
1452)]
1453#[allow(non_camel_case_types)]
1454pub enum RecordFlag {
1455    /// Last message in the book event or packet from the venue for a given `instrument_id`.
1456    F_LAST = 1 << 7, // 128
1457    /// Top-of-book message, not an individual order.
1458    F_TOB = 1 << 6, // 64
1459    /// Message sourced from a replay, such as a snapshot server.
1460    F_SNAPSHOT = 1 << 5, // 32
1461    /// Aggregated price level message, not an individual order.
1462    F_MBP = 1 << 4, // 16
1463    /// Reserved for future use.
1464    RESERVED_2 = 1 << 3, // 8
1465    /// Reserved for future use.
1466    RESERVED_1 = 1 << 2, // 4
1467}
1468
1469impl RecordFlag {
1470    /// Checks if the flag matches a given value.
1471    #[must_use]
1472    pub fn matches(self, value: u8) -> bool {
1473        (self as u8) & value != 0
1474    }
1475}
1476
1477/// The 'Time in Force' instruction for an order.
1478#[repr(C)]
1479#[derive(
1480    Copy,
1481    Clone,
1482    Debug,
1483    Display,
1484    Hash,
1485    PartialEq,
1486    Eq,
1487    PartialOrd,
1488    Ord,
1489    AsRefStr,
1490    FromRepr,
1491    EnumIter,
1492    EnumString,
1493)]
1494#[strum(ascii_case_insensitive)]
1495#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1496#[cfg_attr(
1497    feature = "python",
1498    pyo3::pyclass(
1499        frozen,
1500        eq,
1501        eq_int,
1502        hash,
1503        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1504    )
1505)]
1506pub enum TimeInForce {
1507    /// Good Till Cancel (GTC) - Remains active until canceled.
1508    Gtc = 1,
1509    /// Immediate or Cancel (IOC) - Executes immediately to the extent possible, with any unfilled portion canceled.
1510    Ioc = 2,
1511    /// Fill or Kill (FOK) - Executes in its entirety immediately or is canceled if full execution is not possible.
1512    Fok = 3,
1513    /// Good Till Date (GTD) - Remains active until the specified expiration date or time is reached.
1514    Gtd = 4,
1515    /// Day - Remains active until the close of the current trading session.
1516    Day = 5,
1517    /// At the Opening (ATO) - Executes at the market opening or expires if not filled.
1518    AtTheOpen = 6,
1519    /// At the Closing (ATC) - Executes at the market close or expires if not filled.
1520    AtTheClose = 7,
1521}
1522
1523/// The trading state for a node.
1524#[repr(C)]
1525#[derive(
1526    Copy,
1527    Clone,
1528    Debug,
1529    Display,
1530    Hash,
1531    PartialEq,
1532    Eq,
1533    PartialOrd,
1534    Ord,
1535    AsRefStr,
1536    FromRepr,
1537    EnumIter,
1538    EnumString,
1539)]
1540#[strum(ascii_case_insensitive)]
1541#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1542#[cfg_attr(
1543    feature = "python",
1544    pyo3::pyclass(
1545        frozen,
1546        eq,
1547        eq_int,
1548        hash,
1549        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1550    )
1551)]
1552pub enum TradingState {
1553    /// Normal trading operations.
1554    Active = 1,
1555    /// Trading is completely halted, no new order commands will be emitted.
1556    Halted = 2,
1557    /// Only order commands which would cancel order, or reduce position sizes are permitted.
1558    Reducing = 3,
1559}
1560
1561/// The trailing offset type for an order type which specifies a trailing stop/trigger or limit price.
1562#[repr(C)]
1563#[derive(
1564    Copy,
1565    Clone,
1566    Debug,
1567    Default,
1568    Display,
1569    Hash,
1570    PartialEq,
1571    Eq,
1572    PartialOrd,
1573    Ord,
1574    AsRefStr,
1575    FromRepr,
1576    EnumIter,
1577    EnumString,
1578)]
1579#[strum(ascii_case_insensitive)]
1580#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1581#[cfg_attr(
1582    feature = "python",
1583    pyo3::pyclass(
1584        frozen,
1585        eq,
1586        eq_int,
1587        hash,
1588        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1589    )
1590)]
1591pub enum TrailingOffsetType {
1592    /// No trailing offset type is specified (invalid for trailing type orders).
1593    #[default]
1594    NoTrailingOffset = 0,
1595    /// The trailing offset is based on a market price.
1596    Price = 1,
1597    /// The trailing offset is based on a percentage represented in basis points, of a market price.
1598    BasisPoints = 2,
1599    /// The trailing offset is based on the number of ticks from a market price.
1600    Ticks = 3,
1601    /// The trailing offset is based on a price tier set by a specific trading venue.
1602    PriceTier = 4,
1603}
1604
1605/// The trigger type for the stop/trigger price of an order.
1606#[repr(C)]
1607#[derive(
1608    Copy,
1609    Clone,
1610    Debug,
1611    Default,
1612    Display,
1613    Hash,
1614    PartialEq,
1615    Eq,
1616    PartialOrd,
1617    Ord,
1618    AsRefStr,
1619    FromRepr,
1620    EnumIter,
1621    EnumString,
1622)]
1623#[strum(ascii_case_insensitive)]
1624#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1625#[cfg_attr(
1626    feature = "python",
1627    pyo3::pyclass(
1628        frozen,
1629        eq,
1630        eq_int,
1631        hash,
1632        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1633    )
1634)]
1635pub enum TriggerType {
1636    /// No trigger type is specified (invalid for orders with a trigger).
1637    #[default]
1638    NoTrigger = 0,
1639    /// The default trigger type set by the trading venue.
1640    Default = 1,
1641    /// Based on the last traded price for the instrument.
1642    LastPrice = 2,
1643    /// Based on the mark price for the instrument.
1644    MarkPrice = 3,
1645    /// Based on the index price for the instrument.
1646    IndexPrice = 4,
1647    /// Based on the top-of-book quoted prices for the instrument.
1648    BidAsk = 5,
1649    /// Based on a 'double match' of the last traded price for the instrument
1650    DoubleLast = 6,
1651    /// Based on a 'double match' of the bid/ask price for the instrument
1652    DoubleBidAsk = 7,
1653    /// Based on both the [`TriggerType::LastPrice`] and [`TriggerType::BidAsk`].
1654    LastOrBidAsk = 8,
1655    /// Based on the mid-point of the [`TriggerType::BidAsk`].
1656    MidPoint = 9,
1657}
1658
1659enum_strum_serde!(AccountType);
1660enum_strum_serde!(AggregationSource);
1661enum_strum_serde!(AggressorSide);
1662enum_strum_serde!(AssetClass);
1663enum_strum_serde!(BarAggregation);
1664enum_strum_serde!(BarIntervalType);
1665enum_strum_serde!(BookAction);
1666enum_strum_serde!(BookType);
1667enum_strum_serde!(ContingencyType);
1668enum_strum_serde!(CurrencyType);
1669enum_strum_serde!(InstrumentClass);
1670enum_strum_serde!(InstrumentCloseType);
1671enum_strum_serde!(LiquiditySide);
1672enum_strum_serde!(MarketStatus);
1673enum_strum_serde!(MarketStatusAction);
1674enum_strum_serde!(OmsType);
1675enum_strum_serde!(OptionKind);
1676enum_strum_serde!(OrderSide);
1677enum_strum_serde!(OrderSideSpecified);
1678enum_strum_serde!(OrderStatus);
1679enum_strum_serde!(OrderType);
1680enum_strum_serde!(PositionAdjustmentType);
1681enum_strum_serde!(PositionSide);
1682enum_strum_serde!(PositionSideSpecified);
1683enum_strum_serde!(PriceType);
1684enum_strum_serde!(RecordFlag);
1685enum_strum_serde!(TimeInForce);
1686enum_strum_serde!(TradingState);
1687enum_strum_serde!(TrailingOffsetType);
1688enum_strum_serde!(TriggerType);