Skip to main content

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/// Defines when OTO (One-Triggers-Other) child orders are released.
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#[cfg_attr(
972    feature = "python",
973    pyo3::pyclass(
974        frozen,
975        eq,
976        eq_int,
977        hash,
978        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
979    )
980)]
981pub enum OtoTriggerMode {
982    /// Release child order(s) pro-rata to each partial fill (default).
983    #[default]
984    Partial = 0,
985    /// Release child order(s) only once the parent is fully filled.
986    Full = 1,
987}
988
989/// The order side for a specific order, or action related to orders.
990#[repr(C)]
991#[derive(
992    Copy,
993    Clone,
994    Debug,
995    Default,
996    Display,
997    Hash,
998    PartialEq,
999    Eq,
1000    PartialOrd,
1001    Ord,
1002    AsRefStr,
1003    FromRepr,
1004    EnumIter,
1005    EnumString,
1006)]
1007#[strum(ascii_case_insensitive)]
1008#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1009#[allow(clippy::enum_variant_names)]
1010#[cfg_attr(
1011    feature = "python",
1012    pyo3::pyclass(
1013        frozen,
1014        eq,
1015        eq_int,
1016        hash,
1017        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1018    )
1019)]
1020pub enum OrderSide {
1021    /// No order side is specified.
1022    #[default]
1023    NoOrderSide = 0,
1024    /// The order is a BUY.
1025    Buy = 1,
1026    /// The order is a SELL.
1027    Sell = 2,
1028}
1029
1030impl OrderSide {
1031    /// Returns the specified [`OrderSideSpecified`] (BUY or SELL) for this side.
1032    ///
1033    /// # Panics
1034    ///
1035    /// Panics if `self` is [`OrderSide::NoOrderSide`].
1036    #[must_use]
1037    pub fn as_specified(&self) -> OrderSideSpecified {
1038        match &self {
1039            Self::Buy => OrderSideSpecified::Buy,
1040            Self::Sell => OrderSideSpecified::Sell,
1041            _ => panic!("Order invariant failed: side must be `Buy` or `Sell`"),
1042        }
1043    }
1044}
1045
1046/// Convert the given `value` to an [`OrderSide`].
1047impl FromU8 for OrderSide {
1048    fn from_u8(value: u8) -> Option<Self> {
1049        match value {
1050            0 => Some(Self::NoOrderSide),
1051            1 => Some(Self::Buy),
1052            2 => Some(Self::Sell),
1053            _ => None,
1054        }
1055    }
1056}
1057
1058/// The specified order side (BUY or SELL).
1059#[repr(C)]
1060#[derive(
1061    Copy,
1062    Clone,
1063    Debug,
1064    Display,
1065    Hash,
1066    PartialEq,
1067    Eq,
1068    PartialOrd,
1069    Ord,
1070    AsRefStr,
1071    FromRepr,
1072    EnumIter,
1073    EnumString,
1074)]
1075#[strum(ascii_case_insensitive)]
1076#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1077#[allow(clippy::enum_variant_names)]
1078pub enum OrderSideSpecified {
1079    /// The order is a BUY.
1080    Buy = 1,
1081    /// The order is a SELL.
1082    Sell = 2,
1083}
1084
1085impl OrderSideSpecified {
1086    /// Returns the opposite order side.
1087    #[must_use]
1088    pub fn opposite(&self) -> Self {
1089        match &self {
1090            Self::Buy => Self::Sell,
1091            Self::Sell => Self::Buy,
1092        }
1093    }
1094
1095    /// Converts this specified side into an [`OrderSide`].
1096    #[must_use]
1097    pub fn as_order_side(&self) -> OrderSide {
1098        match &self {
1099            Self::Buy => OrderSide::Buy,
1100            Self::Sell => OrderSide::Sell,
1101        }
1102    }
1103}
1104
1105/// The status for a specific order.
1106///
1107/// An order is considered _open_ for the following status:
1108///  - `ACCEPTED`
1109///  - `TRIGGERED`
1110///  - `PENDING_UPDATE`
1111///  - `PENDING_CANCEL`
1112///  - `PARTIALLY_FILLED`
1113///
1114/// An order is considered _in-flight_ for the following status:
1115///  - `SUBMITTED`
1116///  - `PENDING_UPDATE`
1117///  - `PENDING_CANCEL`
1118///
1119/// An order is considered _closed_ for the following status:
1120///  - `DENIED`
1121///  - `REJECTED`
1122///  - `CANCELED`
1123///  - `EXPIRED`
1124///  - `FILLED`
1125#[repr(C)]
1126#[derive(
1127    Copy,
1128    Clone,
1129    Debug,
1130    Display,
1131    Hash,
1132    PartialEq,
1133    Eq,
1134    PartialOrd,
1135    Ord,
1136    AsRefStr,
1137    FromRepr,
1138    EnumIter,
1139    EnumString,
1140)]
1141#[strum(ascii_case_insensitive)]
1142#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1143#[cfg_attr(
1144    feature = "python",
1145    pyo3::pyclass(
1146        frozen,
1147        eq,
1148        eq_int,
1149        hash,
1150        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1151    )
1152)]
1153pub enum OrderStatus {
1154    /// The order is initialized (instantiated) within the Nautilus system.
1155    Initialized = 1,
1156    /// The order was denied by the Nautilus system, either for being invalid, unprocessable or exceeding a risk limit.
1157    Denied = 2,
1158    /// The order became emulated by the Nautilus system in the `OrderEmulator` component.
1159    Emulated = 3,
1160    /// The order was released by the Nautilus system from the `OrderEmulator` component.
1161    Released = 4,
1162    /// The order was submitted by the Nautilus system to the external service or trading venue (awaiting acknowledgement).
1163    Submitted = 5,
1164    /// The order was acknowledged by the trading venue as being received and valid (may now be working).
1165    Accepted = 6,
1166    /// The order was rejected by the trading venue.
1167    Rejected = 7,
1168    /// The order was canceled (closed/done).
1169    Canceled = 8,
1170    /// The order reached a GTD expiration (closed/done).
1171    Expired = 9,
1172    /// The order STOP price was triggered on a trading venue.
1173    Triggered = 10,
1174    /// The order is currently pending a request to modify on a trading venue.
1175    PendingUpdate = 11,
1176    /// The order is currently pending a request to cancel on a trading venue.
1177    PendingCancel = 12,
1178    /// The order has been partially filled on a trading venue.
1179    PartiallyFilled = 13,
1180    /// The order has been completely filled on a trading venue (closed/done).
1181    Filled = 14,
1182}
1183
1184impl OrderStatus {
1185    /// Returns a cached `AHashSet` of order statuses safe for cancellation queries.
1186    ///
1187    /// These are statuses where an order is working on the venue but not already
1188    /// in the process of being cancelled or updated. Including `PENDING_CANCEL`
1189    /// in cancellation filters can cause duplicate cancel attempts or incorrect open order counts.
1190    ///
1191    /// Returns:
1192    /// - `ACCEPTED`: Order is working on the venue.
1193    /// - `TRIGGERED`: Stop order has been triggered.
1194    /// - `PENDING_UPDATE`: Order being updated.
1195    /// - `PARTIALLY_FILLED`: Order is partially filled but still working.
1196    ///
1197    /// Excludes:
1198    /// - `PENDING_CANCEL`: Already being cancelled.
1199    #[must_use]
1200    pub fn cancellable_statuses_set() -> &'static AHashSet<Self> {
1201        static CANCELLABLE_SET: OnceLock<AHashSet<OrderStatus>> = OnceLock::new();
1202        CANCELLABLE_SET.get_or_init(|| {
1203            AHashSet::from_iter([
1204                Self::Accepted,
1205                Self::Triggered,
1206                Self::PendingUpdate,
1207                Self::PartiallyFilled,
1208            ])
1209        })
1210    }
1211
1212    /// Returns whether the order status represents an open/working order.
1213    #[must_use]
1214    pub const fn is_open(self) -> bool {
1215        matches!(
1216            self,
1217            Self::Submitted
1218                | Self::Accepted
1219                | Self::Triggered
1220                | Self::PendingUpdate
1221                | Self::PendingCancel
1222                | Self::PartiallyFilled
1223        )
1224    }
1225}
1226
1227/// The type of order.
1228#[repr(C)]
1229#[derive(
1230    Copy,
1231    Clone,
1232    Debug,
1233    Display,
1234    Hash,
1235    PartialEq,
1236    Eq,
1237    PartialOrd,
1238    Ord,
1239    AsRefStr,
1240    FromRepr,
1241    EnumIter,
1242    EnumString,
1243)]
1244#[strum(ascii_case_insensitive)]
1245#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1246#[cfg_attr(
1247    feature = "python",
1248    pyo3::pyclass(
1249        frozen,
1250        eq,
1251        eq_int,
1252        hash,
1253        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1254    )
1255)]
1256pub enum OrderType {
1257    /// A market order to buy or sell at the best available price in the current market.
1258    Market = 1,
1259    /// A limit order to buy or sell at a specific price or better.
1260    Limit = 2,
1261    /// 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.
1262    StopMarket = 3,
1263    /// 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.
1264    StopLimit = 4,
1265    /// 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.
1266    MarketToLimit = 5,
1267    /// A market-if-touched order effectively becomes a market order when the specified trigger price is reached.
1268    MarketIfTouched = 6,
1269    /// A limit-if-touched order effectively becomes a limit order when the specified trigger price is reached.
1270    LimitIfTouched = 7,
1271    /// A trailing stop market order sets the stop/trigger price at a fixed "trailing offset" amount from the market.
1272    TrailingStopMarket = 8,
1273    /// A trailing stop limit order combines the features of a trailing stop order with those of a limit order.
1274    TrailingStopLimit = 9,
1275}
1276
1277/// The type of position adjustment.
1278#[repr(C)]
1279#[derive(
1280    Copy,
1281    Clone,
1282    Debug,
1283    Display,
1284    Hash,
1285    PartialEq,
1286    Eq,
1287    PartialOrd,
1288    Ord,
1289    AsRefStr,
1290    FromRepr,
1291    EnumIter,
1292    EnumString,
1293)]
1294#[strum(ascii_case_insensitive)]
1295#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1296#[cfg_attr(
1297    feature = "python",
1298    pyo3::pyclass(eq, eq_int, module = "nautilus_trader.core.nautilus_pyo3.model.enums")
1299)]
1300pub enum PositionAdjustmentType {
1301    /// Commission adjustment affecting position quantity.
1302    Commission = 1,
1303    /// Funding payment affecting position realized PnL.
1304    Funding = 2,
1305}
1306
1307impl FromU8 for PositionAdjustmentType {
1308    fn from_u8(value: u8) -> Option<Self> {
1309        match value {
1310            1 => Some(Self::Commission),
1311            2 => Some(Self::Funding),
1312            _ => None,
1313        }
1314    }
1315}
1316
1317/// The market side for a specific position, or action related to positions.
1318#[repr(C)]
1319#[derive(
1320    Copy,
1321    Clone,
1322    Debug,
1323    Default,
1324    Display,
1325    Hash,
1326    PartialEq,
1327    Eq,
1328    PartialOrd,
1329    Ord,
1330    AsRefStr,
1331    FromRepr,
1332    EnumIter,
1333    EnumString,
1334)]
1335#[strum(ascii_case_insensitive)]
1336#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1337#[allow(clippy::enum_variant_names)]
1338#[cfg_attr(
1339    feature = "python",
1340    pyo3::pyclass(
1341        frozen,
1342        eq,
1343        eq_int,
1344        hash,
1345        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1346    )
1347)]
1348pub enum PositionSide {
1349    /// No position side is specified (only valid in the context of a filter for actions involving positions).
1350    #[default]
1351    NoPositionSide = 0,
1352    /// A neural/flat position, where no position is currently held in the market.
1353    Flat = 1,
1354    /// A long position in the market, typically acquired through one or many BUY orders.
1355    Long = 2,
1356    /// A short position in the market, typically acquired through one or many SELL orders.
1357    Short = 3,
1358}
1359
1360impl PositionSide {
1361    /// Returns the specified [`PositionSideSpecified`] (`Long`, `Short`, or `Flat`) for this side.
1362    ///
1363    /// # Panics
1364    ///
1365    /// Panics if `self` is [`PositionSide::NoPositionSide`].
1366    #[must_use]
1367    pub fn as_specified(&self) -> PositionSideSpecified {
1368        match &self {
1369            Self::Long => PositionSideSpecified::Long,
1370            Self::Short => PositionSideSpecified::Short,
1371            Self::Flat => PositionSideSpecified::Flat,
1372            _ => panic!("Position invariant failed: side must be `Long`, `Short`, or `Flat`"),
1373        }
1374    }
1375}
1376
1377/// The market side for a specific position, or action related to positions.
1378#[repr(C)]
1379#[derive(
1380    Copy,
1381    Clone,
1382    Debug,
1383    Display,
1384    Hash,
1385    PartialEq,
1386    Eq,
1387    PartialOrd,
1388    Ord,
1389    AsRefStr,
1390    FromRepr,
1391    EnumIter,
1392    EnumString,
1393)]
1394#[strum(ascii_case_insensitive)]
1395#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1396#[allow(clippy::enum_variant_names)]
1397#[cfg_attr(
1398    feature = "python",
1399    pyo3::pyclass(
1400        frozen,
1401        eq,
1402        eq_int,
1403        hash,
1404        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1405    )
1406)]
1407pub enum PositionSideSpecified {
1408    /// A neural/flat position, where no position is currently held in the market.
1409    Flat = 1,
1410    /// A long position in the market, typically acquired through one or many BUY orders.
1411    Long = 2,
1412    /// A short position in the market, typically acquired through one or many SELL orders.
1413    Short = 3,
1414}
1415
1416impl PositionSideSpecified {
1417    /// Converts this specified side into a [`PositionSide`].
1418    #[must_use]
1419    pub fn as_position_side(&self) -> PositionSide {
1420        match &self {
1421            Self::Long => PositionSide::Long,
1422            Self::Short => PositionSide::Short,
1423            Self::Flat => PositionSide::Flat,
1424        }
1425    }
1426}
1427
1428/// The type of price for an instrument in a market.
1429#[repr(C)]
1430#[derive(
1431    Copy,
1432    Clone,
1433    Debug,
1434    Display,
1435    Hash,
1436    PartialEq,
1437    Eq,
1438    PartialOrd,
1439    Ord,
1440    AsRefStr,
1441    FromRepr,
1442    EnumIter,
1443    EnumString,
1444)]
1445#[strum(ascii_case_insensitive)]
1446#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1447#[cfg_attr(
1448    feature = "python",
1449    pyo3::pyclass(
1450        frozen,
1451        eq,
1452        eq_int,
1453        hash,
1454        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1455    )
1456)]
1457pub enum PriceType {
1458    /// The best quoted price at which buyers are willing to buy a quantity of an instrument.
1459    /// Often considered the best bid in the order book.
1460    Bid = 1,
1461    /// The best quoted price at which sellers are willing to sell a quantity of an instrument.
1462    /// Often considered the best ask in the order book.
1463    Ask = 2,
1464    /// The arithmetic midpoint between the best bid and ask quotes.
1465    Mid = 3,
1466    /// The price at which the last trade of an instrument was executed.
1467    Last = 4,
1468    /// A reference price reflecting an instrument's fair value, often used for portfolio
1469    /// calculations and risk management.
1470    Mark = 5,
1471}
1472
1473/// A record flag bit field, indicating event end and data information.
1474#[repr(C)]
1475#[derive(
1476    Copy,
1477    Clone,
1478    Debug,
1479    Display,
1480    Hash,
1481    PartialEq,
1482    Eq,
1483    PartialOrd,
1484    Ord,
1485    AsRefStr,
1486    FromRepr,
1487    EnumIter,
1488    EnumString,
1489)]
1490#[strum(ascii_case_insensitive)]
1491#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1492#[cfg_attr(
1493    feature = "python",
1494    pyo3::pyclass(
1495        frozen,
1496        eq,
1497        eq_int,
1498        hash,
1499        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1500    )
1501)]
1502#[allow(non_camel_case_types)]
1503pub enum RecordFlag {
1504    /// Last message in the book event or packet from the venue for a given `instrument_id`.
1505    F_LAST = 1 << 7, // 128
1506    /// Top-of-book message, not an individual order.
1507    F_TOB = 1 << 6, // 64
1508    /// Message sourced from a replay, such as a snapshot server.
1509    F_SNAPSHOT = 1 << 5, // 32
1510    /// Aggregated price level message, not an individual order.
1511    F_MBP = 1 << 4, // 16
1512    /// Reserved for future use.
1513    RESERVED_2 = 1 << 3, // 8
1514    /// Reserved for future use.
1515    RESERVED_1 = 1 << 2, // 4
1516}
1517
1518impl RecordFlag {
1519    /// Checks if the flag matches a given value.
1520    #[must_use]
1521    pub fn matches(self, value: u8) -> bool {
1522        (self as u8) & value != 0
1523    }
1524}
1525
1526/// The 'Time in Force' instruction for an order.
1527#[repr(C)]
1528#[derive(
1529    Copy,
1530    Clone,
1531    Debug,
1532    Display,
1533    Hash,
1534    PartialEq,
1535    Eq,
1536    PartialOrd,
1537    Ord,
1538    AsRefStr,
1539    FromRepr,
1540    EnumIter,
1541    EnumString,
1542)]
1543#[strum(ascii_case_insensitive)]
1544#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1545#[cfg_attr(
1546    feature = "python",
1547    pyo3::pyclass(
1548        frozen,
1549        eq,
1550        eq_int,
1551        hash,
1552        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1553    )
1554)]
1555pub enum TimeInForce {
1556    /// Good Till Cancel (GTC) - Remains active until canceled.
1557    Gtc = 1,
1558    /// Immediate or Cancel (IOC) - Executes immediately to the extent possible, with any unfilled portion canceled.
1559    Ioc = 2,
1560    /// Fill or Kill (FOK) - Executes in its entirety immediately or is canceled if full execution is not possible.
1561    Fok = 3,
1562    /// Good Till Date (GTD) - Remains active until the specified expiration date or time is reached.
1563    Gtd = 4,
1564    /// Day - Remains active until the close of the current trading session.
1565    Day = 5,
1566    /// At the Opening (ATO) - Executes at the market opening or expires if not filled.
1567    AtTheOpen = 6,
1568    /// At the Closing (ATC) - Executes at the market close or expires if not filled.
1569    AtTheClose = 7,
1570}
1571
1572/// The trading state for a node.
1573#[repr(C)]
1574#[derive(
1575    Copy,
1576    Clone,
1577    Debug,
1578    Display,
1579    Hash,
1580    PartialEq,
1581    Eq,
1582    PartialOrd,
1583    Ord,
1584    AsRefStr,
1585    FromRepr,
1586    EnumIter,
1587    EnumString,
1588)]
1589#[strum(ascii_case_insensitive)]
1590#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1591#[cfg_attr(
1592    feature = "python",
1593    pyo3::pyclass(
1594        frozen,
1595        eq,
1596        eq_int,
1597        hash,
1598        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1599    )
1600)]
1601pub enum TradingState {
1602    /// Normal trading operations.
1603    Active = 1,
1604    /// Trading is completely halted, no new order commands will be emitted.
1605    Halted = 2,
1606    /// Only order commands which would cancel order, or reduce position sizes are permitted.
1607    Reducing = 3,
1608}
1609
1610/// The trailing offset type for an order type which specifies a trailing stop/trigger or limit price.
1611#[repr(C)]
1612#[derive(
1613    Copy,
1614    Clone,
1615    Debug,
1616    Default,
1617    Display,
1618    Hash,
1619    PartialEq,
1620    Eq,
1621    PartialOrd,
1622    Ord,
1623    AsRefStr,
1624    FromRepr,
1625    EnumIter,
1626    EnumString,
1627)]
1628#[strum(ascii_case_insensitive)]
1629#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1630#[cfg_attr(
1631    feature = "python",
1632    pyo3::pyclass(
1633        frozen,
1634        eq,
1635        eq_int,
1636        hash,
1637        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1638    )
1639)]
1640pub enum TrailingOffsetType {
1641    /// No trailing offset type is specified (invalid for trailing type orders).
1642    #[default]
1643    NoTrailingOffset = 0,
1644    /// The trailing offset is based on a market price.
1645    Price = 1,
1646    /// The trailing offset is based on a percentage represented in basis points, of a market price.
1647    BasisPoints = 2,
1648    /// The trailing offset is based on the number of ticks from a market price.
1649    Ticks = 3,
1650    /// The trailing offset is based on a price tier set by a specific trading venue.
1651    PriceTier = 4,
1652}
1653
1654/// The trigger type for the stop/trigger price of an order.
1655#[repr(C)]
1656#[derive(
1657    Copy,
1658    Clone,
1659    Debug,
1660    Default,
1661    Display,
1662    Hash,
1663    PartialEq,
1664    Eq,
1665    PartialOrd,
1666    Ord,
1667    AsRefStr,
1668    FromRepr,
1669    EnumIter,
1670    EnumString,
1671)]
1672#[strum(ascii_case_insensitive)]
1673#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
1674#[cfg_attr(
1675    feature = "python",
1676    pyo3::pyclass(
1677        frozen,
1678        eq,
1679        eq_int,
1680        hash,
1681        module = "nautilus_trader.core.nautilus_pyo3.model.enums"
1682    )
1683)]
1684pub enum TriggerType {
1685    /// No trigger type is specified (invalid for orders with a trigger).
1686    #[default]
1687    NoTrigger = 0,
1688    /// The default trigger type set by the trading venue.
1689    Default = 1,
1690    /// Based on the last traded price for the instrument.
1691    LastPrice = 2,
1692    /// Based on the mark price for the instrument.
1693    MarkPrice = 3,
1694    /// Based on the index price for the instrument.
1695    IndexPrice = 4,
1696    /// Based on the top-of-book quoted prices for the instrument.
1697    BidAsk = 5,
1698    /// Based on a 'double match' of the last traded price for the instrument
1699    DoubleLast = 6,
1700    /// Based on a 'double match' of the bid/ask price for the instrument
1701    DoubleBidAsk = 7,
1702    /// Based on both the [`TriggerType::LastPrice`] and [`TriggerType::BidAsk`].
1703    LastOrBidAsk = 8,
1704    /// Based on the mid-point of the [`TriggerType::BidAsk`].
1705    MidPoint = 9,
1706}
1707
1708enum_strum_serde!(AccountType);
1709enum_strum_serde!(AggregationSource);
1710enum_strum_serde!(AggressorSide);
1711enum_strum_serde!(AssetClass);
1712enum_strum_serde!(BarAggregation);
1713enum_strum_serde!(BarIntervalType);
1714enum_strum_serde!(BookAction);
1715enum_strum_serde!(BookType);
1716enum_strum_serde!(ContingencyType);
1717enum_strum_serde!(CurrencyType);
1718enum_strum_serde!(InstrumentClass);
1719enum_strum_serde!(InstrumentCloseType);
1720enum_strum_serde!(LiquiditySide);
1721enum_strum_serde!(MarketStatus);
1722enum_strum_serde!(MarketStatusAction);
1723enum_strum_serde!(OmsType);
1724enum_strum_serde!(OptionKind);
1725enum_strum_serde!(OrderSide);
1726enum_strum_serde!(OrderSideSpecified);
1727enum_strum_serde!(OrderStatus);
1728enum_strum_serde!(OrderType);
1729enum_strum_serde!(PositionAdjustmentType);
1730enum_strum_serde!(PositionSide);
1731enum_strum_serde!(PositionSideSpecified);
1732enum_strum_serde!(PriceType);
1733enum_strum_serde!(RecordFlag);
1734enum_strum_serde!(TimeInForce);
1735enum_strum_serde!(TradingState);
1736enum_strum_serde!(TrailingOffsetType);
1737enum_strum_serde!(TriggerType);