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#[cfg_attr(
475    feature = "python",
476    pyo3::pyclass(
477        frozen,
478        eq,
479        eq_int,
480        hash,
481        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
482    )
483)]
484#[allow(non_camel_case_types)]
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
643impl InstrumentClass {
644    /// Returns whether this instrument class has an expiration.
645    #[must_use]
646    pub const fn has_expiration(&self) -> bool {
647        matches!(
648            self,
649            Self::Future | Self::FuturesSpread | Self::Option | Self::OptionSpread
650        )
651    }
652}
653
654/// The type of event for an instrument close.
655#[repr(C)]
656#[derive(
657    Copy,
658    Clone,
659    Debug,
660    Display,
661    Hash,
662    PartialEq,
663    Eq,
664    PartialOrd,
665    Ord,
666    AsRefStr,
667    FromRepr,
668    EnumIter,
669    EnumString,
670)]
671#[strum(ascii_case_insensitive)]
672#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
673#[cfg_attr(
674    feature = "python",
675    pyo3::pyclass(
676        frozen,
677        eq,
678        eq_int,
679        hash,
680        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
681    )
682)]
683pub enum InstrumentCloseType {
684    /// When the market session ended.
685    EndOfSession = 1,
686    /// When the instrument expiration was reached.
687    ContractExpired = 2,
688}
689
690/// Convert the given `value` to an [`InstrumentCloseType`].
691impl FromU8 for InstrumentCloseType {
692    fn from_u8(value: u8) -> Option<Self> {
693        match value {
694            1 => Some(Self::EndOfSession),
695            2 => Some(Self::ContractExpired),
696            _ => None,
697        }
698    }
699}
700
701/// The liquidity side for a trade.
702#[repr(C)]
703#[derive(
704    Copy,
705    Clone,
706    Debug,
707    Display,
708    Hash,
709    PartialEq,
710    Eq,
711    PartialOrd,
712    Ord,
713    AsRefStr,
714    FromRepr,
715    EnumIter,
716    EnumString,
717)]
718#[strum(ascii_case_insensitive)]
719#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
720#[cfg_attr(
721    feature = "python",
722    pyo3::pyclass(
723        frozen,
724        eq,
725        eq_int,
726        hash,
727        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
728    )
729)]
730#[allow(clippy::enum_variant_names)]
731pub enum LiquiditySide {
732    /// No liquidity side specified.
733    NoLiquiditySide = 0,
734    /// The order passively provided liquidity to the market to complete the trade (made a market).
735    Maker = 1,
736    /// The order aggressively took liquidity from the market to complete the trade.
737    Taker = 2,
738}
739
740/// The status of an individual market on a trading venue.
741#[repr(C)]
742#[derive(
743    Copy,
744    Clone,
745    Debug,
746    Display,
747    Hash,
748    PartialEq,
749    Eq,
750    PartialOrd,
751    Ord,
752    AsRefStr,
753    FromRepr,
754    EnumIter,
755    EnumString,
756)]
757#[strum(ascii_case_insensitive)]
758#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
759#[cfg_attr(
760    feature = "python",
761    pyo3::pyclass(
762        frozen,
763        eq,
764        eq_int,
765        hash,
766        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
767    )
768)]
769pub enum MarketStatus {
770    /// The instrument is trading.
771    Open = 1,
772    /// The instrument is in a pre-open period.
773    Closed = 2,
774    /// Trading in the instrument has been paused.
775    Paused = 3,
776    /// Trading in the instrument has been halted.
777    // Halted = 4,  # TODO: Unfortunately can't use this yet due to Cython (C enum namespacing)
778    /// Trading in the instrument has been suspended.
779    Suspended = 5,
780    /// Trading in the instrument is not available.
781    NotAvailable = 6,
782}
783
784/// An action affecting the status of an individual market on a trading venue.
785#[repr(C)]
786#[derive(
787    Copy,
788    Clone,
789    Debug,
790    Display,
791    Hash,
792    PartialEq,
793    Eq,
794    PartialOrd,
795    Ord,
796    AsRefStr,
797    FromRepr,
798    EnumIter,
799    EnumString,
800)]
801#[strum(ascii_case_insensitive)]
802#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
803#[cfg_attr(
804    feature = "python",
805    pyo3::pyclass(
806        frozen,
807        eq,
808        eq_int,
809        hash,
810        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
811    )
812)]
813pub enum MarketStatusAction {
814    /// No change.
815    None = 0,
816    /// The instrument is in a pre-open period.
817    PreOpen = 1,
818    /// The instrument is in a pre-cross period.
819    PreCross = 2,
820    /// The instrument is quoting but not trading.
821    Quoting = 3,
822    /// The instrument is in a cross/auction.
823    Cross = 4,
824    /// The instrument is being opened through a trading rotation.
825    Rotation = 5,
826    /// A new price indication is available for the instrument.
827    NewPriceIndication = 6,
828    /// The instrument is trading.
829    Trading = 7,
830    /// Trading in the instrument has been halted.
831    Halt = 8,
832    /// Trading in the instrument has been paused.
833    Pause = 9,
834    /// Trading in the instrument has been suspended.
835    Suspend = 10,
836    /// The instrument is in a pre-close period.
837    PreClose = 11,
838    /// Trading in the instrument has closed.
839    Close = 12,
840    /// The instrument is in a post-close period.
841    PostClose = 13,
842    /// A change in short-selling restrictions.
843    ShortSellRestrictionChange = 14,
844    /// The instrument is not available for trading, either trading has closed or been halted.
845    NotAvailableForTrading = 15,
846}
847
848/// Convert the given `value` to an [`OrderSide`].
849impl FromU16 for MarketStatusAction {
850    fn from_u16(value: u16) -> Option<Self> {
851        match value {
852            0 => Some(Self::None),
853            1 => Some(Self::PreOpen),
854            2 => Some(Self::PreCross),
855            3 => Some(Self::Quoting),
856            4 => Some(Self::Cross),
857            5 => Some(Self::Rotation),
858            6 => Some(Self::NewPriceIndication),
859            7 => Some(Self::Trading),
860            8 => Some(Self::Halt),
861            9 => Some(Self::Pause),
862            10 => Some(Self::Suspend),
863            11 => Some(Self::PreClose),
864            12 => Some(Self::Close),
865            13 => Some(Self::PostClose),
866            14 => Some(Self::ShortSellRestrictionChange),
867            15 => Some(Self::NotAvailableForTrading),
868            _ => None,
869        }
870    }
871}
872
873/// The order management system (OMS) type for a trading venue or trading strategy.
874#[repr(C)]
875#[derive(
876    Copy,
877    Clone,
878    Debug,
879    Default,
880    Display,
881    Hash,
882    PartialEq,
883    Eq,
884    PartialOrd,
885    Ord,
886    AsRefStr,
887    FromRepr,
888    EnumIter,
889    EnumString,
890)]
891#[strum(ascii_case_insensitive)]
892#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
893#[cfg_attr(
894    feature = "python",
895    pyo3::pyclass(
896        frozen,
897        eq,
898        eq_int,
899        hash,
900        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
901    )
902)]
903pub enum OmsType {
904    /// There is no specific type of order management specified (will defer to the venue OMS).
905    #[default]
906    Unspecified = 0,
907    /// The netting type where there is one position per instrument.
908    Netting = 1,
909    /// The hedging type where there can be multiple positions per instrument.
910    /// This can be in LONG/SHORT directions, by position/ticket ID, or tracked virtually by
911    /// Nautilus.
912    Hedging = 2,
913}
914
915/// The kind of option contract.
916#[repr(C)]
917#[derive(
918    Copy,
919    Clone,
920    Debug,
921    Display,
922    Hash,
923    PartialEq,
924    Eq,
925    PartialOrd,
926    Ord,
927    AsRefStr,
928    FromRepr,
929    EnumIter,
930    EnumString,
931)]
932#[strum(ascii_case_insensitive)]
933#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
934#[cfg_attr(
935    feature = "python",
936    pyo3::pyclass(
937        frozen,
938        eq,
939        eq_int,
940        hash,
941        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
942    )
943)]
944pub enum OptionKind {
945    /// 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.
946    Call = 1,
947    /// 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.
948    Put = 2,
949}
950
951/// The order side for a specific order, or action related to orders.
952#[repr(C)]
953#[derive(
954    Copy,
955    Clone,
956    Debug,
957    Default,
958    Display,
959    Hash,
960    PartialEq,
961    Eq,
962    PartialOrd,
963    Ord,
964    AsRefStr,
965    FromRepr,
966    EnumIter,
967    EnumString,
968)]
969#[strum(ascii_case_insensitive)]
970#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
971#[allow(clippy::enum_variant_names)]
972#[cfg_attr(
973    feature = "python",
974    pyo3::pyclass(
975        frozen,
976        eq,
977        eq_int,
978        hash,
979        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
980    )
981)]
982pub enum OrderSide {
983    /// No order side is specified.
984    #[default]
985    NoOrderSide = 0,
986    /// The order is a BUY.
987    Buy = 1,
988    /// The order is a SELL.
989    Sell = 2,
990}
991
992impl OrderSide {
993    /// Returns the specified [`OrderSideSpecified`] (BUY or SELL) for this side.
994    ///
995    /// # Panics
996    ///
997    /// Panics if `self` is [`OrderSide::NoOrderSide`].
998    #[must_use]
999    pub fn as_specified(&self) -> OrderSideSpecified {
1000        match &self {
1001            Self::Buy => OrderSideSpecified::Buy,
1002            Self::Sell => OrderSideSpecified::Sell,
1003            _ => panic!("Order invariant failed: side must be `Buy` or `Sell`"),
1004        }
1005    }
1006}
1007
1008/// Convert the given `value` to an [`OrderSide`].
1009impl FromU8 for OrderSide {
1010    fn from_u8(value: u8) -> Option<Self> {
1011        match value {
1012            0 => Some(Self::NoOrderSide),
1013            1 => Some(Self::Buy),
1014            2 => Some(Self::Sell),
1015            _ => None,
1016        }
1017    }
1018}
1019
1020/// The specified order side (BUY or SELL).
1021#[repr(C)]
1022#[derive(
1023    Copy,
1024    Clone,
1025    Debug,
1026    Display,
1027    Hash,
1028    PartialEq,
1029    Eq,
1030    PartialOrd,
1031    Ord,
1032    AsRefStr,
1033    FromRepr,
1034    EnumIter,
1035    EnumString,
1036)]
1037#[strum(ascii_case_insensitive)]
1038#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1039#[allow(clippy::enum_variant_names)]
1040pub enum OrderSideSpecified {
1041    /// The order is a BUY.
1042    Buy = 1,
1043    /// The order is a SELL.
1044    Sell = 2,
1045}
1046
1047impl OrderSideSpecified {
1048    /// Returns the opposite order side.
1049    #[must_use]
1050    pub fn opposite(&self) -> Self {
1051        match &self {
1052            Self::Buy => Self::Sell,
1053            Self::Sell => Self::Buy,
1054        }
1055    }
1056
1057    /// Converts this specified side into an [`OrderSide`].
1058    #[must_use]
1059    pub fn as_order_side(&self) -> OrderSide {
1060        match &self {
1061            Self::Buy => OrderSide::Buy,
1062            Self::Sell => OrderSide::Sell,
1063        }
1064    }
1065}
1066
1067/// The status for a specific order.
1068///
1069/// An order is considered _open_ for the following status:
1070///  - `ACCEPTED`
1071///  - `TRIGGERED`
1072///  - `PENDING_UPDATE`
1073///  - `PENDING_CANCEL`
1074///  - `PARTIALLY_FILLED`
1075///
1076/// An order is considered _in-flight_ for the following status:
1077///  - `SUBMITTED`
1078///  - `PENDING_UPDATE`
1079///  - `PENDING_CANCEL`
1080///
1081/// An order is considered _closed_ for the following status:
1082///  - `DENIED`
1083///  - `REJECTED`
1084///  - `CANCELED`
1085///  - `EXPIRED`
1086///  - `FILLED`
1087#[repr(C)]
1088#[derive(
1089    Copy,
1090    Clone,
1091    Debug,
1092    Display,
1093    Hash,
1094    PartialEq,
1095    Eq,
1096    PartialOrd,
1097    Ord,
1098    AsRefStr,
1099    FromRepr,
1100    EnumIter,
1101    EnumString,
1102)]
1103#[strum(ascii_case_insensitive)]
1104#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1105#[cfg_attr(
1106    feature = "python",
1107    pyo3::pyclass(
1108        frozen,
1109        eq,
1110        eq_int,
1111        hash,
1112        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1113    )
1114)]
1115pub enum OrderStatus {
1116    /// The order is initialized (instantiated) within the Nautilus system.
1117    Initialized = 1,
1118    /// The order was denied by the Nautilus system, either for being invalid, unprocessable or exceeding a risk limit.
1119    Denied = 2,
1120    /// The order became emulated by the Nautilus system in the `OrderEmulator` component.
1121    Emulated = 3,
1122    /// The order was released by the Nautilus system from the `OrderEmulator` component.
1123    Released = 4,
1124    /// The order was submitted by the Nautilus system to the external service or trading venue (awaiting acknowledgement).
1125    Submitted = 5,
1126    /// The order was acknowledged by the trading venue as being received and valid (may now be working).
1127    Accepted = 6,
1128    /// The order was rejected by the trading venue.
1129    Rejected = 7,
1130    /// The order was canceled (closed/done).
1131    Canceled = 8,
1132    /// The order reached a GTD expiration (closed/done).
1133    Expired = 9,
1134    /// The order STOP price was triggered on a trading venue.
1135    Triggered = 10,
1136    /// The order is currently pending a request to modify on a trading venue.
1137    PendingUpdate = 11,
1138    /// The order is currently pending a request to cancel on a trading venue.
1139    PendingCancel = 12,
1140    /// The order has been partially filled on a trading venue.
1141    PartiallyFilled = 13,
1142    /// The order has been completely filled on a trading venue (closed/done).
1143    Filled = 14,
1144}
1145
1146impl OrderStatus {
1147    /// Returns a cached `AHashSet` of order statuses safe for cancellation queries.
1148    ///
1149    /// These are statuses where an order is working on the venue but not already
1150    /// in the process of being cancelled or updated. Including `PENDING_CANCEL`
1151    /// in cancellation filters can cause duplicate cancel attempts or incorrect open order counts.
1152    ///
1153    /// Returns:
1154    /// - `ACCEPTED`: Order is working on the venue.
1155    /// - `TRIGGERED`: Stop order has been triggered.
1156    /// - `PENDING_UPDATE`: Order being updated.
1157    /// - `PARTIALLY_FILLED`: Order is partially filled but still working.
1158    ///
1159    /// Excludes:
1160    /// - `PENDING_CANCEL`: Already being cancelled.
1161    #[must_use]
1162    pub fn cancellable_statuses_set() -> &'static AHashSet<Self> {
1163        static CANCELLABLE_SET: OnceLock<AHashSet<OrderStatus>> = OnceLock::new();
1164        CANCELLABLE_SET.get_or_init(|| {
1165            AHashSet::from_iter([
1166                Self::Accepted,
1167                Self::Triggered,
1168                Self::PendingUpdate,
1169                Self::PartiallyFilled,
1170            ])
1171        })
1172    }
1173
1174    /// Returns whether the order status represents an open/working order.
1175    #[must_use]
1176    pub const fn is_open(self) -> bool {
1177        matches!(
1178            self,
1179            Self::Submitted
1180                | Self::Accepted
1181                | Self::Triggered
1182                | Self::PendingUpdate
1183                | Self::PendingCancel
1184                | Self::PartiallyFilled
1185        )
1186    }
1187}
1188
1189/// The type of order.
1190#[repr(C)]
1191#[derive(
1192    Copy,
1193    Clone,
1194    Debug,
1195    Display,
1196    Hash,
1197    PartialEq,
1198    Eq,
1199    PartialOrd,
1200    Ord,
1201    AsRefStr,
1202    FromRepr,
1203    EnumIter,
1204    EnumString,
1205)]
1206#[strum(ascii_case_insensitive)]
1207#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1208#[cfg_attr(
1209    feature = "python",
1210    pyo3::pyclass(
1211        frozen,
1212        eq,
1213        eq_int,
1214        hash,
1215        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1216    )
1217)]
1218pub enum OrderType {
1219    /// A market order to buy or sell at the best available price in the current market.
1220    Market = 1,
1221    /// A limit order to buy or sell at a specific price or better.
1222    Limit = 2,
1223    /// 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.
1224    StopMarket = 3,
1225    /// 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.
1226    StopLimit = 4,
1227    /// 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.
1228    MarketToLimit = 5,
1229    /// A market-if-touched order effectively becomes a market order when the specified trigger price is reached.
1230    MarketIfTouched = 6,
1231    /// A limit-if-touched order effectively becomes a limit order when the specified trigger price is reached.
1232    LimitIfTouched = 7,
1233    /// A trailing stop market order sets the stop/trigger price at a fixed "trailing offset" amount from the market.
1234    TrailingStopMarket = 8,
1235    /// A trailing stop limit order combines the features of a trailing stop order with those of a limit order.
1236    TrailingStopLimit = 9,
1237}
1238
1239/// The type of position adjustment.
1240#[repr(C)]
1241#[derive(
1242    Copy,
1243    Clone,
1244    Debug,
1245    Display,
1246    Hash,
1247    PartialEq,
1248    Eq,
1249    PartialOrd,
1250    Ord,
1251    AsRefStr,
1252    FromRepr,
1253    EnumIter,
1254    EnumString,
1255)]
1256#[strum(ascii_case_insensitive)]
1257#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1258#[cfg_attr(
1259    feature = "python",
1260    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.model.enums")
1261)]
1262pub enum PositionAdjustmentType {
1263    /// Commission adjustment affecting position quantity.
1264    Commission = 1,
1265    /// Funding payment affecting position realized PnL.
1266    Funding = 2,
1267}
1268
1269impl FromU8 for PositionAdjustmentType {
1270    fn from_u8(value: u8) -> Option<Self> {
1271        match value {
1272            1 => Some(Self::Commission),
1273            2 => Some(Self::Funding),
1274            _ => None,
1275        }
1276    }
1277}
1278
1279/// The market side for a specific position, or action related to positions.
1280#[repr(C)]
1281#[derive(
1282    Copy,
1283    Clone,
1284    Debug,
1285    Default,
1286    Display,
1287    Hash,
1288    PartialEq,
1289    Eq,
1290    PartialOrd,
1291    Ord,
1292    AsRefStr,
1293    FromRepr,
1294    EnumIter,
1295    EnumString,
1296)]
1297#[strum(ascii_case_insensitive)]
1298#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1299#[allow(clippy::enum_variant_names)]
1300#[cfg_attr(
1301    feature = "python",
1302    pyo3::pyclass(
1303        frozen,
1304        eq,
1305        eq_int,
1306        hash,
1307        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1308    )
1309)]
1310pub enum PositionSide {
1311    /// No position side is specified (only valid in the context of a filter for actions involving positions).
1312    #[default]
1313    NoPositionSide = 0,
1314    /// A neural/flat position, where no position is currently held in the market.
1315    Flat = 1,
1316    /// A long position in the market, typically acquired through one or many BUY orders.
1317    Long = 2,
1318    /// A short position in the market, typically acquired through one or many SELL orders.
1319    Short = 3,
1320}
1321
1322impl PositionSide {
1323    /// Returns the specified [`PositionSideSpecified`] (`Long`, `Short`, or `Flat`) for this side.
1324    ///
1325    /// # Panics
1326    ///
1327    /// Panics if `self` is [`PositionSide::NoPositionSide`].
1328    #[must_use]
1329    pub fn as_specified(&self) -> PositionSideSpecified {
1330        match &self {
1331            Self::Long => PositionSideSpecified::Long,
1332            Self::Short => PositionSideSpecified::Short,
1333            Self::Flat => PositionSideSpecified::Flat,
1334            _ => panic!("Position invariant failed: side must be `Long`, `Short`, or `Flat`"),
1335        }
1336    }
1337}
1338
1339/// The market side for a specific position, or action related to positions.
1340#[repr(C)]
1341#[derive(
1342    Copy,
1343    Clone,
1344    Debug,
1345    Display,
1346    Hash,
1347    PartialEq,
1348    Eq,
1349    PartialOrd,
1350    Ord,
1351    AsRefStr,
1352    FromRepr,
1353    EnumIter,
1354    EnumString,
1355)]
1356#[strum(ascii_case_insensitive)]
1357#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1358#[allow(clippy::enum_variant_names)]
1359#[cfg_attr(
1360    feature = "python",
1361    pyo3::pyclass(
1362        frozen,
1363        eq,
1364        eq_int,
1365        hash,
1366        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1367    )
1368)]
1369pub enum PositionSideSpecified {
1370    /// A neural/flat position, where no position is currently held in the market.
1371    Flat = 1,
1372    /// A long position in the market, typically acquired through one or many BUY orders.
1373    Long = 2,
1374    /// A short position in the market, typically acquired through one or many SELL orders.
1375    Short = 3,
1376}
1377
1378impl PositionSideSpecified {
1379    /// Converts this specified side into a [`PositionSide`].
1380    #[must_use]
1381    pub fn as_position_side(&self) -> PositionSide {
1382        match &self {
1383            Self::Long => PositionSide::Long,
1384            Self::Short => PositionSide::Short,
1385            Self::Flat => PositionSide::Flat,
1386        }
1387    }
1388}
1389
1390/// The type of price for an instrument in a market.
1391#[repr(C)]
1392#[derive(
1393    Copy,
1394    Clone,
1395    Debug,
1396    Display,
1397    Hash,
1398    PartialEq,
1399    Eq,
1400    PartialOrd,
1401    Ord,
1402    AsRefStr,
1403    FromRepr,
1404    EnumIter,
1405    EnumString,
1406)]
1407#[strum(ascii_case_insensitive)]
1408#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1409#[cfg_attr(
1410    feature = "python",
1411    pyo3::pyclass(
1412        frozen,
1413        eq,
1414        eq_int,
1415        hash,
1416        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1417    )
1418)]
1419pub enum PriceType {
1420    /// The best quoted price at which buyers are willing to buy a quantity of an instrument.
1421    /// Often considered the best bid in the order book.
1422    Bid = 1,
1423    /// The best quoted price at which sellers are willing to sell a quantity of an instrument.
1424    /// Often considered the best ask in the order book.
1425    Ask = 2,
1426    /// The arithmetic midpoint between the best bid and ask quotes.
1427    Mid = 3,
1428    /// The price at which the last trade of an instrument was executed.
1429    Last = 4,
1430    /// A reference price reflecting an instrument's fair value, often used for portfolio
1431    /// calculations and risk management.
1432    Mark = 5,
1433}
1434
1435/// A record flag bit field, indicating event end and data information.
1436#[repr(C)]
1437#[derive(
1438    Copy,
1439    Clone,
1440    Debug,
1441    Display,
1442    Hash,
1443    PartialEq,
1444    Eq,
1445    PartialOrd,
1446    Ord,
1447    AsRefStr,
1448    FromRepr,
1449    EnumIter,
1450    EnumString,
1451)]
1452#[strum(ascii_case_insensitive)]
1453#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1454#[cfg_attr(
1455    feature = "python",
1456    pyo3::pyclass(
1457        frozen,
1458        eq,
1459        eq_int,
1460        hash,
1461        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1462    )
1463)]
1464#[allow(non_camel_case_types)]
1465pub enum RecordFlag {
1466    /// Last message in the book event or packet from the venue for a given `instrument_id`.
1467    F_LAST = 1 << 7, // 128
1468    /// Top-of-book message, not an individual order.
1469    F_TOB = 1 << 6, // 64
1470    /// Message sourced from a replay, such as a snapshot server.
1471    F_SNAPSHOT = 1 << 5, // 32
1472    /// Aggregated price level message, not an individual order.
1473    F_MBP = 1 << 4, // 16
1474    /// Reserved for future use.
1475    RESERVED_2 = 1 << 3, // 8
1476    /// Reserved for future use.
1477    RESERVED_1 = 1 << 2, // 4
1478}
1479
1480impl RecordFlag {
1481    /// Checks if the flag matches a given value.
1482    #[must_use]
1483    pub fn matches(self, value: u8) -> bool {
1484        (self as u8) & value != 0
1485    }
1486}
1487
1488/// The 'Time in Force' instruction for an order.
1489#[repr(C)]
1490#[derive(
1491    Copy,
1492    Clone,
1493    Debug,
1494    Display,
1495    Hash,
1496    PartialEq,
1497    Eq,
1498    PartialOrd,
1499    Ord,
1500    AsRefStr,
1501    FromRepr,
1502    EnumIter,
1503    EnumString,
1504)]
1505#[strum(ascii_case_insensitive)]
1506#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1507#[cfg_attr(
1508    feature = "python",
1509    pyo3::pyclass(
1510        frozen,
1511        eq,
1512        eq_int,
1513        hash,
1514        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1515    )
1516)]
1517pub enum TimeInForce {
1518    /// Good Till Cancel (GTC) - Remains active until canceled.
1519    Gtc = 1,
1520    /// Immediate or Cancel (IOC) - Executes immediately to the extent possible, with any unfilled portion canceled.
1521    Ioc = 2,
1522    /// Fill or Kill (FOK) - Executes in its entirety immediately or is canceled if full execution is not possible.
1523    Fok = 3,
1524    /// Good Till Date (GTD) - Remains active until the specified expiration date or time is reached.
1525    Gtd = 4,
1526    /// Day - Remains active until the close of the current trading session.
1527    Day = 5,
1528    /// At the Opening (ATO) - Executes at the market opening or expires if not filled.
1529    AtTheOpen = 6,
1530    /// At the Closing (ATC) - Executes at the market close or expires if not filled.
1531    AtTheClose = 7,
1532}
1533
1534/// The trading state for a node.
1535#[repr(C)]
1536#[derive(
1537    Copy,
1538    Clone,
1539    Debug,
1540    Display,
1541    Hash,
1542    PartialEq,
1543    Eq,
1544    PartialOrd,
1545    Ord,
1546    AsRefStr,
1547    FromRepr,
1548    EnumIter,
1549    EnumString,
1550)]
1551#[strum(ascii_case_insensitive)]
1552#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1553#[cfg_attr(
1554    feature = "python",
1555    pyo3::pyclass(
1556        frozen,
1557        eq,
1558        eq_int,
1559        hash,
1560        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1561    )
1562)]
1563pub enum TradingState {
1564    /// Normal trading operations.
1565    Active = 1,
1566    /// Trading is completely halted, no new order commands will be emitted.
1567    Halted = 2,
1568    /// Only order commands which would cancel order, or reduce position sizes are permitted.
1569    Reducing = 3,
1570}
1571
1572/// The trailing offset type for an order type which specifies a trailing stop/trigger or limit price.
1573#[repr(C)]
1574#[derive(
1575    Copy,
1576    Clone,
1577    Debug,
1578    Default,
1579    Display,
1580    Hash,
1581    PartialEq,
1582    Eq,
1583    PartialOrd,
1584    Ord,
1585    AsRefStr,
1586    FromRepr,
1587    EnumIter,
1588    EnumString,
1589)]
1590#[strum(ascii_case_insensitive)]
1591#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1592#[cfg_attr(
1593    feature = "python",
1594    pyo3::pyclass(
1595        frozen,
1596        eq,
1597        eq_int,
1598        hash,
1599        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1600    )
1601)]
1602pub enum TrailingOffsetType {
1603    /// No trailing offset type is specified (invalid for trailing type orders).
1604    #[default]
1605    NoTrailingOffset = 0,
1606    /// The trailing offset is based on a market price.
1607    Price = 1,
1608    /// The trailing offset is based on a percentage represented in basis points, of a market price.
1609    BasisPoints = 2,
1610    /// The trailing offset is based on the number of ticks from a market price.
1611    Ticks = 3,
1612    /// The trailing offset is based on a price tier set by a specific trading venue.
1613    PriceTier = 4,
1614}
1615
1616/// The trigger type for the stop/trigger price of an order.
1617#[repr(C)]
1618#[derive(
1619    Copy,
1620    Clone,
1621    Debug,
1622    Default,
1623    Display,
1624    Hash,
1625    PartialEq,
1626    Eq,
1627    PartialOrd,
1628    Ord,
1629    AsRefStr,
1630    FromRepr,
1631    EnumIter,
1632    EnumString,
1633)]
1634#[strum(ascii_case_insensitive)]
1635#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1636#[cfg_attr(
1637    feature = "python",
1638    pyo3::pyclass(
1639        frozen,
1640        eq,
1641        eq_int,
1642        hash,
1643        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1644    )
1645)]
1646pub enum TriggerType {
1647    /// No trigger type is specified (invalid for orders with a trigger).
1648    #[default]
1649    NoTrigger = 0,
1650    /// The default trigger type set by the trading venue.
1651    Default = 1,
1652    /// Based on the last traded price for the instrument.
1653    LastPrice = 2,
1654    /// Based on the mark price for the instrument.
1655    MarkPrice = 3,
1656    /// Based on the index price for the instrument.
1657    IndexPrice = 4,
1658    /// Based on the top-of-book quoted prices for the instrument.
1659    BidAsk = 5,
1660    /// Based on a 'double match' of the last traded price for the instrument
1661    DoubleLast = 6,
1662    /// Based on a 'double match' of the bid/ask price for the instrument
1663    DoubleBidAsk = 7,
1664    /// Based on both the [`TriggerType::LastPrice`] and [`TriggerType::BidAsk`].
1665    LastOrBidAsk = 8,
1666    /// Based on the mid-point of the [`TriggerType::BidAsk`].
1667    MidPoint = 9,
1668}
1669
1670enum_strum_serde!(AccountType);
1671enum_strum_serde!(AggregationSource);
1672enum_strum_serde!(AggressorSide);
1673enum_strum_serde!(AssetClass);
1674enum_strum_serde!(BarAggregation);
1675enum_strum_serde!(BarIntervalType);
1676enum_strum_serde!(BookAction);
1677enum_strum_serde!(BookType);
1678enum_strum_serde!(ContingencyType);
1679enum_strum_serde!(CurrencyType);
1680enum_strum_serde!(InstrumentClass);
1681enum_strum_serde!(InstrumentCloseType);
1682enum_strum_serde!(LiquiditySide);
1683enum_strum_serde!(MarketStatus);
1684enum_strum_serde!(MarketStatusAction);
1685enum_strum_serde!(OmsType);
1686enum_strum_serde!(OptionKind);
1687enum_strum_serde!(OrderSide);
1688enum_strum_serde!(OrderSideSpecified);
1689enum_strum_serde!(OrderStatus);
1690enum_strum_serde!(OrderType);
1691enum_strum_serde!(PositionAdjustmentType);
1692enum_strum_serde!(PositionSide);
1693enum_strum_serde!(PositionSideSpecified);
1694enum_strum_serde!(PriceType);
1695enum_strum_serde!(RecordFlag);
1696enum_strum_serde!(TimeInForce);
1697enum_strum_serde!(TradingState);
1698enum_strum_serde!(TrailingOffsetType);
1699enum_strum_serde!(TriggerType);