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