Skip to main content

nautilus_model/python/
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;
19
20use nautilus_core::python::to_pyvalue_err;
21use pyo3::{PyTypeInfo, prelude::*, types::PyType};
22
23use crate::{
24    enums::{
25        AccountType, AggregationSource, AggressorSide, AssetClass, AvgPxReconciliation,
26        BarAggregation, BarIntervalType, BetSide, BookAction, BookType, ContingencyType,
27        ContinuousFutureAdjustmentType, CurrencyType, GreeksConvention, InstrumentClass,
28        InstrumentCloseType, LiquiditySide, MarketStatus, MarketStatusAction, OmsType, OptionKind,
29        OptionSideFilter, OrderSide, OrderStatus, OrderType, OtoTriggerMode,
30        PositionAdjustmentType, PositionSide, PriceType, RecordFlag, TimeInForce, TradingState,
31        TrailingOffsetType, TriggerType,
32    },
33    python::common::EnumIterator,
34};
35
36#[pymethods]
37#[pyo3_stub_gen::derive::gen_stub_pymethods]
38impl AccountType {
39    /// An account type provided by a trading venue or broker.
40    #[new]
41    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
42        let t = Self::type_object(py);
43        Self::py_from_str(&t, value)
44    }
45
46    const fn __hash__(&self) -> isize {
47        *self as isize
48    }
49
50    fn __str__(&self) -> String {
51        self.to_string()
52    }
53
54    #[getter]
55    #[must_use]
56    pub fn name(&self) -> String {
57        self.to_string()
58    }
59
60    #[getter]
61    #[must_use]
62    pub fn value(&self) -> u8 {
63        *self as u8
64    }
65
66    #[classmethod]
67    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
68        EnumIterator::new::<Self>(py)
69    }
70
71    #[classmethod]
72    #[pyo3(name = "from_str")]
73    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
74        let data_str: &str = data.extract()?;
75        let tokenized = data_str.to_uppercase();
76        Self::from_str(&tokenized).map_err(to_pyvalue_err)
77    }
78}
79
80#[pymethods]
81#[pyo3_stub_gen::derive::gen_stub_pymethods]
82impl PositionAdjustmentType {
83    /// The type of position adjustment.
84    #[new]
85    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
86        let t = Self::type_object(py);
87        Self::py_from_str(&t, value)
88    }
89
90    const fn __hash__(&self) -> isize {
91        *self as isize
92    }
93
94    fn __str__(&self) -> String {
95        self.to_string()
96    }
97
98    #[getter]
99    #[must_use]
100    pub fn name(&self) -> String {
101        self.to_string()
102    }
103
104    #[getter]
105    #[must_use]
106    pub fn value(&self) -> u8 {
107        *self as u8
108    }
109
110    #[classmethod]
111    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
112        EnumIterator::new::<Self>(py)
113    }
114
115    #[classmethod]
116    #[pyo3(name = "from_str")]
117    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
118        let data_str: &str = data.extract()?;
119        let tokenized = data_str.to_uppercase();
120        Self::from_str(&tokenized).map_err(to_pyvalue_err)
121    }
122}
123
124#[pymethods]
125#[pyo3_stub_gen::derive::gen_stub_pymethods]
126impl AggregationSource {
127    /// An aggregation source for derived data.
128    #[new]
129    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
130        let t = Self::type_object(py);
131        Self::py_from_str(&t, value)
132    }
133
134    const fn __hash__(&self) -> isize {
135        *self as isize
136    }
137
138    fn __str__(&self) -> String {
139        self.to_string()
140    }
141
142    #[getter]
143    #[must_use]
144    pub fn name(&self) -> String {
145        self.to_string()
146    }
147
148    #[getter]
149    #[must_use]
150    pub fn value(&self) -> u8 {
151        *self as u8
152    }
153
154    #[classmethod]
155    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
156        EnumIterator::new::<Self>(py)
157    }
158
159    #[classmethod]
160    #[pyo3(name = "from_str")]
161    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
162        let data_str: &str = data.extract()?;
163        let tokenized = data_str.to_uppercase();
164        Self::from_str(&tokenized).map_err(to_pyvalue_err)
165    }
166}
167
168#[pymethods]
169#[pyo3_stub_gen::derive::gen_stub_pymethods]
170impl AggressorSide {
171    /// The side for the aggressing order of a trade in a market.
172    #[new]
173    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
174        let t = Self::type_object(py);
175        Self::py_from_str(&t, value)
176    }
177
178    const fn __hash__(&self) -> isize {
179        *self as isize
180    }
181
182    fn __str__(&self) -> String {
183        self.to_string()
184    }
185
186    #[getter]
187    #[must_use]
188    pub fn name(&self) -> String {
189        self.to_string()
190    }
191
192    #[getter]
193    #[must_use]
194    pub fn value(&self) -> u8 {
195        *self as u8
196    }
197
198    #[classmethod]
199    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
200        EnumIterator::new::<Self>(py)
201    }
202
203    #[classmethod]
204    #[pyo3(name = "from_str")]
205    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
206        let data_str: &str = data.extract()?;
207        let tokenized = data_str.to_uppercase();
208        Self::from_str(&tokenized).map_err(to_pyvalue_err)
209    }
210}
211
212#[pymethods]
213#[pyo3_stub_gen::derive::gen_stub_pymethods]
214impl AssetClass {
215    /// A broad financial market asset class.
216    #[new]
217    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
218        let t = Self::type_object(py);
219        Self::py_from_str(&t, value)
220    }
221
222    const fn __hash__(&self) -> isize {
223        *self as isize
224    }
225
226    fn __str__(&self) -> String {
227        self.to_string()
228    }
229
230    #[getter]
231    #[must_use]
232    pub fn name(&self) -> String {
233        self.to_string()
234    }
235
236    #[getter]
237    #[must_use]
238    pub fn value(&self) -> u8 {
239        *self as u8
240    }
241
242    #[classmethod]
243    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
244        EnumIterator::new::<Self>(py)
245    }
246
247    #[classmethod]
248    #[pyo3(name = "from_str")]
249    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
250        let data_str: &str = data.extract()?;
251        let tokenized = data_str.to_uppercase();
252        Self::from_str(&tokenized).map_err(to_pyvalue_err)
253    }
254}
255
256#[pymethods]
257#[pyo3_stub_gen::derive::gen_stub_pymethods]
258impl AvgPxReconciliation {
259    /// How position reconciliation may use a venue-reported average entry price.
260    #[new]
261    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
262        let t = Self::type_object(py);
263        Self::py_from_str(&t, value)
264    }
265
266    const fn __hash__(&self) -> isize {
267        *self as isize
268    }
269
270    fn __str__(&self) -> String {
271        self.to_string()
272    }
273
274    #[getter]
275    #[must_use]
276    pub fn name(&self) -> String {
277        self.to_string()
278    }
279
280    #[getter]
281    #[must_use]
282    pub fn value(&self) -> u8 {
283        *self as u8
284    }
285
286    #[classmethod]
287    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
288        EnumIterator::new::<Self>(py)
289    }
290
291    #[classmethod]
292    #[pyo3(name = "from_str")]
293    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
294        let data_str: &str = data.extract()?;
295        let tokenized = data_str.to_uppercase();
296        Self::from_str(&tokenized).map_err(to_pyvalue_err)
297    }
298}
299
300#[pymethods]
301#[pyo3_stub_gen::derive::gen_stub_pymethods]
302impl InstrumentClass {
303    /// The instrument class.
304    #[new]
305    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
306        let t = Self::type_object(py);
307        Self::py_from_str(&t, value)
308    }
309
310    const fn __hash__(&self) -> isize {
311        *self as isize
312    }
313
314    fn __str__(&self) -> String {
315        self.to_string()
316    }
317
318    #[getter]
319    #[must_use]
320    pub fn name(&self) -> String {
321        self.to_string()
322    }
323
324    #[getter]
325    #[must_use]
326    pub fn value(&self) -> u8 {
327        *self as u8
328    }
329
330    #[classmethod]
331    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
332        EnumIterator::new::<Self>(py)
333    }
334
335    #[classmethod]
336    #[pyo3(name = "from_str")]
337    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
338        let data_str: &str = data.extract()?;
339        let tokenized = data_str.to_uppercase();
340        Self::from_str(&tokenized).map_err(to_pyvalue_err)
341    }
342
343    /// Returns whether this instrument class has an expiration.
344    #[pyo3(name = "has_expiration")]
345    #[must_use]
346    pub const fn py_has_expiration(&self) -> bool {
347        self.has_expiration()
348    }
349
350    /// Returns whether this instrument class allows negative prices.
351    ///
352    /// Futures allow negative prices, which occur as real settlement prices (e.g. WTI crude
353    /// oil in April 2020) and in back-adjusted continuous price series. Inverse instruments
354    /// whose notional divides by price still require a positive price.
355    #[pyo3(name = "allows_negative_price")]
356    #[must_use]
357    pub const fn py_allows_negative_price(&self) -> bool {
358        self.allows_negative_price()
359    }
360
361    /// Returns the canonical parent-symbol suffix for this class, if one exists.
362    ///
363    /// Always emits the short form (`FUT`, `OPT`) so that adapters constructing
364    /// parent ids produce a single canonical string per class.
365    #[pyo3(name = "parent_suffix")]
366    #[must_use]
367    pub const fn py_parent_suffix(&self) -> Option<&'static str> {
368        self.parent_suffix()
369    }
370
371    /// Returns the `InstrumentClass` for the parent-symbol suffix, if recognized.
372    ///
373    /// Matches strict uppercase forms only. Both Databento-style abbreviations
374    /// (`FUT`, `OPT`) and long forms (`FUTURE`, `OPTION`) are accepted.
375    #[classmethod]
376    #[pyo3(name = "try_from_parent_suffix")]
377    #[must_use]
378    pub fn py_try_from_parent_suffix(_: &Bound<'_, PyType>, suffix: &str) -> Option<Self> {
379        Self::try_from_parent_suffix(suffix)
380    }
381}
382
383#[pymethods]
384#[pyo3_stub_gen::derive::gen_stub_pymethods]
385impl BarAggregation {
386    /// The aggregation method through which a bar is generated and closed.
387    #[new]
388    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
389        let t = Self::type_object(py);
390        Self::py_from_str(&t, value)
391    }
392
393    const fn __hash__(&self) -> isize {
394        *self as isize
395    }
396
397    fn __str__(&self) -> String {
398        self.to_string()
399    }
400
401    #[getter]
402    #[must_use]
403    pub fn name(&self) -> String {
404        self.to_string()
405    }
406
407    #[getter]
408    #[must_use]
409    pub fn value(&self) -> u8 {
410        *self as u8
411    }
412
413    #[classmethod]
414    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
415        EnumIterator::new::<Self>(py)
416    }
417
418    #[classmethod]
419    #[pyo3(name = "from_str")]
420    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
421        let data_str: &str = data.extract()?;
422        let tokenized = data_str.to_uppercase();
423        Self::from_str(&tokenized).map_err(to_pyvalue_err)
424    }
425}
426
427#[pymethods]
428#[pyo3_stub_gen::derive::gen_stub_pymethods]
429impl BarIntervalType {
430    /// The interval type for bar aggregation.
431    #[new]
432    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
433        let t = Self::type_object(py);
434        Self::py_from_str(&t, value)
435    }
436
437    const fn __hash__(&self) -> isize {
438        *self as isize
439    }
440
441    fn __str__(&self) -> String {
442        self.to_string()
443    }
444
445    #[getter]
446    #[must_use]
447    pub fn name(&self) -> String {
448        self.to_string()
449    }
450
451    #[getter]
452    #[must_use]
453    pub fn value(&self) -> u8 {
454        *self as u8
455    }
456
457    #[classmethod]
458    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
459        EnumIterator::new::<Self>(py)
460    }
461
462    #[classmethod]
463    #[pyo3(name = "from_str")]
464    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
465        let data_str: &str = data.extract()?;
466        let tokenized = data_str.to_uppercase();
467        Self::from_str(&tokenized).map_err(to_pyvalue_err)
468    }
469}
470
471#[pymethods]
472#[pyo3_stub_gen::derive::gen_stub_pymethods]
473impl BetSide {
474    /// Represents the side of a bet in a betting market.
475    #[new]
476    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
477        let t = Self::type_object(py);
478        Self::py_from_str(&t, value)
479    }
480
481    const fn __hash__(&self) -> isize {
482        *self as isize
483    }
484
485    fn __str__(&self) -> String {
486        self.to_string()
487    }
488
489    #[getter]
490    #[must_use]
491    pub fn name(&self) -> String {
492        self.to_string()
493    }
494
495    #[getter]
496    #[must_use]
497    pub fn value(&self) -> u8 {
498        *self as u8
499    }
500
501    #[classmethod]
502    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
503        EnumIterator::new::<Self>(py)
504    }
505
506    #[classmethod]
507    #[pyo3(name = "from_str")]
508    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
509        let data_str: &str = data.extract()?;
510        let tokenized = data_str.to_uppercase();
511        Self::from_str(&tokenized).map_err(to_pyvalue_err)
512    }
513
514    #[classmethod]
515    #[pyo3(name = "from_order_side")]
516    fn py_from_order_side(_: &Bound<'_, PyType>, order_side: OrderSide) -> Self {
517        order_side.into()
518    }
519
520    /// Returns the opposite betting side.
521    #[pyo3(name = "opposite")]
522    fn py_opposite(&self) -> Self {
523        self.opposite()
524    }
525}
526
527#[pymethods]
528#[pyo3_stub_gen::derive::gen_stub_pymethods]
529impl BookAction {
530    /// The type of order book action for an order book event.
531    #[new]
532    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
533        let t = Self::type_object(py);
534        Self::py_from_str(&t, value)
535    }
536
537    const fn __hash__(&self) -> isize {
538        *self as isize
539    }
540
541    fn __str__(&self) -> String {
542        self.to_string()
543    }
544
545    #[getter]
546    #[must_use]
547    pub fn name(&self) -> String {
548        self.to_string()
549    }
550
551    #[getter]
552    #[must_use]
553    pub fn value(&self) -> u8 {
554        *self as u8
555    }
556
557    #[classmethod]
558    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
559        EnumIterator::new::<Self>(py)
560    }
561
562    #[classmethod]
563    #[pyo3(name = "from_str")]
564    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
565        let data_str: &str = data.extract()?;
566        let tokenized = data_str.to_uppercase();
567        Self::from_str(&tokenized).map_err(to_pyvalue_err)
568    }
569}
570
571// The stub macro must run first so it records the compatibility class attribute
572#[pyo3_stub_gen::derive::gen_stub_pymethods]
573#[pymethods]
574impl ContingencyType {
575    /// The order contingency type which specifies the behavior of linked orders.
576    ///
577    /// [FIX 5.0 SP2 : ContingencyType <1385> field](https://www.onixs.biz/fix-dictionary/5.0.sp2/tagnum_1385.html).
578    ///
579    /// Python retains `NO_CONTINGENCY` as a compatibility alias for `None`. The alias is not an enum
580    /// variant and may be removed in a future version.
581    #[new]
582    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
583        let t = Self::type_object(py);
584        Self::py_from_str(&t, value)
585    }
586
587    /// Compatibility alias for the removed `NO_CONTINGENCY` variant.
588    ///
589    /// This alias returns `None` and may be removed in a future version.
590    #[classattr]
591    #[pyo3(name = "NO_CONTINGENCY")]
592    #[allow(clippy::use_self)]
593    const fn py_no_contingency() -> Option<ContingencyType> {
594        None
595    }
596
597    const fn __hash__(&self) -> isize {
598        *self as isize
599    }
600
601    fn __str__(&self) -> String {
602        self.to_string()
603    }
604
605    #[getter]
606    #[must_use]
607    pub fn name(&self) -> String {
608        self.to_string()
609    }
610
611    #[getter]
612    #[must_use]
613    pub fn value(&self) -> u8 {
614        *self as u8
615    }
616
617    #[classmethod]
618    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
619        EnumIterator::new::<Self>(py)
620    }
621
622    #[classmethod]
623    #[pyo3(name = "from_str")]
624    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
625        let data_str: &str = data.extract()?;
626        let tokenized = data_str.to_uppercase();
627        if tokenized == "NO_CONTINGENCY" {
628            Ok(None)
629        } else {
630            Self::from_str(&tokenized).map(Some).map_err(to_pyvalue_err)
631        }
632    }
633}
634
635#[pymethods]
636#[pyo3_stub_gen::derive::gen_stub_pymethods]
637impl ContinuousFutureAdjustmentType {
638    /// The price-adjustment scheme applied when stitching segment contracts into a
639    /// continuous future series.
640    ///
641    /// The direction (backward vs. forward) selects the anchor contract:
642    /// - Backward modes anchor on the most recent contract; prices in older
643    ///   segments are shifted into the latest contract's frame.
644    /// - Forward modes anchor on the first contract; prices in later segments
645    ///   are shifted into the first contract's frame.
646    ///
647    /// The kind (spread vs. ratio) selects how each transition's offset is combined:
648    /// - Spread modes accumulate additive offsets (`post_price - pre_price`).
649    /// - Ratio modes accumulate multiplicative factors (`post_price / pre_price`)
650    ///   and require strictly positive prices.
651    #[new]
652    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
653        let t = Self::type_object(py);
654        Self::py_from_str(&t, value)
655    }
656
657    const fn __hash__(&self) -> isize {
658        *self as isize
659    }
660
661    fn __str__(&self) -> String {
662        self.to_string()
663    }
664
665    #[getter]
666    #[must_use]
667    pub fn name(&self) -> String {
668        self.to_string()
669    }
670
671    #[getter]
672    #[must_use]
673    pub fn value(&self) -> u8 {
674        *self as u8
675    }
676
677    /// Returns whether this mode accumulates multiplicative factors.
678    #[getter(is_ratio)]
679    #[must_use]
680    pub const fn py_is_ratio(&self) -> bool {
681        self.is_ratio()
682    }
683
684    /// Returns whether this mode anchors on the most recent contract.
685    #[getter(is_backward)]
686    #[must_use]
687    pub const fn py_is_backward(&self) -> bool {
688        self.is_backward()
689    }
690
691    #[classmethod]
692    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
693        EnumIterator::new::<Self>(py)
694    }
695
696    #[classmethod]
697    #[pyo3(name = "from_str")]
698    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
699        let data_str: &str = data.extract()?;
700        let tokenized = data_str.to_uppercase();
701        Self::from_str(&tokenized).map_err(to_pyvalue_err)
702    }
703}
704
705#[pymethods]
706#[pyo3_stub_gen::derive::gen_stub_pymethods]
707impl CurrencyType {
708    /// The broad currency type.
709    #[new]
710    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
711        let t = Self::type_object(py);
712        Self::py_from_str(&t, value)
713    }
714
715    const fn __hash__(&self) -> isize {
716        *self as isize
717    }
718
719    fn __str__(&self) -> String {
720        self.to_string()
721    }
722
723    #[getter]
724    #[must_use]
725    pub fn name(&self) -> String {
726        self.to_string()
727    }
728
729    #[getter]
730    #[must_use]
731    pub fn value(&self) -> u8 {
732        *self as u8
733    }
734
735    #[classmethod]
736    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
737        EnumIterator::new::<Self>(py)
738    }
739
740    #[classmethod]
741    #[pyo3(name = "from_str")]
742    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
743        let data_str: &str = data.extract()?;
744        let tokenized = data_str.to_uppercase();
745        Self::from_str(&tokenized).map_err(to_pyvalue_err)
746    }
747}
748
749#[pymethods]
750#[pyo3_stub_gen::derive::gen_stub_pymethods]
751impl InstrumentCloseType {
752    /// The type of event for an instrument close.
753    #[new]
754    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
755        let t = Self::type_object(py);
756        Self::py_from_str(&t, value)
757    }
758
759    const fn __hash__(&self) -> isize {
760        *self as isize
761    }
762
763    fn __str__(&self) -> String {
764        self.to_string()
765    }
766
767    #[getter]
768    #[must_use]
769    pub fn name(&self) -> String {
770        self.to_string()
771    }
772
773    #[getter]
774    #[must_use]
775    pub fn value(&self) -> u8 {
776        *self as u8
777    }
778
779    #[classmethod]
780    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
781        EnumIterator::new::<Self>(py)
782    }
783
784    #[classmethod]
785    #[pyo3(name = "from_str")]
786    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
787        let data_str: &str = data.extract()?;
788        let tokenized = data_str.to_uppercase();
789        Self::from_str(&tokenized).map_err(to_pyvalue_err)
790    }
791}
792
793#[pymethods]
794#[pyo3_stub_gen::derive::gen_stub_pymethods]
795impl LiquiditySide {
796    /// The liquidity side for a trade.
797    #[new]
798    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
799        let t = Self::type_object(py);
800        Self::py_from_str(&t, value)
801    }
802
803    const fn __hash__(&self) -> isize {
804        *self as isize
805    }
806
807    fn __str__(&self) -> String {
808        self.to_string()
809    }
810
811    #[getter]
812    #[must_use]
813    pub fn name(&self) -> String {
814        self.to_string()
815    }
816
817    #[getter]
818    #[must_use]
819    pub fn value(&self) -> u8 {
820        *self as u8
821    }
822
823    #[classmethod]
824    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
825        EnumIterator::new::<Self>(py)
826    }
827
828    #[classmethod]
829    #[pyo3(name = "from_str")]
830    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
831        let data_str: &str = data.extract()?;
832        let tokenized = data_str.to_uppercase();
833        Self::from_str(&tokenized).map_err(to_pyvalue_err)
834    }
835}
836
837#[pymethods]
838#[pyo3_stub_gen::derive::gen_stub_pymethods]
839impl MarketStatus {
840    /// The status of an individual market on a trading venue.
841    #[new]
842    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
843        let t = Self::type_object(py);
844        Self::py_from_str(&t, value)
845    }
846
847    const fn __hash__(&self) -> isize {
848        *self as isize
849    }
850
851    fn __str__(&self) -> String {
852        self.to_string()
853    }
854
855    #[getter]
856    #[must_use]
857    pub fn name(&self) -> String {
858        self.to_string()
859    }
860
861    #[getter]
862    #[must_use]
863    pub fn value(&self) -> u8 {
864        *self as u8
865    }
866
867    #[classmethod]
868    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
869        EnumIterator::new::<Self>(py)
870    }
871
872    #[classmethod]
873    #[pyo3(name = "from_str")]
874    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
875        let data_str: &str = data.extract()?;
876        let tokenized = data_str.to_uppercase();
877        Self::from_str(&tokenized).map_err(to_pyvalue_err)
878    }
879}
880
881#[pymethods]
882#[pyo3_stub_gen::derive::gen_stub_pymethods]
883impl MarketStatusAction {
884    /// An action affecting the status of an individual market on a trading venue.
885    #[new]
886    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
887        let t = Self::type_object(py);
888        Self::py_from_str(&t, value)
889    }
890
891    const fn __hash__(&self) -> isize {
892        *self as isize
893    }
894
895    fn __str__(&self) -> String {
896        self.to_string()
897    }
898
899    #[getter]
900    #[must_use]
901    pub fn name(&self) -> String {
902        self.to_string()
903    }
904
905    #[getter]
906    #[must_use]
907    pub fn value(&self) -> u8 {
908        *self as u8
909    }
910
911    #[classmethod]
912    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
913        EnumIterator::new::<Self>(py)
914    }
915
916    #[classmethod]
917    #[pyo3(name = "from_str")]
918    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
919        let data_str: &str = data.extract()?;
920        let tokenized = data_str.to_uppercase();
921        Self::from_str(&tokenized).map_err(to_pyvalue_err)
922    }
923}
924
925#[pymethods]
926#[pyo3_stub_gen::derive::gen_stub_pymethods]
927impl OmsType {
928    /// The order management system (OMS) type for a trading venue or trading strategy.
929    #[new]
930    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
931        let t = Self::type_object(py);
932        Self::py_from_str(&t, value)
933    }
934
935    const fn __hash__(&self) -> isize {
936        *self as isize
937    }
938
939    fn __str__(&self) -> String {
940        self.to_string()
941    }
942
943    #[getter]
944    #[must_use]
945    pub fn name(&self) -> String {
946        self.to_string()
947    }
948
949    #[getter]
950    #[must_use]
951    pub fn value(&self) -> u8 {
952        *self as u8
953    }
954
955    #[classmethod]
956    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
957        EnumIterator::new::<Self>(py)
958    }
959
960    #[classmethod]
961    #[pyo3(name = "from_str")]
962    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
963        let data_str: &str = data.extract()?;
964        let tokenized = data_str.to_uppercase();
965        Self::from_str(&tokenized).map_err(to_pyvalue_err)
966    }
967}
968
969#[pymethods]
970#[pyo3_stub_gen::derive::gen_stub_pymethods]
971impl OptionKind {
972    /// The kind of option contract.
973    #[new]
974    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
975        let t = Self::type_object(py);
976        Self::py_from_str(&t, value)
977    }
978
979    const fn __hash__(&self) -> isize {
980        *self as isize
981    }
982
983    fn __str__(&self) -> String {
984        self.to_string()
985    }
986
987    #[getter]
988    #[must_use]
989    pub fn name(&self) -> String {
990        self.to_string()
991    }
992
993    #[getter]
994    #[must_use]
995    pub fn value(&self) -> u8 {
996        *self as u8
997    }
998
999    #[classmethod]
1000    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1001        EnumIterator::new::<Self>(py)
1002    }
1003
1004    #[classmethod]
1005    #[pyo3(name = "from_str")]
1006    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1007        let data_str: &str = data.extract()?;
1008        let tokenized = data_str.to_uppercase();
1009        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1010    }
1011}
1012
1013#[pymethods]
1014#[pyo3_stub_gen::derive::gen_stub_pymethods]
1015impl OptionSideFilter {
1016    /// Selects which option kinds an option chain carries at each strike position.
1017    #[new]
1018    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1019        let t = Self::type_object(py);
1020        Self::py_from_str(&t, value)
1021    }
1022
1023    const fn __hash__(&self) -> isize {
1024        *self as isize
1025    }
1026
1027    fn __str__(&self) -> String {
1028        self.to_string()
1029    }
1030
1031    #[getter]
1032    #[must_use]
1033    pub fn name(&self) -> String {
1034        self.to_string()
1035    }
1036
1037    #[getter]
1038    #[must_use]
1039    pub fn value(&self) -> u8 {
1040        *self as u8
1041    }
1042
1043    #[classmethod]
1044    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1045        EnumIterator::new::<Self>(py)
1046    }
1047
1048    #[classmethod]
1049    #[pyo3(name = "from_str")]
1050    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1051        let data_str: &str = data.extract()?;
1052        let tokenized = data_str.to_uppercase();
1053        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1054    }
1055}
1056
1057#[pymethods]
1058#[pyo3_stub_gen::derive::gen_stub_pymethods]
1059impl GreeksConvention {
1060    /// The numeraire convention for option greeks published by a venue.
1061    ///
1062    /// Crypto option venues commonly publish two parallel greek sets for the same
1063    /// instrument: Black-Scholes greeks in USD, and price-adjusted greeks denominated
1064    /// in the underlying/coin units. Deribit and OKX both expose the distinction;
1065    /// see the OKX reference for the canonical definition:
1066    /// <https://www.okx.com/docs-v5/en/#public-data-websocket-option-market-data>.
1067    ///
1068    /// This is orthogonal to the percent-greeks transformation in the internal
1069    /// `GreeksCalculator`,
1070    /// which rescales the delta/gamma input step rather than the numeraire.
1071    #[new]
1072    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1073        let t = Self::type_object(py);
1074        Self::py_from_str(&t, value)
1075    }
1076
1077    const fn __hash__(&self) -> isize {
1078        *self as isize
1079    }
1080
1081    fn __str__(&self) -> String {
1082        self.to_string()
1083    }
1084
1085    #[getter]
1086    #[must_use]
1087    pub fn name(&self) -> String {
1088        self.to_string()
1089    }
1090
1091    #[getter]
1092    #[must_use]
1093    pub fn value(&self) -> u8 {
1094        *self as u8
1095    }
1096
1097    #[classmethod]
1098    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1099        EnumIterator::new::<Self>(py)
1100    }
1101
1102    #[classmethod]
1103    #[pyo3(name = "from_str")]
1104    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1105        let data_str: &str = data.extract()?;
1106        let tokenized = data_str.to_uppercase();
1107        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1108    }
1109}
1110
1111#[pymethods]
1112#[pyo3_stub_gen::derive::gen_stub_pymethods]
1113impl OtoTriggerMode {
1114    /// Defines when OTO (One-Triggers-Other) child orders are released.
1115    #[new]
1116    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1117        let t = Self::type_object(py);
1118        Self::py_from_str(&t, value)
1119    }
1120
1121    const fn __hash__(&self) -> isize {
1122        *self as isize
1123    }
1124
1125    fn __str__(&self) -> String {
1126        self.to_string()
1127    }
1128
1129    #[getter]
1130    #[must_use]
1131    pub fn name(&self) -> String {
1132        self.to_string()
1133    }
1134
1135    #[getter]
1136    #[must_use]
1137    pub fn value(&self) -> u8 {
1138        *self as u8
1139    }
1140
1141    #[classmethod]
1142    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1143        EnumIterator::new::<Self>(py)
1144    }
1145
1146    #[classmethod]
1147    #[pyo3(name = "from_str")]
1148    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1149        let data_str: &str = data.extract()?;
1150        let tokenized = data_str.to_uppercase();
1151        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1152    }
1153}
1154
1155// The stub macro must run first so it records the compatibility class attribute
1156#[pyo3_stub_gen::derive::gen_stub_pymethods]
1157#[pymethods]
1158impl OrderSide {
1159    /// The order side (BUY or SELL).
1160    ///
1161    /// Python retains `NO_ORDER_SIDE` as a compatibility alias for `None`. The alias is not an enum
1162    /// variant and may be removed in a future version.
1163    #[new]
1164    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1165        let t = Self::type_object(py);
1166        Self::py_from_str(&t, value)
1167    }
1168
1169    /// Compatibility alias for the removed `NO_ORDER_SIDE` variant.
1170    ///
1171    /// This alias returns `None` and may be removed in a future version.
1172    #[classattr]
1173    #[pyo3(name = "NO_ORDER_SIDE")]
1174    #[allow(clippy::use_self)]
1175    const fn py_no_order_side() -> Option<OrderSide> {
1176        None
1177    }
1178
1179    const fn __hash__(&self) -> isize {
1180        *self as isize
1181    }
1182
1183    fn __str__(&self) -> String {
1184        self.to_string()
1185    }
1186
1187    #[getter]
1188    #[must_use]
1189    pub fn name(&self) -> String {
1190        self.to_string()
1191    }
1192
1193    #[getter]
1194    #[must_use]
1195    pub fn value(&self) -> u8 {
1196        *self as u8
1197    }
1198
1199    #[classmethod]
1200    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1201        EnumIterator::new::<Self>(py)
1202    }
1203
1204    #[classmethod]
1205    #[pyo3(name = "from_str")]
1206    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1207        let data_str: &str = data.extract()?;
1208        let tokenized = data_str.to_uppercase();
1209        if tokenized == "NO_ORDER_SIDE" {
1210            Ok(None)
1211        } else {
1212            Self::from_str(&tokenized).map(Some).map_err(to_pyvalue_err)
1213        }
1214    }
1215}
1216
1217#[pymethods]
1218#[pyo3_stub_gen::derive::gen_stub_pymethods]
1219impl OrderStatus {
1220    /// The status for a specific order.
1221    ///
1222    /// An order is considered _open_ for the following status:
1223    ///  - `ACCEPTED`
1224    ///  - `TRIGGERED`
1225    ///  - `PENDING_UPDATE`
1226    ///  - `PENDING_CANCEL`
1227    ///  - `PARTIALLY_FILLED`
1228    ///
1229    /// An order is considered _in-flight_ for the following status:
1230    ///  - `SUBMITTED`
1231    ///  - `PENDING_UPDATE`
1232    ///  - `PENDING_CANCEL`
1233    ///
1234    /// An order is considered _closed_ for the following status:
1235    ///  - `DENIED`
1236    ///  - `REJECTED`
1237    ///  - `CANCELED`
1238    ///  - `EXPIRED`
1239    ///  - `FILLED`
1240    ///  - `VOIDED`
1241    #[new]
1242    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1243        let t = Self::type_object(py);
1244        Self::py_from_str(&t, value)
1245    }
1246
1247    const fn __hash__(&self) -> isize {
1248        *self as isize
1249    }
1250
1251    fn __str__(&self) -> String {
1252        self.to_string()
1253    }
1254
1255    #[getter]
1256    #[must_use]
1257    pub fn name(&self) -> String {
1258        self.to_string()
1259    }
1260
1261    #[getter]
1262    #[must_use]
1263    pub fn value(&self) -> u8 {
1264        *self as u8
1265    }
1266
1267    #[classmethod]
1268    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1269        EnumIterator::new::<Self>(py)
1270    }
1271
1272    #[classmethod]
1273    #[pyo3(name = "from_str")]
1274    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1275        let data_str: &str = data.extract()?;
1276        let tokenized = data_str.to_uppercase();
1277        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1278    }
1279}
1280
1281#[pymethods]
1282#[pyo3_stub_gen::derive::gen_stub_pymethods]
1283impl OrderType {
1284    /// The type of order.
1285    #[new]
1286    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1287        let t = Self::type_object(py);
1288        Self::py_from_str(&t, value)
1289    }
1290
1291    const fn __hash__(&self) -> isize {
1292        *self as isize
1293    }
1294
1295    fn __str__(&self) -> String {
1296        self.to_string()
1297    }
1298
1299    #[getter]
1300    #[must_use]
1301    pub fn name(&self) -> String {
1302        self.to_string()
1303    }
1304
1305    #[getter]
1306    #[must_use]
1307    pub fn value(&self) -> u8 {
1308        *self as u8
1309    }
1310
1311    #[classmethod]
1312    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1313        EnumIterator::new::<Self>(py)
1314    }
1315
1316    #[classmethod]
1317    #[pyo3(name = "from_str")]
1318    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1319        let data_str: &str = data.extract()?;
1320        let tokenized = data_str.to_uppercase();
1321        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1322    }
1323}
1324
1325// The stub macro must run first so it records the compatibility class attribute
1326#[pyo3_stub_gen::derive::gen_stub_pymethods]
1327#[pymethods]
1328impl PositionSide {
1329    /// The position side (FLAT, LONG, or SHORT).
1330    ///
1331    /// Python retains `NO_POSITION_SIDE` as a compatibility alias for `None`. The alias is not an enum
1332    /// variant and may be removed in a future version.
1333    #[new]
1334    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1335        let t = Self::type_object(py);
1336        Self::py_from_str(&t, value)
1337    }
1338
1339    /// Compatibility alias for the removed `NO_POSITION_SIDE` variant.
1340    ///
1341    /// This alias returns `None` and may be removed in a future version.
1342    #[classattr]
1343    #[pyo3(name = "NO_POSITION_SIDE")]
1344    #[allow(clippy::use_self)]
1345    const fn py_no_position_side() -> Option<PositionSide> {
1346        None
1347    }
1348
1349    const fn __hash__(&self) -> isize {
1350        *self as isize
1351    }
1352
1353    fn __str__(&self) -> String {
1354        self.to_string()
1355    }
1356
1357    #[getter]
1358    #[must_use]
1359    pub fn name(&self) -> String {
1360        self.to_string()
1361    }
1362
1363    #[getter]
1364    #[must_use]
1365    pub fn value(&self) -> u8 {
1366        *self as u8
1367    }
1368
1369    #[classmethod]
1370    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1371        EnumIterator::new::<Self>(py)
1372    }
1373
1374    #[classmethod]
1375    #[pyo3(name = "from_str")]
1376    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1377        let data_str: &str = data.extract()?;
1378        let tokenized = data_str.to_uppercase();
1379        if tokenized == "NO_POSITION_SIDE" {
1380            Ok(None)
1381        } else {
1382            Self::from_str(&tokenized).map(Some).map_err(to_pyvalue_err)
1383        }
1384    }
1385}
1386
1387#[pymethods]
1388#[pyo3_stub_gen::derive::gen_stub_pymethods]
1389impl PriceType {
1390    /// The type of price for an instrument in a market.
1391    #[new]
1392    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1393        let t = Self::type_object(py);
1394        Self::py_from_str(&t, value)
1395    }
1396
1397    const fn __hash__(&self) -> isize {
1398        *self as isize
1399    }
1400
1401    fn __str__(&self) -> String {
1402        self.to_string()
1403    }
1404
1405    #[getter]
1406    #[must_use]
1407    pub fn name(&self) -> String {
1408        self.to_string()
1409    }
1410
1411    #[getter]
1412    #[must_use]
1413    pub fn value(&self) -> u8 {
1414        *self as u8
1415    }
1416
1417    #[classmethod]
1418    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1419        EnumIterator::new::<Self>(py)
1420    }
1421
1422    #[classmethod]
1423    #[pyo3(name = "from_str")]
1424    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1425        let data_str: &str = data.extract()?;
1426        let tokenized = data_str.to_uppercase();
1427        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1428    }
1429
1430    #[classmethod]
1431    #[pyo3(name = "from_int")]
1432    fn py_from_int(_: &Bound<'_, PyType>, value: i32) -> PyResult<Self> {
1433        Self::from_repr(value as usize)
1434            .ok_or_else(|| to_pyvalue_err(format!("Invalid PriceType value: {value}")))
1435    }
1436}
1437
1438#[pymethods]
1439#[pyo3_stub_gen::derive::gen_stub_pymethods]
1440impl RecordFlag {
1441    /// A record flag bit field, indicating event end and data information.
1442    #[new]
1443    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1444        let t = Self::type_object(py);
1445        Self::py_from_str(&t, value)
1446    }
1447
1448    const fn __hash__(&self) -> isize {
1449        *self as isize
1450    }
1451
1452    fn __str__(&self) -> String {
1453        self.to_string()
1454    }
1455
1456    #[getter]
1457    #[must_use]
1458    pub fn name(&self) -> String {
1459        self.to_string()
1460    }
1461
1462    #[getter]
1463    #[must_use]
1464    pub fn value(&self) -> u8 {
1465        *self as u8
1466    }
1467
1468    #[classmethod]
1469    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1470        EnumIterator::new::<Self>(py)
1471    }
1472
1473    #[classmethod]
1474    #[pyo3(name = "from_str")]
1475    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1476        let data_str: &str = data.extract()?;
1477        let tokenized = data_str.to_uppercase();
1478        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1479    }
1480
1481    /// Checks if the flag matches a given value.
1482    #[pyo3(name = "matches")]
1483    fn py_matches(&self, value: u8) -> bool {
1484        self.matches(value)
1485    }
1486}
1487
1488#[pymethods]
1489#[pyo3_stub_gen::derive::gen_stub_pymethods]
1490impl TimeInForce {
1491    /// The 'Time in Force' instruction for an order.
1492    #[new]
1493    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1494        let t = Self::type_object(py);
1495        Self::py_from_str(&t, value)
1496    }
1497
1498    const fn __hash__(&self) -> isize {
1499        *self as isize
1500    }
1501
1502    fn __str__(&self) -> String {
1503        self.to_string()
1504    }
1505
1506    #[getter]
1507    #[must_use]
1508    pub fn name(&self) -> String {
1509        self.to_string()
1510    }
1511
1512    #[getter]
1513    #[must_use]
1514    pub fn value(&self) -> u8 {
1515        *self as u8
1516    }
1517
1518    #[classmethod]
1519    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1520        EnumIterator::new::<Self>(py)
1521    }
1522
1523    #[classmethod]
1524    #[pyo3(name = "from_str")]
1525    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1526        let data_str: &str = data.extract()?;
1527        let tokenized = data_str.to_uppercase();
1528        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1529    }
1530}
1531
1532// The stub macro must run first so it records the compatibility class attribute
1533#[pyo3_stub_gen::derive::gen_stub_pymethods]
1534#[pymethods]
1535impl TrailingOffsetType {
1536    /// The trailing offset type for an order type which specifies a trailing stop/trigger or limit price.
1537    ///
1538    /// Python retains `NO_TRAILING_OFFSET` as a compatibility alias for `None`. The alias is not an enum
1539    /// variant and may be removed in a future version.
1540    #[new]
1541    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1542        let t = Self::type_object(py);
1543        Self::py_from_str(&t, value)
1544    }
1545
1546    /// Compatibility alias for the removed `NO_TRAILING_OFFSET` variant.
1547    ///
1548    /// This alias returns `None` and may be removed in a future version.
1549    #[classattr]
1550    #[pyo3(name = "NO_TRAILING_OFFSET")]
1551    #[allow(clippy::use_self)]
1552    const fn py_no_trailing_offset() -> Option<TrailingOffsetType> {
1553        None
1554    }
1555
1556    const fn __hash__(&self) -> isize {
1557        *self as isize
1558    }
1559
1560    fn __str__(&self) -> String {
1561        self.to_string()
1562    }
1563
1564    #[getter]
1565    #[must_use]
1566    pub fn name(&self) -> String {
1567        self.to_string()
1568    }
1569
1570    #[getter]
1571    #[must_use]
1572    pub fn value(&self) -> u8 {
1573        *self as u8
1574    }
1575
1576    #[classmethod]
1577    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1578        EnumIterator::new::<Self>(py)
1579    }
1580
1581    #[classmethod]
1582    #[pyo3(name = "from_str")]
1583    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1584        let data_str: &str = data.extract()?;
1585        let tokenized = data_str.to_uppercase();
1586        if tokenized == "NO_TRAILING_OFFSET" {
1587            Ok(None)
1588        } else {
1589            Self::from_str(&tokenized).map(Some).map_err(to_pyvalue_err)
1590        }
1591    }
1592}
1593
1594// The stub macro must run first so it records the compatibility class attribute
1595#[pyo3_stub_gen::derive::gen_stub_pymethods]
1596#[pymethods]
1597impl TriggerType {
1598    /// The trigger type for the stop/trigger price of an order.
1599    ///
1600    /// Python retains `NO_TRIGGER` as a compatibility alias for `None`. The alias is not an enum variant
1601    /// and may be removed in a future version.
1602    #[new]
1603    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1604        let t = Self::type_object(py);
1605        Self::py_from_str(&t, value)
1606    }
1607
1608    /// Compatibility alias for the removed `NO_TRIGGER` variant.
1609    ///
1610    /// This alias returns `None` and may be removed in a future version.
1611    #[classattr]
1612    #[pyo3(name = "NO_TRIGGER")]
1613    #[allow(clippy::use_self)]
1614    const fn py_no_trigger() -> Option<TriggerType> {
1615        None
1616    }
1617
1618    const fn __hash__(&self) -> isize {
1619        *self as isize
1620    }
1621
1622    fn __str__(&self) -> String {
1623        self.to_string()
1624    }
1625
1626    #[getter]
1627    #[must_use]
1628    pub fn name(&self) -> String {
1629        self.to_string()
1630    }
1631
1632    #[getter]
1633    #[must_use]
1634    pub fn value(&self) -> u8 {
1635        *self as u8
1636    }
1637
1638    #[classmethod]
1639    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1640        EnumIterator::new::<Self>(py)
1641    }
1642
1643    #[classmethod]
1644    #[pyo3(name = "from_str")]
1645    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Option<Self>> {
1646        let data_str: &str = data.extract()?;
1647        let tokenized = data_str.to_uppercase();
1648        if tokenized == "NO_TRIGGER" {
1649            Ok(None)
1650        } else {
1651            Self::from_str(&tokenized).map(Some).map_err(to_pyvalue_err)
1652        }
1653    }
1654}
1655
1656#[pymethods]
1657#[pyo3_stub_gen::derive::gen_stub_pymethods]
1658impl BookType {
1659    /// The order book type, representing the type of levels granularity and delta updating heuristics.
1660    #[new]
1661    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1662        let t = Self::type_object(py);
1663        Self::py_from_str(&t, value)
1664    }
1665
1666    const fn __hash__(&self) -> isize {
1667        *self as isize
1668    }
1669
1670    fn __str__(&self) -> String {
1671        self.to_string()
1672    }
1673
1674    #[getter]
1675    #[must_use]
1676    pub fn name(&self) -> String {
1677        self.to_string()
1678    }
1679
1680    #[getter]
1681    #[must_use]
1682    pub fn value(&self) -> u8 {
1683        *self as u8
1684    }
1685
1686    #[classmethod]
1687    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1688        EnumIterator::new::<Self>(py)
1689    }
1690
1691    #[classmethod]
1692    #[pyo3(name = "from_str")]
1693    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1694        let data_str: &str = data.extract()?;
1695        let tokenized = data_str.to_uppercase();
1696        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1697    }
1698}
1699
1700#[pymethods]
1701#[pyo3_stub_gen::derive::gen_stub_pymethods]
1702impl TradingState {
1703    /// The trading state for a node.
1704    #[new]
1705    fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
1706        let t = Self::type_object(py);
1707        Self::py_from_str(&t, value)
1708    }
1709
1710    const fn __hash__(&self) -> isize {
1711        *self as isize
1712    }
1713
1714    fn __str__(&self) -> String {
1715        self.to_string()
1716    }
1717
1718    #[getter]
1719    #[must_use]
1720    pub fn name(&self) -> String {
1721        self.to_string()
1722    }
1723
1724    #[getter]
1725    #[must_use]
1726    pub fn value(&self) -> u8 {
1727        *self as u8
1728    }
1729
1730    #[classmethod]
1731    fn variants(_: &Bound<'_, PyType>, py: Python<'_>) -> EnumIterator {
1732        EnumIterator::new::<Self>(py)
1733    }
1734
1735    #[classmethod]
1736    #[pyo3(name = "from_str")]
1737    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
1738        let data_str: &str = data.extract()?;
1739        let tokenized = data_str.to_uppercase();
1740        Self::from_str(&tokenized).map_err(to_pyvalue_err)
1741    }
1742}