Skip to main content

nautilus_common/python/
commands.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//! Python properties for native subscription and execution commands.
17//!
18//! Exposes owned Rust messages through read-only getters, converting timestamps, parameters,
19//! and order payloads into their Python representations. These classes are registered in the
20//! Python live module for delivery to custom adapter handlers.
21
22use std::num::NonZero;
23
24use nautilus_core::{
25    UUID4,
26    python::{params::params_to_pydict, to_pyvalue_err},
27};
28use nautilus_model::{
29    data::{BarType, DataType},
30    enums::{BookType, OrderSide},
31    events::OrderInitialized,
32    identifiers::{
33        AccountId, ClientId, ClientOrderId, ExecAlgorithmId, InstrumentId, PositionId, StrategyId,
34        TraderId, Venue, VenueOrderId,
35    },
36    orders::{OrderAny, OrderList},
37    python::orders::order_any_to_pyobject,
38    types::{Price, Quantity},
39};
40use pyo3::{prelude::*, types::PyDict};
41
42use crate::{
43    enums::LogLevel,
44    messages::{
45        data::{
46            SubscribeBars, SubscribeBookDeltas, SubscribeBookDepth, SubscribeCustomData,
47            SubscribeFundingRates, SubscribeIndexPrices, SubscribeInstrument,
48            SubscribeInstrumentClose, SubscribeInstrumentStatus, SubscribeInstruments,
49            SubscribeMarkPrices, SubscribeOptionGreeks, SubscribeQuotes, SubscribeTrades,
50            UnsubscribeBars, UnsubscribeBookDeltas, UnsubscribeBookDepth, UnsubscribeCustomData,
51            UnsubscribeFundingRates, UnsubscribeIndexPrices, UnsubscribeInstrument,
52            UnsubscribeInstrumentClose, UnsubscribeInstrumentStatus, UnsubscribeInstruments,
53            UnsubscribeMarkPrices, UnsubscribeOptionGreeks, UnsubscribeQuotes, UnsubscribeTrades,
54        },
55        execution::{
56            BatchCancelOrders, BatchModifyOrders, CancelAllOrders, CancelOrder,
57            GenerateFillReports, GenerateOrderStatusReport, GenerateOrderStatusReports,
58            GeneratePositionStatusReports, ModifyOrder, QueryAccount, QueryOrder, SubmitOrder,
59            SubmitOrderList,
60        },
61    },
62};
63
64#[pymethods]
65#[pyo3_stub_gen::derive::gen_stub_pymethods]
66impl SubscribeCustomData {
67    #[getter]
68    #[pyo3(name = "client_id")]
69    fn py_client_id(&self) -> Option<ClientId> {
70        self.client_id
71    }
72
73    #[getter]
74    #[pyo3(name = "venue")]
75    fn py_venue(&self) -> Option<Venue> {
76        self.venue
77    }
78
79    #[getter]
80    #[pyo3(name = "command_id")]
81    fn py_command_id(&self) -> UUID4 {
82        self.command_id
83    }
84
85    #[getter]
86    #[pyo3(name = "ts_init")]
87    fn py_ts_init(&self) -> u64 {
88        self.ts_init.as_u64()
89    }
90
91    #[getter]
92    #[pyo3(name = "correlation_id")]
93    fn py_correlation_id(&self) -> Option<UUID4> {
94        self.correlation_id
95    }
96
97    #[getter]
98    #[pyo3(name = "params")]
99    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
100        self.params
101            .as_ref()
102            .map(|params| params_to_pydict(py, params))
103            .transpose()
104    }
105
106    #[getter]
107    #[pyo3(name = "data_type")]
108    fn py_data_type(&self) -> DataType {
109        self.data_type.clone()
110    }
111}
112
113#[pymethods]
114#[pyo3_stub_gen::derive::gen_stub_pymethods]
115impl SubscribeInstruments {
116    #[getter]
117    #[pyo3(name = "client_id")]
118    fn py_client_id(&self) -> Option<ClientId> {
119        self.client_id
120    }
121
122    #[getter]
123    #[pyo3(name = "venue")]
124    fn py_venue(&self) -> Venue {
125        self.venue
126    }
127
128    #[getter]
129    #[pyo3(name = "command_id")]
130    fn py_command_id(&self) -> UUID4 {
131        self.command_id
132    }
133
134    #[getter]
135    #[pyo3(name = "ts_init")]
136    fn py_ts_init(&self) -> u64 {
137        self.ts_init.as_u64()
138    }
139
140    #[getter]
141    #[pyo3(name = "correlation_id")]
142    fn py_correlation_id(&self) -> Option<UUID4> {
143        self.correlation_id
144    }
145
146    #[getter]
147    #[pyo3(name = "params")]
148    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
149        self.params
150            .as_ref()
151            .map(|params| params_to_pydict(py, params))
152            .transpose()
153    }
154}
155
156#[pymethods]
157#[pyo3_stub_gen::derive::gen_stub_pymethods]
158impl SubscribeInstrument {
159    #[getter]
160    #[pyo3(name = "client_id")]
161    fn py_client_id(&self) -> Option<ClientId> {
162        self.client_id
163    }
164
165    #[getter]
166    #[pyo3(name = "venue")]
167    fn py_venue(&self) -> Option<Venue> {
168        self.venue
169    }
170
171    #[getter]
172    #[pyo3(name = "command_id")]
173    fn py_command_id(&self) -> UUID4 {
174        self.command_id
175    }
176
177    #[getter]
178    #[pyo3(name = "ts_init")]
179    fn py_ts_init(&self) -> u64 {
180        self.ts_init.as_u64()
181    }
182
183    #[getter]
184    #[pyo3(name = "correlation_id")]
185    fn py_correlation_id(&self) -> Option<UUID4> {
186        self.correlation_id
187    }
188
189    #[getter]
190    #[pyo3(name = "params")]
191    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
192        self.params
193            .as_ref()
194            .map(|params| params_to_pydict(py, params))
195            .transpose()
196    }
197
198    #[getter]
199    #[pyo3(name = "instrument_id")]
200    fn py_instrument_id(&self) -> InstrumentId {
201        self.instrument_id
202    }
203}
204
205#[pymethods]
206#[pyo3_stub_gen::derive::gen_stub_pymethods]
207impl SubscribeBookDeltas {
208    #[getter]
209    #[pyo3(name = "client_id")]
210    fn py_client_id(&self) -> Option<ClientId> {
211        self.client_id
212    }
213
214    #[getter]
215    #[pyo3(name = "venue")]
216    fn py_venue(&self) -> Option<Venue> {
217        self.venue
218    }
219
220    #[getter]
221    #[pyo3(name = "command_id")]
222    fn py_command_id(&self) -> UUID4 {
223        self.command_id
224    }
225
226    #[getter]
227    #[pyo3(name = "ts_init")]
228    fn py_ts_init(&self) -> u64 {
229        self.ts_init.as_u64()
230    }
231
232    #[getter]
233    #[pyo3(name = "correlation_id")]
234    fn py_correlation_id(&self) -> Option<UUID4> {
235        self.correlation_id
236    }
237
238    #[getter]
239    #[pyo3(name = "params")]
240    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
241        self.params
242            .as_ref()
243            .map(|params| params_to_pydict(py, params))
244            .transpose()
245    }
246
247    #[getter]
248    #[pyo3(name = "instrument_id")]
249    fn py_instrument_id(&self) -> InstrumentId {
250        self.instrument_id
251    }
252
253    #[getter]
254    #[pyo3(name = "book_type")]
255    fn py_book_type(&self) -> BookType {
256        self.book_type
257    }
258
259    #[getter]
260    #[pyo3(name = "depth")]
261    fn py_depth(&self) -> Option<usize> {
262        self.depth.map(NonZero::get)
263    }
264
265    #[getter]
266    #[pyo3(name = "managed")]
267    fn py_managed(&self) -> bool {
268        self.managed
269    }
270}
271
272#[pymethods]
273#[pyo3_stub_gen::derive::gen_stub_pymethods]
274impl SubscribeBookDepth {
275    #[getter]
276    #[pyo3(name = "client_id")]
277    fn py_client_id(&self) -> Option<ClientId> {
278        self.client_id
279    }
280
281    #[getter]
282    #[pyo3(name = "venue")]
283    fn py_venue(&self) -> Option<Venue> {
284        self.venue
285    }
286
287    #[getter]
288    #[pyo3(name = "command_id")]
289    fn py_command_id(&self) -> UUID4 {
290        self.command_id
291    }
292
293    #[getter]
294    #[pyo3(name = "ts_init")]
295    fn py_ts_init(&self) -> u64 {
296        self.ts_init.as_u64()
297    }
298
299    #[getter]
300    #[pyo3(name = "correlation_id")]
301    fn py_correlation_id(&self) -> Option<UUID4> {
302        self.correlation_id
303    }
304
305    #[getter]
306    #[pyo3(name = "params")]
307    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
308        self.params
309            .as_ref()
310            .map(|params| params_to_pydict(py, params))
311            .transpose()
312    }
313
314    #[getter]
315    #[pyo3(name = "instrument_id")]
316    fn py_instrument_id(&self) -> InstrumentId {
317        self.instrument_id
318    }
319
320    #[getter]
321    #[pyo3(name = "book_type")]
322    fn py_book_type(&self) -> BookType {
323        self.book_type
324    }
325
326    #[getter]
327    #[pyo3(name = "depth")]
328    fn py_depth(&self) -> Option<usize> {
329        self.depth.map(NonZero::get)
330    }
331
332    #[getter]
333    #[pyo3(name = "managed")]
334    fn py_managed(&self) -> bool {
335        self.managed
336    }
337}
338
339#[pymethods]
340#[pyo3_stub_gen::derive::gen_stub_pymethods]
341impl SubscribeQuotes {
342    #[getter]
343    #[pyo3(name = "client_id")]
344    fn py_client_id(&self) -> Option<ClientId> {
345        self.client_id
346    }
347
348    #[getter]
349    #[pyo3(name = "venue")]
350    fn py_venue(&self) -> Option<Venue> {
351        self.venue
352    }
353
354    #[getter]
355    #[pyo3(name = "command_id")]
356    fn py_command_id(&self) -> UUID4 {
357        self.command_id
358    }
359
360    #[getter]
361    #[pyo3(name = "ts_init")]
362    fn py_ts_init(&self) -> u64 {
363        self.ts_init.as_u64()
364    }
365
366    #[getter]
367    #[pyo3(name = "correlation_id")]
368    fn py_correlation_id(&self) -> Option<UUID4> {
369        self.correlation_id
370    }
371
372    #[getter]
373    #[pyo3(name = "params")]
374    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
375        self.params
376            .as_ref()
377            .map(|params| params_to_pydict(py, params))
378            .transpose()
379    }
380
381    #[getter]
382    #[pyo3(name = "instrument_id")]
383    fn py_instrument_id(&self) -> InstrumentId {
384        self.instrument_id
385    }
386}
387
388#[pymethods]
389#[pyo3_stub_gen::derive::gen_stub_pymethods]
390impl SubscribeTrades {
391    #[getter]
392    #[pyo3(name = "client_id")]
393    fn py_client_id(&self) -> Option<ClientId> {
394        self.client_id
395    }
396
397    #[getter]
398    #[pyo3(name = "venue")]
399    fn py_venue(&self) -> Option<Venue> {
400        self.venue
401    }
402
403    #[getter]
404    #[pyo3(name = "command_id")]
405    fn py_command_id(&self) -> UUID4 {
406        self.command_id
407    }
408
409    #[getter]
410    #[pyo3(name = "ts_init")]
411    fn py_ts_init(&self) -> u64 {
412        self.ts_init.as_u64()
413    }
414
415    #[getter]
416    #[pyo3(name = "correlation_id")]
417    fn py_correlation_id(&self) -> Option<UUID4> {
418        self.correlation_id
419    }
420
421    #[getter]
422    #[pyo3(name = "params")]
423    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
424        self.params
425            .as_ref()
426            .map(|params| params_to_pydict(py, params))
427            .transpose()
428    }
429
430    #[getter]
431    #[pyo3(name = "instrument_id")]
432    fn py_instrument_id(&self) -> InstrumentId {
433        self.instrument_id
434    }
435}
436
437#[pymethods]
438#[pyo3_stub_gen::derive::gen_stub_pymethods]
439impl SubscribeMarkPrices {
440    #[getter]
441    #[pyo3(name = "client_id")]
442    fn py_client_id(&self) -> Option<ClientId> {
443        self.client_id
444    }
445
446    #[getter]
447    #[pyo3(name = "venue")]
448    fn py_venue(&self) -> Option<Venue> {
449        self.venue
450    }
451
452    #[getter]
453    #[pyo3(name = "command_id")]
454    fn py_command_id(&self) -> UUID4 {
455        self.command_id
456    }
457
458    #[getter]
459    #[pyo3(name = "ts_init")]
460    fn py_ts_init(&self) -> u64 {
461        self.ts_init.as_u64()
462    }
463
464    #[getter]
465    #[pyo3(name = "correlation_id")]
466    fn py_correlation_id(&self) -> Option<UUID4> {
467        self.correlation_id
468    }
469
470    #[getter]
471    #[pyo3(name = "params")]
472    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
473        self.params
474            .as_ref()
475            .map(|params| params_to_pydict(py, params))
476            .transpose()
477    }
478
479    #[getter]
480    #[pyo3(name = "instrument_id")]
481    fn py_instrument_id(&self) -> InstrumentId {
482        self.instrument_id
483    }
484}
485
486#[pymethods]
487#[pyo3_stub_gen::derive::gen_stub_pymethods]
488impl SubscribeIndexPrices {
489    #[getter]
490    #[pyo3(name = "client_id")]
491    fn py_client_id(&self) -> Option<ClientId> {
492        self.client_id
493    }
494
495    #[getter]
496    #[pyo3(name = "venue")]
497    fn py_venue(&self) -> Option<Venue> {
498        self.venue
499    }
500
501    #[getter]
502    #[pyo3(name = "command_id")]
503    fn py_command_id(&self) -> UUID4 {
504        self.command_id
505    }
506
507    #[getter]
508    #[pyo3(name = "ts_init")]
509    fn py_ts_init(&self) -> u64 {
510        self.ts_init.as_u64()
511    }
512
513    #[getter]
514    #[pyo3(name = "correlation_id")]
515    fn py_correlation_id(&self) -> Option<UUID4> {
516        self.correlation_id
517    }
518
519    #[getter]
520    #[pyo3(name = "params")]
521    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
522        self.params
523            .as_ref()
524            .map(|params| params_to_pydict(py, params))
525            .transpose()
526    }
527
528    #[getter]
529    #[pyo3(name = "instrument_id")]
530    fn py_instrument_id(&self) -> InstrumentId {
531        self.instrument_id
532    }
533}
534
535#[pymethods]
536#[pyo3_stub_gen::derive::gen_stub_pymethods]
537impl SubscribeFundingRates {
538    #[getter]
539    #[pyo3(name = "client_id")]
540    fn py_client_id(&self) -> Option<ClientId> {
541        self.client_id
542    }
543
544    #[getter]
545    #[pyo3(name = "venue")]
546    fn py_venue(&self) -> Option<Venue> {
547        self.venue
548    }
549
550    #[getter]
551    #[pyo3(name = "command_id")]
552    fn py_command_id(&self) -> UUID4 {
553        self.command_id
554    }
555
556    #[getter]
557    #[pyo3(name = "ts_init")]
558    fn py_ts_init(&self) -> u64 {
559        self.ts_init.as_u64()
560    }
561
562    #[getter]
563    #[pyo3(name = "correlation_id")]
564    fn py_correlation_id(&self) -> Option<UUID4> {
565        self.correlation_id
566    }
567
568    #[getter]
569    #[pyo3(name = "params")]
570    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
571        self.params
572            .as_ref()
573            .map(|params| params_to_pydict(py, params))
574            .transpose()
575    }
576
577    #[getter]
578    #[pyo3(name = "instrument_id")]
579    fn py_instrument_id(&self) -> InstrumentId {
580        self.instrument_id
581    }
582}
583
584#[pymethods]
585#[pyo3_stub_gen::derive::gen_stub_pymethods]
586impl SubscribeBars {
587    #[getter]
588    #[pyo3(name = "client_id")]
589    fn py_client_id(&self) -> Option<ClientId> {
590        self.client_id
591    }
592
593    #[getter]
594    #[pyo3(name = "venue")]
595    fn py_venue(&self) -> Option<Venue> {
596        self.venue
597    }
598
599    #[getter]
600    #[pyo3(name = "command_id")]
601    fn py_command_id(&self) -> UUID4 {
602        self.command_id
603    }
604
605    #[getter]
606    #[pyo3(name = "ts_init")]
607    fn py_ts_init(&self) -> u64 {
608        self.ts_init.as_u64()
609    }
610
611    #[getter]
612    #[pyo3(name = "correlation_id")]
613    fn py_correlation_id(&self) -> Option<UUID4> {
614        self.correlation_id
615    }
616
617    #[getter]
618    #[pyo3(name = "params")]
619    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
620        self.params
621            .as_ref()
622            .map(|params| params_to_pydict(py, params))
623            .transpose()
624    }
625
626    #[getter]
627    #[pyo3(name = "bar_type")]
628    fn py_bar_type(&self) -> BarType {
629        self.bar_type
630    }
631}
632
633#[pymethods]
634#[pyo3_stub_gen::derive::gen_stub_pymethods]
635impl SubscribeInstrumentStatus {
636    #[getter]
637    #[pyo3(name = "client_id")]
638    fn py_client_id(&self) -> Option<ClientId> {
639        self.client_id
640    }
641
642    #[getter]
643    #[pyo3(name = "venue")]
644    fn py_venue(&self) -> Option<Venue> {
645        self.venue
646    }
647
648    #[getter]
649    #[pyo3(name = "command_id")]
650    fn py_command_id(&self) -> UUID4 {
651        self.command_id
652    }
653
654    #[getter]
655    #[pyo3(name = "ts_init")]
656    fn py_ts_init(&self) -> u64 {
657        self.ts_init.as_u64()
658    }
659
660    #[getter]
661    #[pyo3(name = "correlation_id")]
662    fn py_correlation_id(&self) -> Option<UUID4> {
663        self.correlation_id
664    }
665
666    #[getter]
667    #[pyo3(name = "params")]
668    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
669        self.params
670            .as_ref()
671            .map(|params| params_to_pydict(py, params))
672            .transpose()
673    }
674
675    #[getter]
676    #[pyo3(name = "instrument_id")]
677    fn py_instrument_id(&self) -> InstrumentId {
678        self.instrument_id
679    }
680}
681
682#[pymethods]
683#[pyo3_stub_gen::derive::gen_stub_pymethods]
684impl SubscribeInstrumentClose {
685    #[getter]
686    #[pyo3(name = "client_id")]
687    fn py_client_id(&self) -> Option<ClientId> {
688        self.client_id
689    }
690
691    #[getter]
692    #[pyo3(name = "venue")]
693    fn py_venue(&self) -> Option<Venue> {
694        self.venue
695    }
696
697    #[getter]
698    #[pyo3(name = "command_id")]
699    fn py_command_id(&self) -> UUID4 {
700        self.command_id
701    }
702
703    #[getter]
704    #[pyo3(name = "ts_init")]
705    fn py_ts_init(&self) -> u64 {
706        self.ts_init.as_u64()
707    }
708
709    #[getter]
710    #[pyo3(name = "correlation_id")]
711    fn py_correlation_id(&self) -> Option<UUID4> {
712        self.correlation_id
713    }
714
715    #[getter]
716    #[pyo3(name = "params")]
717    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
718        self.params
719            .as_ref()
720            .map(|params| params_to_pydict(py, params))
721            .transpose()
722    }
723
724    #[getter]
725    #[pyo3(name = "instrument_id")]
726    fn py_instrument_id(&self) -> InstrumentId {
727        self.instrument_id
728    }
729}
730
731#[pymethods]
732#[pyo3_stub_gen::derive::gen_stub_pymethods]
733impl SubscribeOptionGreeks {
734    #[getter]
735    #[pyo3(name = "client_id")]
736    fn py_client_id(&self) -> Option<ClientId> {
737        self.client_id
738    }
739
740    #[getter]
741    #[pyo3(name = "venue")]
742    fn py_venue(&self) -> Option<Venue> {
743        self.venue
744    }
745
746    #[getter]
747    #[pyo3(name = "command_id")]
748    fn py_command_id(&self) -> UUID4 {
749        self.command_id
750    }
751
752    #[getter]
753    #[pyo3(name = "ts_init")]
754    fn py_ts_init(&self) -> u64 {
755        self.ts_init.as_u64()
756    }
757
758    #[getter]
759    #[pyo3(name = "correlation_id")]
760    fn py_correlation_id(&self) -> Option<UUID4> {
761        self.correlation_id
762    }
763
764    #[getter]
765    #[pyo3(name = "params")]
766    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
767        self.params
768            .as_ref()
769            .map(|params| params_to_pydict(py, params))
770            .transpose()
771    }
772
773    #[getter]
774    #[pyo3(name = "instrument_id")]
775    fn py_instrument_id(&self) -> InstrumentId {
776        self.instrument_id
777    }
778}
779
780#[pymethods]
781#[pyo3_stub_gen::derive::gen_stub_pymethods]
782impl UnsubscribeCustomData {
783    #[getter]
784    #[pyo3(name = "client_id")]
785    fn py_client_id(&self) -> Option<ClientId> {
786        self.client_id
787    }
788
789    #[getter]
790    #[pyo3(name = "venue")]
791    fn py_venue(&self) -> Option<Venue> {
792        self.venue
793    }
794
795    #[getter]
796    #[pyo3(name = "command_id")]
797    fn py_command_id(&self) -> UUID4 {
798        self.command_id
799    }
800
801    #[getter]
802    #[pyo3(name = "ts_init")]
803    fn py_ts_init(&self) -> u64 {
804        self.ts_init.as_u64()
805    }
806
807    #[getter]
808    #[pyo3(name = "correlation_id")]
809    fn py_correlation_id(&self) -> Option<UUID4> {
810        self.correlation_id
811    }
812
813    #[getter]
814    #[pyo3(name = "params")]
815    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
816        self.params
817            .as_ref()
818            .map(|params| params_to_pydict(py, params))
819            .transpose()
820    }
821
822    #[getter]
823    #[pyo3(name = "data_type")]
824    fn py_data_type(&self) -> DataType {
825        self.data_type.clone()
826    }
827}
828
829#[pymethods]
830#[pyo3_stub_gen::derive::gen_stub_pymethods]
831impl UnsubscribeInstruments {
832    #[getter]
833    #[pyo3(name = "client_id")]
834    fn py_client_id(&self) -> Option<ClientId> {
835        self.client_id
836    }
837
838    #[getter]
839    #[pyo3(name = "venue")]
840    fn py_venue(&self) -> Venue {
841        self.venue
842    }
843
844    #[getter]
845    #[pyo3(name = "command_id")]
846    fn py_command_id(&self) -> UUID4 {
847        self.command_id
848    }
849
850    #[getter]
851    #[pyo3(name = "ts_init")]
852    fn py_ts_init(&self) -> u64 {
853        self.ts_init.as_u64()
854    }
855
856    #[getter]
857    #[pyo3(name = "correlation_id")]
858    fn py_correlation_id(&self) -> Option<UUID4> {
859        self.correlation_id
860    }
861
862    #[getter]
863    #[pyo3(name = "params")]
864    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
865        self.params
866            .as_ref()
867            .map(|params| params_to_pydict(py, params))
868            .transpose()
869    }
870}
871
872#[pymethods]
873#[pyo3_stub_gen::derive::gen_stub_pymethods]
874impl UnsubscribeInstrument {
875    #[getter]
876    #[pyo3(name = "client_id")]
877    fn py_client_id(&self) -> Option<ClientId> {
878        self.client_id
879    }
880
881    #[getter]
882    #[pyo3(name = "venue")]
883    fn py_venue(&self) -> Option<Venue> {
884        self.venue
885    }
886
887    #[getter]
888    #[pyo3(name = "command_id")]
889    fn py_command_id(&self) -> UUID4 {
890        self.command_id
891    }
892
893    #[getter]
894    #[pyo3(name = "ts_init")]
895    fn py_ts_init(&self) -> u64 {
896        self.ts_init.as_u64()
897    }
898
899    #[getter]
900    #[pyo3(name = "correlation_id")]
901    fn py_correlation_id(&self) -> Option<UUID4> {
902        self.correlation_id
903    }
904
905    #[getter]
906    #[pyo3(name = "params")]
907    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
908        self.params
909            .as_ref()
910            .map(|params| params_to_pydict(py, params))
911            .transpose()
912    }
913
914    #[getter]
915    #[pyo3(name = "instrument_id")]
916    fn py_instrument_id(&self) -> InstrumentId {
917        self.instrument_id
918    }
919}
920
921#[pymethods]
922#[pyo3_stub_gen::derive::gen_stub_pymethods]
923impl UnsubscribeBookDeltas {
924    #[getter]
925    #[pyo3(name = "client_id")]
926    fn py_client_id(&self) -> Option<ClientId> {
927        self.client_id
928    }
929
930    #[getter]
931    #[pyo3(name = "venue")]
932    fn py_venue(&self) -> Option<Venue> {
933        self.venue
934    }
935
936    #[getter]
937    #[pyo3(name = "command_id")]
938    fn py_command_id(&self) -> UUID4 {
939        self.command_id
940    }
941
942    #[getter]
943    #[pyo3(name = "ts_init")]
944    fn py_ts_init(&self) -> u64 {
945        self.ts_init.as_u64()
946    }
947
948    #[getter]
949    #[pyo3(name = "correlation_id")]
950    fn py_correlation_id(&self) -> Option<UUID4> {
951        self.correlation_id
952    }
953
954    #[getter]
955    #[pyo3(name = "params")]
956    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
957        self.params
958            .as_ref()
959            .map(|params| params_to_pydict(py, params))
960            .transpose()
961    }
962
963    #[getter]
964    #[pyo3(name = "instrument_id")]
965    fn py_instrument_id(&self) -> InstrumentId {
966        self.instrument_id
967    }
968}
969
970#[pymethods]
971#[pyo3_stub_gen::derive::gen_stub_pymethods]
972impl UnsubscribeBookDepth {
973    #[getter]
974    #[pyo3(name = "client_id")]
975    fn py_client_id(&self) -> Option<ClientId> {
976        self.client_id
977    }
978
979    #[getter]
980    #[pyo3(name = "venue")]
981    fn py_venue(&self) -> Option<Venue> {
982        self.venue
983    }
984
985    #[getter]
986    #[pyo3(name = "command_id")]
987    fn py_command_id(&self) -> UUID4 {
988        self.command_id
989    }
990
991    #[getter]
992    #[pyo3(name = "ts_init")]
993    fn py_ts_init(&self) -> u64 {
994        self.ts_init.as_u64()
995    }
996
997    #[getter]
998    #[pyo3(name = "correlation_id")]
999    fn py_correlation_id(&self) -> Option<UUID4> {
1000        self.correlation_id
1001    }
1002
1003    #[getter]
1004    #[pyo3(name = "params")]
1005    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1006        self.params
1007            .as_ref()
1008            .map(|params| params_to_pydict(py, params))
1009            .transpose()
1010    }
1011
1012    #[getter]
1013    #[pyo3(name = "instrument_id")]
1014    fn py_instrument_id(&self) -> InstrumentId {
1015        self.instrument_id
1016    }
1017}
1018
1019#[pymethods]
1020#[pyo3_stub_gen::derive::gen_stub_pymethods]
1021impl UnsubscribeQuotes {
1022    #[getter]
1023    #[pyo3(name = "client_id")]
1024    fn py_client_id(&self) -> Option<ClientId> {
1025        self.client_id
1026    }
1027
1028    #[getter]
1029    #[pyo3(name = "venue")]
1030    fn py_venue(&self) -> Option<Venue> {
1031        self.venue
1032    }
1033
1034    #[getter]
1035    #[pyo3(name = "command_id")]
1036    fn py_command_id(&self) -> UUID4 {
1037        self.command_id
1038    }
1039
1040    #[getter]
1041    #[pyo3(name = "ts_init")]
1042    fn py_ts_init(&self) -> u64 {
1043        self.ts_init.as_u64()
1044    }
1045
1046    #[getter]
1047    #[pyo3(name = "correlation_id")]
1048    fn py_correlation_id(&self) -> Option<UUID4> {
1049        self.correlation_id
1050    }
1051
1052    #[getter]
1053    #[pyo3(name = "params")]
1054    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1055        self.params
1056            .as_ref()
1057            .map(|params| params_to_pydict(py, params))
1058            .transpose()
1059    }
1060
1061    #[getter]
1062    #[pyo3(name = "instrument_id")]
1063    fn py_instrument_id(&self) -> InstrumentId {
1064        self.instrument_id
1065    }
1066}
1067
1068#[pymethods]
1069#[pyo3_stub_gen::derive::gen_stub_pymethods]
1070impl UnsubscribeTrades {
1071    #[getter]
1072    #[pyo3(name = "client_id")]
1073    fn py_client_id(&self) -> Option<ClientId> {
1074        self.client_id
1075    }
1076
1077    #[getter]
1078    #[pyo3(name = "venue")]
1079    fn py_venue(&self) -> Option<Venue> {
1080        self.venue
1081    }
1082
1083    #[getter]
1084    #[pyo3(name = "command_id")]
1085    fn py_command_id(&self) -> UUID4 {
1086        self.command_id
1087    }
1088
1089    #[getter]
1090    #[pyo3(name = "ts_init")]
1091    fn py_ts_init(&self) -> u64 {
1092        self.ts_init.as_u64()
1093    }
1094
1095    #[getter]
1096    #[pyo3(name = "correlation_id")]
1097    fn py_correlation_id(&self) -> Option<UUID4> {
1098        self.correlation_id
1099    }
1100
1101    #[getter]
1102    #[pyo3(name = "params")]
1103    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1104        self.params
1105            .as_ref()
1106            .map(|params| params_to_pydict(py, params))
1107            .transpose()
1108    }
1109
1110    #[getter]
1111    #[pyo3(name = "instrument_id")]
1112    fn py_instrument_id(&self) -> InstrumentId {
1113        self.instrument_id
1114    }
1115}
1116
1117#[pymethods]
1118#[pyo3_stub_gen::derive::gen_stub_pymethods]
1119impl UnsubscribeMarkPrices {
1120    #[getter]
1121    #[pyo3(name = "client_id")]
1122    fn py_client_id(&self) -> Option<ClientId> {
1123        self.client_id
1124    }
1125
1126    #[getter]
1127    #[pyo3(name = "venue")]
1128    fn py_venue(&self) -> Option<Venue> {
1129        self.venue
1130    }
1131
1132    #[getter]
1133    #[pyo3(name = "command_id")]
1134    fn py_command_id(&self) -> UUID4 {
1135        self.command_id
1136    }
1137
1138    #[getter]
1139    #[pyo3(name = "ts_init")]
1140    fn py_ts_init(&self) -> u64 {
1141        self.ts_init.as_u64()
1142    }
1143
1144    #[getter]
1145    #[pyo3(name = "correlation_id")]
1146    fn py_correlation_id(&self) -> Option<UUID4> {
1147        self.correlation_id
1148    }
1149
1150    #[getter]
1151    #[pyo3(name = "params")]
1152    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1153        self.params
1154            .as_ref()
1155            .map(|params| params_to_pydict(py, params))
1156            .transpose()
1157    }
1158
1159    #[getter]
1160    #[pyo3(name = "instrument_id")]
1161    fn py_instrument_id(&self) -> InstrumentId {
1162        self.instrument_id
1163    }
1164}
1165
1166#[pymethods]
1167#[pyo3_stub_gen::derive::gen_stub_pymethods]
1168impl UnsubscribeIndexPrices {
1169    #[getter]
1170    #[pyo3(name = "client_id")]
1171    fn py_client_id(&self) -> Option<ClientId> {
1172        self.client_id
1173    }
1174
1175    #[getter]
1176    #[pyo3(name = "venue")]
1177    fn py_venue(&self) -> Option<Venue> {
1178        self.venue
1179    }
1180
1181    #[getter]
1182    #[pyo3(name = "command_id")]
1183    fn py_command_id(&self) -> UUID4 {
1184        self.command_id
1185    }
1186
1187    #[getter]
1188    #[pyo3(name = "ts_init")]
1189    fn py_ts_init(&self) -> u64 {
1190        self.ts_init.as_u64()
1191    }
1192
1193    #[getter]
1194    #[pyo3(name = "correlation_id")]
1195    fn py_correlation_id(&self) -> Option<UUID4> {
1196        self.correlation_id
1197    }
1198
1199    #[getter]
1200    #[pyo3(name = "params")]
1201    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1202        self.params
1203            .as_ref()
1204            .map(|params| params_to_pydict(py, params))
1205            .transpose()
1206    }
1207
1208    #[getter]
1209    #[pyo3(name = "instrument_id")]
1210    fn py_instrument_id(&self) -> InstrumentId {
1211        self.instrument_id
1212    }
1213}
1214
1215#[pymethods]
1216#[pyo3_stub_gen::derive::gen_stub_pymethods]
1217impl UnsubscribeFundingRates {
1218    #[getter]
1219    #[pyo3(name = "client_id")]
1220    fn py_client_id(&self) -> Option<ClientId> {
1221        self.client_id
1222    }
1223
1224    #[getter]
1225    #[pyo3(name = "venue")]
1226    fn py_venue(&self) -> Option<Venue> {
1227        self.venue
1228    }
1229
1230    #[getter]
1231    #[pyo3(name = "command_id")]
1232    fn py_command_id(&self) -> UUID4 {
1233        self.command_id
1234    }
1235
1236    #[getter]
1237    #[pyo3(name = "ts_init")]
1238    fn py_ts_init(&self) -> u64 {
1239        self.ts_init.as_u64()
1240    }
1241
1242    #[getter]
1243    #[pyo3(name = "correlation_id")]
1244    fn py_correlation_id(&self) -> Option<UUID4> {
1245        self.correlation_id
1246    }
1247
1248    #[getter]
1249    #[pyo3(name = "params")]
1250    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1251        self.params
1252            .as_ref()
1253            .map(|params| params_to_pydict(py, params))
1254            .transpose()
1255    }
1256
1257    #[getter]
1258    #[pyo3(name = "instrument_id")]
1259    fn py_instrument_id(&self) -> InstrumentId {
1260        self.instrument_id
1261    }
1262}
1263
1264#[pymethods]
1265#[pyo3_stub_gen::derive::gen_stub_pymethods]
1266impl UnsubscribeBars {
1267    #[getter]
1268    #[pyo3(name = "client_id")]
1269    fn py_client_id(&self) -> Option<ClientId> {
1270        self.client_id
1271    }
1272
1273    #[getter]
1274    #[pyo3(name = "venue")]
1275    fn py_venue(&self) -> Option<Venue> {
1276        self.venue
1277    }
1278
1279    #[getter]
1280    #[pyo3(name = "command_id")]
1281    fn py_command_id(&self) -> UUID4 {
1282        self.command_id
1283    }
1284
1285    #[getter]
1286    #[pyo3(name = "ts_init")]
1287    fn py_ts_init(&self) -> u64 {
1288        self.ts_init.as_u64()
1289    }
1290
1291    #[getter]
1292    #[pyo3(name = "correlation_id")]
1293    fn py_correlation_id(&self) -> Option<UUID4> {
1294        self.correlation_id
1295    }
1296
1297    #[getter]
1298    #[pyo3(name = "params")]
1299    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1300        self.params
1301            .as_ref()
1302            .map(|params| params_to_pydict(py, params))
1303            .transpose()
1304    }
1305
1306    #[getter]
1307    #[pyo3(name = "bar_type")]
1308    fn py_bar_type(&self) -> BarType {
1309        self.bar_type
1310    }
1311}
1312
1313#[pymethods]
1314#[pyo3_stub_gen::derive::gen_stub_pymethods]
1315impl UnsubscribeInstrumentStatus {
1316    #[getter]
1317    #[pyo3(name = "client_id")]
1318    fn py_client_id(&self) -> Option<ClientId> {
1319        self.client_id
1320    }
1321
1322    #[getter]
1323    #[pyo3(name = "venue")]
1324    fn py_venue(&self) -> Option<Venue> {
1325        self.venue
1326    }
1327
1328    #[getter]
1329    #[pyo3(name = "command_id")]
1330    fn py_command_id(&self) -> UUID4 {
1331        self.command_id
1332    }
1333
1334    #[getter]
1335    #[pyo3(name = "ts_init")]
1336    fn py_ts_init(&self) -> u64 {
1337        self.ts_init.as_u64()
1338    }
1339
1340    #[getter]
1341    #[pyo3(name = "correlation_id")]
1342    fn py_correlation_id(&self) -> Option<UUID4> {
1343        self.correlation_id
1344    }
1345
1346    #[getter]
1347    #[pyo3(name = "params")]
1348    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1349        self.params
1350            .as_ref()
1351            .map(|params| params_to_pydict(py, params))
1352            .transpose()
1353    }
1354
1355    #[getter]
1356    #[pyo3(name = "instrument_id")]
1357    fn py_instrument_id(&self) -> InstrumentId {
1358        self.instrument_id
1359    }
1360}
1361
1362#[pymethods]
1363#[pyo3_stub_gen::derive::gen_stub_pymethods]
1364impl UnsubscribeInstrumentClose {
1365    #[getter]
1366    #[pyo3(name = "client_id")]
1367    fn py_client_id(&self) -> Option<ClientId> {
1368        self.client_id
1369    }
1370
1371    #[getter]
1372    #[pyo3(name = "venue")]
1373    fn py_venue(&self) -> Option<Venue> {
1374        self.venue
1375    }
1376
1377    #[getter]
1378    #[pyo3(name = "command_id")]
1379    fn py_command_id(&self) -> UUID4 {
1380        self.command_id
1381    }
1382
1383    #[getter]
1384    #[pyo3(name = "ts_init")]
1385    fn py_ts_init(&self) -> u64 {
1386        self.ts_init.as_u64()
1387    }
1388
1389    #[getter]
1390    #[pyo3(name = "correlation_id")]
1391    fn py_correlation_id(&self) -> Option<UUID4> {
1392        self.correlation_id
1393    }
1394
1395    #[getter]
1396    #[pyo3(name = "params")]
1397    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1398        self.params
1399            .as_ref()
1400            .map(|params| params_to_pydict(py, params))
1401            .transpose()
1402    }
1403
1404    #[getter]
1405    #[pyo3(name = "instrument_id")]
1406    fn py_instrument_id(&self) -> InstrumentId {
1407        self.instrument_id
1408    }
1409}
1410
1411#[pymethods]
1412#[pyo3_stub_gen::derive::gen_stub_pymethods]
1413impl UnsubscribeOptionGreeks {
1414    #[getter]
1415    #[pyo3(name = "client_id")]
1416    fn py_client_id(&self) -> Option<ClientId> {
1417        self.client_id
1418    }
1419
1420    #[getter]
1421    #[pyo3(name = "venue")]
1422    fn py_venue(&self) -> Option<Venue> {
1423        self.venue
1424    }
1425
1426    #[getter]
1427    #[pyo3(name = "command_id")]
1428    fn py_command_id(&self) -> UUID4 {
1429        self.command_id
1430    }
1431
1432    #[getter]
1433    #[pyo3(name = "ts_init")]
1434    fn py_ts_init(&self) -> u64 {
1435        self.ts_init.as_u64()
1436    }
1437
1438    #[getter]
1439    #[pyo3(name = "correlation_id")]
1440    fn py_correlation_id(&self) -> Option<UUID4> {
1441        self.correlation_id
1442    }
1443
1444    #[getter]
1445    #[pyo3(name = "params")]
1446    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1447        self.params
1448            .as_ref()
1449            .map(|params| params_to_pydict(py, params))
1450            .transpose()
1451    }
1452
1453    #[getter]
1454    #[pyo3(name = "instrument_id")]
1455    fn py_instrument_id(&self) -> InstrumentId {
1456        self.instrument_id
1457    }
1458}
1459
1460#[pymethods]
1461#[pyo3_stub_gen::derive::gen_stub_pymethods]
1462impl SubmitOrder {
1463    #[getter]
1464    #[pyo3(name = "command_id")]
1465    fn py_command_id(&self) -> UUID4 {
1466        self.command_id
1467    }
1468
1469    #[getter]
1470    #[pyo3(name = "ts_init")]
1471    fn py_ts_init(&self) -> u64 {
1472        self.ts_init.as_u64()
1473    }
1474
1475    #[getter]
1476    #[pyo3(name = "correlation_id")]
1477    fn py_correlation_id(&self) -> Option<UUID4> {
1478        self.correlation_id
1479    }
1480
1481    #[getter]
1482    #[pyo3(name = "causation_id")]
1483    fn py_causation_id(&self) -> Option<UUID4> {
1484        self.causation_id
1485    }
1486
1487    #[getter]
1488    #[pyo3(name = "params")]
1489    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1490        self.params
1491            .as_ref()
1492            .map(|params| params_to_pydict(py, params))
1493            .transpose()
1494    }
1495
1496    #[getter]
1497    #[pyo3(name = "trader_id")]
1498    fn py_trader_id(&self) -> TraderId {
1499        self.trader_id
1500    }
1501
1502    #[getter]
1503    #[pyo3(name = "client_id")]
1504    fn py_client_id(&self) -> Option<ClientId> {
1505        self.client_id
1506    }
1507
1508    #[getter]
1509    #[pyo3(name = "strategy_id")]
1510    fn py_strategy_id(&self) -> StrategyId {
1511        self.strategy_id
1512    }
1513
1514    #[getter]
1515    #[pyo3(name = "instrument_id")]
1516    fn py_instrument_id(&self) -> InstrumentId {
1517        self.instrument_id
1518    }
1519
1520    #[getter]
1521    #[pyo3(name = "client_order_id")]
1522    fn py_client_order_id(&self) -> ClientOrderId {
1523        self.client_order_id
1524    }
1525
1526    #[getter]
1527    #[pyo3(name = "order_init")]
1528    fn py_order_init(&self) -> OrderInitialized {
1529        self.order_init.clone()
1530    }
1531
1532    #[getter]
1533    #[pyo3(name = "exec_algorithm_id")]
1534    fn py_exec_algorithm_id(&self) -> Option<ExecAlgorithmId> {
1535        self.exec_algorithm_id
1536    }
1537
1538    #[getter]
1539    #[pyo3(name = "position_id")]
1540    fn py_position_id(&self) -> Option<PositionId> {
1541        self.position_id
1542    }
1543
1544    #[getter]
1545    #[pyo3(name = "order")]
1546    fn py_order(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
1547        let order = OrderAny::try_from(self.order_init.clone()).map_err(to_pyvalue_err)?;
1548        order_any_to_pyobject(py, order)
1549    }
1550}
1551
1552#[pymethods]
1553#[pyo3_stub_gen::derive::gen_stub_pymethods]
1554impl SubmitOrderList {
1555    #[getter]
1556    #[pyo3(name = "command_id")]
1557    fn py_command_id(&self) -> UUID4 {
1558        self.command_id
1559    }
1560
1561    #[getter]
1562    #[pyo3(name = "ts_init")]
1563    fn py_ts_init(&self) -> u64 {
1564        self.ts_init.as_u64()
1565    }
1566
1567    #[getter]
1568    #[pyo3(name = "correlation_id")]
1569    fn py_correlation_id(&self) -> Option<UUID4> {
1570        self.correlation_id
1571    }
1572
1573    #[getter]
1574    #[pyo3(name = "causation_id")]
1575    fn py_causation_id(&self) -> Option<UUID4> {
1576        self.causation_id
1577    }
1578
1579    #[getter]
1580    #[pyo3(name = "params")]
1581    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1582        self.params
1583            .as_ref()
1584            .map(|params| params_to_pydict(py, params))
1585            .transpose()
1586    }
1587
1588    #[getter]
1589    #[pyo3(name = "trader_id")]
1590    fn py_trader_id(&self) -> TraderId {
1591        self.trader_id
1592    }
1593
1594    #[getter]
1595    #[pyo3(name = "client_id")]
1596    fn py_client_id(&self) -> Option<ClientId> {
1597        self.client_id
1598    }
1599
1600    #[getter]
1601    #[pyo3(name = "strategy_id")]
1602    fn py_strategy_id(&self) -> StrategyId {
1603        self.strategy_id
1604    }
1605
1606    #[getter]
1607    #[pyo3(name = "instrument_id")]
1608    fn py_instrument_id(&self) -> InstrumentId {
1609        self.instrument_id
1610    }
1611
1612    #[getter]
1613    #[pyo3(name = "order_list")]
1614    fn py_order_list(&self) -> OrderList {
1615        self.order_list.clone()
1616    }
1617
1618    #[getter]
1619    #[pyo3(name = "order_inits")]
1620    fn py_order_inits(&self) -> Vec<OrderInitialized> {
1621        self.order_inits.clone()
1622    }
1623
1624    #[getter]
1625    #[pyo3(name = "exec_algorithm_id")]
1626    fn py_exec_algorithm_id(&self) -> Option<ExecAlgorithmId> {
1627        self.exec_algorithm_id
1628    }
1629
1630    #[getter]
1631    #[pyo3(name = "position_id")]
1632    fn py_position_id(&self) -> Option<PositionId> {
1633        self.position_id
1634    }
1635}
1636
1637#[pymethods]
1638#[pyo3_stub_gen::derive::gen_stub_pymethods]
1639impl ModifyOrder {
1640    #[getter]
1641    #[pyo3(name = "command_id")]
1642    fn py_command_id(&self) -> UUID4 {
1643        self.command_id
1644    }
1645
1646    #[getter]
1647    #[pyo3(name = "ts_init")]
1648    fn py_ts_init(&self) -> u64 {
1649        self.ts_init.as_u64()
1650    }
1651
1652    #[getter]
1653    #[pyo3(name = "correlation_id")]
1654    fn py_correlation_id(&self) -> Option<UUID4> {
1655        self.correlation_id
1656    }
1657
1658    #[getter]
1659    #[pyo3(name = "causation_id")]
1660    fn py_causation_id(&self) -> Option<UUID4> {
1661        self.causation_id
1662    }
1663
1664    #[getter]
1665    #[pyo3(name = "params")]
1666    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1667        self.params
1668            .as_ref()
1669            .map(|params| params_to_pydict(py, params))
1670            .transpose()
1671    }
1672
1673    #[getter]
1674    #[pyo3(name = "trader_id")]
1675    fn py_trader_id(&self) -> TraderId {
1676        self.trader_id
1677    }
1678
1679    #[getter]
1680    #[pyo3(name = "client_id")]
1681    fn py_client_id(&self) -> Option<ClientId> {
1682        self.client_id
1683    }
1684
1685    #[getter]
1686    #[pyo3(name = "strategy_id")]
1687    fn py_strategy_id(&self) -> StrategyId {
1688        self.strategy_id
1689    }
1690
1691    #[getter]
1692    #[pyo3(name = "instrument_id")]
1693    fn py_instrument_id(&self) -> InstrumentId {
1694        self.instrument_id
1695    }
1696
1697    #[getter]
1698    #[pyo3(name = "client_order_id")]
1699    fn py_client_order_id(&self) -> ClientOrderId {
1700        self.client_order_id
1701    }
1702
1703    #[getter]
1704    #[pyo3(name = "venue_order_id")]
1705    fn py_venue_order_id(&self) -> Option<VenueOrderId> {
1706        self.venue_order_id
1707    }
1708
1709    #[getter]
1710    #[pyo3(name = "quantity")]
1711    fn py_quantity(&self) -> Option<Quantity> {
1712        self.quantity
1713    }
1714
1715    #[getter]
1716    #[pyo3(name = "price")]
1717    fn py_price(&self) -> Option<Price> {
1718        self.price
1719    }
1720
1721    #[getter]
1722    #[pyo3(name = "trigger_price")]
1723    fn py_trigger_price(&self) -> Option<Price> {
1724        self.trigger_price
1725    }
1726}
1727
1728#[pymethods]
1729#[pyo3_stub_gen::derive::gen_stub_pymethods]
1730impl BatchModifyOrders {
1731    #[getter]
1732    #[pyo3(name = "command_id")]
1733    fn py_command_id(&self) -> UUID4 {
1734        self.command_id
1735    }
1736
1737    #[getter]
1738    #[pyo3(name = "ts_init")]
1739    fn py_ts_init(&self) -> u64 {
1740        self.ts_init.as_u64()
1741    }
1742
1743    #[getter]
1744    #[pyo3(name = "correlation_id")]
1745    fn py_correlation_id(&self) -> Option<UUID4> {
1746        self.correlation_id
1747    }
1748
1749    #[getter]
1750    #[pyo3(name = "causation_id")]
1751    fn py_causation_id(&self) -> Option<UUID4> {
1752        self.causation_id
1753    }
1754
1755    #[getter]
1756    #[pyo3(name = "params")]
1757    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1758        self.params
1759            .as_ref()
1760            .map(|params| params_to_pydict(py, params))
1761            .transpose()
1762    }
1763
1764    #[getter]
1765    #[pyo3(name = "trader_id")]
1766    fn py_trader_id(&self) -> TraderId {
1767        self.trader_id
1768    }
1769
1770    #[getter]
1771    #[pyo3(name = "client_id")]
1772    fn py_client_id(&self) -> Option<ClientId> {
1773        self.client_id
1774    }
1775
1776    #[getter]
1777    #[pyo3(name = "strategy_id")]
1778    fn py_strategy_id(&self) -> StrategyId {
1779        self.strategy_id
1780    }
1781
1782    #[getter]
1783    #[pyo3(name = "instrument_id")]
1784    fn py_instrument_id(&self) -> InstrumentId {
1785        self.instrument_id
1786    }
1787
1788    #[getter]
1789    #[pyo3(name = "modifies")]
1790    fn py_modifies(&self) -> Vec<ModifyOrder> {
1791        self.modifies.clone()
1792    }
1793}
1794
1795#[pymethods]
1796#[pyo3_stub_gen::derive::gen_stub_pymethods]
1797impl CancelOrder {
1798    #[getter]
1799    #[pyo3(name = "command_id")]
1800    fn py_command_id(&self) -> UUID4 {
1801        self.command_id
1802    }
1803
1804    #[getter]
1805    #[pyo3(name = "ts_init")]
1806    fn py_ts_init(&self) -> u64 {
1807        self.ts_init.as_u64()
1808    }
1809
1810    #[getter]
1811    #[pyo3(name = "correlation_id")]
1812    fn py_correlation_id(&self) -> Option<UUID4> {
1813        self.correlation_id
1814    }
1815
1816    #[getter]
1817    #[pyo3(name = "causation_id")]
1818    fn py_causation_id(&self) -> Option<UUID4> {
1819        self.causation_id
1820    }
1821
1822    #[getter]
1823    #[pyo3(name = "params")]
1824    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1825        self.params
1826            .as_ref()
1827            .map(|params| params_to_pydict(py, params))
1828            .transpose()
1829    }
1830
1831    #[getter]
1832    #[pyo3(name = "trader_id")]
1833    fn py_trader_id(&self) -> TraderId {
1834        self.trader_id
1835    }
1836
1837    #[getter]
1838    #[pyo3(name = "client_id")]
1839    fn py_client_id(&self) -> Option<ClientId> {
1840        self.client_id
1841    }
1842
1843    #[getter]
1844    #[pyo3(name = "strategy_id")]
1845    fn py_strategy_id(&self) -> StrategyId {
1846        self.strategy_id
1847    }
1848
1849    #[getter]
1850    #[pyo3(name = "instrument_id")]
1851    fn py_instrument_id(&self) -> InstrumentId {
1852        self.instrument_id
1853    }
1854
1855    #[getter]
1856    #[pyo3(name = "client_order_id")]
1857    fn py_client_order_id(&self) -> ClientOrderId {
1858        self.client_order_id
1859    }
1860
1861    #[getter]
1862    #[pyo3(name = "venue_order_id")]
1863    fn py_venue_order_id(&self) -> Option<VenueOrderId> {
1864        self.venue_order_id
1865    }
1866}
1867
1868#[pymethods]
1869#[pyo3_stub_gen::derive::gen_stub_pymethods]
1870impl CancelAllOrders {
1871    #[getter]
1872    #[pyo3(name = "command_id")]
1873    fn py_command_id(&self) -> UUID4 {
1874        self.command_id
1875    }
1876
1877    #[getter]
1878    #[pyo3(name = "ts_init")]
1879    fn py_ts_init(&self) -> u64 {
1880        self.ts_init.as_u64()
1881    }
1882
1883    #[getter]
1884    #[pyo3(name = "correlation_id")]
1885    fn py_correlation_id(&self) -> Option<UUID4> {
1886        self.correlation_id
1887    }
1888
1889    #[getter]
1890    #[pyo3(name = "causation_id")]
1891    fn py_causation_id(&self) -> Option<UUID4> {
1892        self.causation_id
1893    }
1894
1895    #[getter]
1896    #[pyo3(name = "params")]
1897    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1898        self.params
1899            .as_ref()
1900            .map(|params| params_to_pydict(py, params))
1901            .transpose()
1902    }
1903
1904    #[getter]
1905    #[pyo3(name = "trader_id")]
1906    fn py_trader_id(&self) -> TraderId {
1907        self.trader_id
1908    }
1909
1910    #[getter]
1911    #[pyo3(name = "client_id")]
1912    fn py_client_id(&self) -> Option<ClientId> {
1913        self.client_id
1914    }
1915
1916    #[getter]
1917    #[pyo3(name = "strategy_id")]
1918    fn py_strategy_id(&self) -> StrategyId {
1919        self.strategy_id
1920    }
1921
1922    #[getter]
1923    #[pyo3(name = "instrument_id")]
1924    fn py_instrument_id(&self) -> InstrumentId {
1925        self.instrument_id
1926    }
1927
1928    #[getter]
1929    #[pyo3(name = "order_side")]
1930    fn py_order_side(&self) -> Option<OrderSide> {
1931        self.order_side
1932    }
1933}
1934
1935#[pymethods]
1936#[pyo3_stub_gen::derive::gen_stub_pymethods]
1937impl BatchCancelOrders {
1938    #[getter]
1939    #[pyo3(name = "command_id")]
1940    fn py_command_id(&self) -> UUID4 {
1941        self.command_id
1942    }
1943
1944    #[getter]
1945    #[pyo3(name = "ts_init")]
1946    fn py_ts_init(&self) -> u64 {
1947        self.ts_init.as_u64()
1948    }
1949
1950    #[getter]
1951    #[pyo3(name = "correlation_id")]
1952    fn py_correlation_id(&self) -> Option<UUID4> {
1953        self.correlation_id
1954    }
1955
1956    #[getter]
1957    #[pyo3(name = "causation_id")]
1958    fn py_causation_id(&self) -> Option<UUID4> {
1959        self.causation_id
1960    }
1961
1962    #[getter]
1963    #[pyo3(name = "params")]
1964    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
1965        self.params
1966            .as_ref()
1967            .map(|params| params_to_pydict(py, params))
1968            .transpose()
1969    }
1970
1971    #[getter]
1972    #[pyo3(name = "trader_id")]
1973    fn py_trader_id(&self) -> TraderId {
1974        self.trader_id
1975    }
1976
1977    #[getter]
1978    #[pyo3(name = "client_id")]
1979    fn py_client_id(&self) -> Option<ClientId> {
1980        self.client_id
1981    }
1982
1983    #[getter]
1984    #[pyo3(name = "strategy_id")]
1985    fn py_strategy_id(&self) -> StrategyId {
1986        self.strategy_id
1987    }
1988
1989    #[getter]
1990    #[pyo3(name = "instrument_id")]
1991    fn py_instrument_id(&self) -> InstrumentId {
1992        self.instrument_id
1993    }
1994
1995    #[getter]
1996    #[pyo3(name = "cancels")]
1997    fn py_cancels(&self) -> Vec<CancelOrder> {
1998        self.cancels.clone()
1999    }
2000}
2001
2002#[pymethods]
2003#[pyo3_stub_gen::derive::gen_stub_pymethods]
2004impl QueryAccount {
2005    #[getter]
2006    #[pyo3(name = "command_id")]
2007    fn py_command_id(&self) -> UUID4 {
2008        self.command_id
2009    }
2010
2011    #[getter]
2012    #[pyo3(name = "ts_init")]
2013    fn py_ts_init(&self) -> u64 {
2014        self.ts_init.as_u64()
2015    }
2016
2017    #[getter]
2018    #[pyo3(name = "correlation_id")]
2019    fn py_correlation_id(&self) -> Option<UUID4> {
2020        self.correlation_id
2021    }
2022
2023    #[getter]
2024    #[pyo3(name = "causation_id")]
2025    fn py_causation_id(&self) -> Option<UUID4> {
2026        self.causation_id
2027    }
2028
2029    #[getter]
2030    #[pyo3(name = "params")]
2031    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
2032        self.params
2033            .as_ref()
2034            .map(|params| params_to_pydict(py, params))
2035            .transpose()
2036    }
2037
2038    #[getter]
2039    #[pyo3(name = "trader_id")]
2040    fn py_trader_id(&self) -> TraderId {
2041        self.trader_id
2042    }
2043
2044    #[getter]
2045    #[pyo3(name = "client_id")]
2046    fn py_client_id(&self) -> Option<ClientId> {
2047        self.client_id
2048    }
2049
2050    #[getter]
2051    #[pyo3(name = "account_id")]
2052    fn py_account_id(&self) -> AccountId {
2053        self.account_id
2054    }
2055}
2056
2057#[pymethods]
2058#[pyo3_stub_gen::derive::gen_stub_pymethods]
2059impl QueryOrder {
2060    #[getter]
2061    #[pyo3(name = "command_id")]
2062    fn py_command_id(&self) -> UUID4 {
2063        self.command_id
2064    }
2065
2066    #[getter]
2067    #[pyo3(name = "ts_init")]
2068    fn py_ts_init(&self) -> u64 {
2069        self.ts_init.as_u64()
2070    }
2071
2072    #[getter]
2073    #[pyo3(name = "correlation_id")]
2074    fn py_correlation_id(&self) -> Option<UUID4> {
2075        self.correlation_id
2076    }
2077
2078    #[getter]
2079    #[pyo3(name = "causation_id")]
2080    fn py_causation_id(&self) -> Option<UUID4> {
2081        self.causation_id
2082    }
2083
2084    #[getter]
2085    #[pyo3(name = "params")]
2086    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
2087        self.params
2088            .as_ref()
2089            .map(|params| params_to_pydict(py, params))
2090            .transpose()
2091    }
2092
2093    #[getter]
2094    #[pyo3(name = "trader_id")]
2095    fn py_trader_id(&self) -> TraderId {
2096        self.trader_id
2097    }
2098
2099    #[getter]
2100    #[pyo3(name = "client_id")]
2101    fn py_client_id(&self) -> Option<ClientId> {
2102        self.client_id
2103    }
2104
2105    #[getter]
2106    #[pyo3(name = "strategy_id")]
2107    fn py_strategy_id(&self) -> StrategyId {
2108        self.strategy_id
2109    }
2110
2111    #[getter]
2112    #[pyo3(name = "instrument_id")]
2113    fn py_instrument_id(&self) -> InstrumentId {
2114        self.instrument_id
2115    }
2116
2117    #[getter]
2118    #[pyo3(name = "client_order_id")]
2119    fn py_client_order_id(&self) -> ClientOrderId {
2120        self.client_order_id
2121    }
2122
2123    #[getter]
2124    #[pyo3(name = "venue_order_id")]
2125    fn py_venue_order_id(&self) -> Option<VenueOrderId> {
2126        self.venue_order_id
2127    }
2128}
2129
2130#[pymethods]
2131#[pyo3_stub_gen::derive::gen_stub_pymethods]
2132impl GenerateOrderStatusReport {
2133    #[getter]
2134    #[pyo3(name = "command_id")]
2135    fn py_command_id(&self) -> UUID4 {
2136        self.command_id
2137    }
2138
2139    #[getter]
2140    #[pyo3(name = "ts_init")]
2141    fn py_ts_init(&self) -> u64 {
2142        self.ts_init.as_u64()
2143    }
2144
2145    #[getter]
2146    #[pyo3(name = "correlation_id")]
2147    fn py_correlation_id(&self) -> Option<UUID4> {
2148        self.correlation_id
2149    }
2150
2151    #[getter]
2152    #[pyo3(name = "causation_id")]
2153    fn py_causation_id(&self) -> Option<UUID4> {
2154        self.causation_id
2155    }
2156
2157    #[getter]
2158    #[pyo3(name = "params")]
2159    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
2160        self.params
2161            .as_ref()
2162            .map(|params| params_to_pydict(py, params))
2163            .transpose()
2164    }
2165
2166    #[getter]
2167    #[pyo3(name = "instrument_id")]
2168    fn py_instrument_id(&self) -> Option<InstrumentId> {
2169        self.instrument_id
2170    }
2171
2172    #[getter]
2173    #[pyo3(name = "client_order_id")]
2174    fn py_client_order_id(&self) -> Option<ClientOrderId> {
2175        self.client_order_id
2176    }
2177
2178    #[getter]
2179    #[pyo3(name = "venue_order_id")]
2180    fn py_venue_order_id(&self) -> Option<VenueOrderId> {
2181        self.venue_order_id
2182    }
2183}
2184
2185#[pymethods]
2186#[pyo3_stub_gen::derive::gen_stub_pymethods]
2187impl GenerateOrderStatusReports {
2188    #[getter]
2189    #[pyo3(name = "command_id")]
2190    fn py_command_id(&self) -> UUID4 {
2191        self.command_id
2192    }
2193
2194    #[getter]
2195    #[pyo3(name = "ts_init")]
2196    fn py_ts_init(&self) -> u64 {
2197        self.ts_init.as_u64()
2198    }
2199
2200    #[getter]
2201    #[pyo3(name = "correlation_id")]
2202    fn py_correlation_id(&self) -> Option<UUID4> {
2203        self.correlation_id
2204    }
2205
2206    #[getter]
2207    #[pyo3(name = "causation_id")]
2208    fn py_causation_id(&self) -> Option<UUID4> {
2209        self.causation_id
2210    }
2211
2212    #[getter]
2213    #[pyo3(name = "params")]
2214    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
2215        self.params
2216            .as_ref()
2217            .map(|params| params_to_pydict(py, params))
2218            .transpose()
2219    }
2220
2221    #[getter]
2222    #[pyo3(name = "open_only")]
2223    fn py_open_only(&self) -> bool {
2224        self.open_only
2225    }
2226
2227    #[getter]
2228    #[pyo3(name = "instrument_id")]
2229    fn py_instrument_id(&self) -> Option<InstrumentId> {
2230        self.instrument_id
2231    }
2232
2233    #[getter]
2234    #[pyo3(name = "start")]
2235    fn py_start(&self) -> Option<u64> {
2236        self.start.map(|timestamp| timestamp.as_u64())
2237    }
2238
2239    #[getter]
2240    #[pyo3(name = "end")]
2241    fn py_end(&self) -> Option<u64> {
2242        self.end.map(|timestamp| timestamp.as_u64())
2243    }
2244
2245    #[getter]
2246    #[pyo3(name = "log_receipt_level")]
2247    fn py_log_receipt_level(&self) -> LogLevel {
2248        self.log_receipt_level
2249    }
2250}
2251
2252#[pymethods]
2253#[pyo3_stub_gen::derive::gen_stub_pymethods]
2254impl GenerateFillReports {
2255    #[getter]
2256    #[pyo3(name = "command_id")]
2257    fn py_command_id(&self) -> UUID4 {
2258        self.command_id
2259    }
2260
2261    #[getter]
2262    #[pyo3(name = "ts_init")]
2263    fn py_ts_init(&self) -> u64 {
2264        self.ts_init.as_u64()
2265    }
2266
2267    #[getter]
2268    #[pyo3(name = "correlation_id")]
2269    fn py_correlation_id(&self) -> Option<UUID4> {
2270        self.correlation_id
2271    }
2272
2273    #[getter]
2274    #[pyo3(name = "causation_id")]
2275    fn py_causation_id(&self) -> Option<UUID4> {
2276        self.causation_id
2277    }
2278
2279    #[getter]
2280    #[pyo3(name = "params")]
2281    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
2282        self.params
2283            .as_ref()
2284            .map(|params| params_to_pydict(py, params))
2285            .transpose()
2286    }
2287
2288    #[getter]
2289    #[pyo3(name = "instrument_id")]
2290    fn py_instrument_id(&self) -> Option<InstrumentId> {
2291        self.instrument_id
2292    }
2293
2294    #[getter]
2295    #[pyo3(name = "venue_order_id")]
2296    fn py_venue_order_id(&self) -> Option<VenueOrderId> {
2297        self.venue_order_id
2298    }
2299
2300    #[getter]
2301    #[pyo3(name = "start")]
2302    fn py_start(&self) -> Option<u64> {
2303        self.start.map(|timestamp| timestamp.as_u64())
2304    }
2305
2306    #[getter]
2307    #[pyo3(name = "end")]
2308    fn py_end(&self) -> Option<u64> {
2309        self.end.map(|timestamp| timestamp.as_u64())
2310    }
2311
2312    #[getter]
2313    #[pyo3(name = "log_receipt_level")]
2314    fn py_log_receipt_level(&self) -> LogLevel {
2315        self.log_receipt_level
2316    }
2317}
2318
2319#[pymethods]
2320#[pyo3_stub_gen::derive::gen_stub_pymethods]
2321impl GeneratePositionStatusReports {
2322    #[getter]
2323    #[pyo3(name = "command_id")]
2324    fn py_command_id(&self) -> UUID4 {
2325        self.command_id
2326    }
2327
2328    #[getter]
2329    #[pyo3(name = "ts_init")]
2330    fn py_ts_init(&self) -> u64 {
2331        self.ts_init.as_u64()
2332    }
2333
2334    #[getter]
2335    #[pyo3(name = "correlation_id")]
2336    fn py_correlation_id(&self) -> Option<UUID4> {
2337        self.correlation_id
2338    }
2339
2340    #[getter]
2341    #[pyo3(name = "causation_id")]
2342    fn py_causation_id(&self) -> Option<UUID4> {
2343        self.causation_id
2344    }
2345
2346    #[getter]
2347    #[pyo3(name = "params")]
2348    fn py_params(&self, py: Python<'_>) -> PyResult<Option<Py<PyDict>>> {
2349        self.params
2350            .as_ref()
2351            .map(|params| params_to_pydict(py, params))
2352            .transpose()
2353    }
2354
2355    #[getter]
2356    #[pyo3(name = "instrument_id")]
2357    fn py_instrument_id(&self) -> Option<InstrumentId> {
2358        self.instrument_id
2359    }
2360
2361    #[getter]
2362    #[pyo3(name = "start")]
2363    fn py_start(&self) -> Option<u64> {
2364        self.start.map(|timestamp| timestamp.as_u64())
2365    }
2366
2367    #[getter]
2368    #[pyo3(name = "end")]
2369    fn py_end(&self) -> Option<u64> {
2370        self.end.map(|timestamp| timestamp.as_u64())
2371    }
2372
2373    #[getter]
2374    #[pyo3(name = "log_receipt_level")]
2375    fn py_log_receipt_level(&self) -> LogLevel {
2376        self.log_receipt_level
2377    }
2378}
2379
2380#[cfg(test)]
2381mod tests {
2382    use nautilus_core::Params;
2383    use pyo3::{exceptions::PyAttributeError, types::PyList};
2384    use rstest::rstest;
2385
2386    use super::*;
2387
2388    #[rstest]
2389    #[case(Some(7), Some(19))]
2390    #[case(None, None)]
2391    fn test_subscription_getters_preserve_values_and_isolate_params(
2392        #[case] depth: Option<usize>,
2393        #[case] parameter: Option<i64>,
2394    ) {
2395        Python::initialize();
2396
2397        let params = parameter.map(|value| {
2398            let mut params = Params::default();
2399            params.insert("limit".to_owned(), serde_json::Value::from(value));
2400            params
2401        });
2402
2403        let command = SubscribeBookDepth::new(
2404            InstrumentId::from("AUD/USD.SIM"),
2405            BookType::L2_MBP,
2406            Some(ClientId::from("CLIENT")),
2407            Some(Venue::from("SIM")),
2408            UUID4::new(),
2409            9_007_199_254_740_993_u64.into(),
2410            depth.and_then(NonZero::new),
2411            true,
2412            Some(UUID4::new()),
2413            params,
2414        );
2415        Python::attach(|py| {
2416            let bound = Py::new(py, command.clone()).unwrap().into_bound(py);
2417            let values = bound.getattr("params").unwrap();
2418
2419            if let Some(parameter) = parameter {
2420                assert_eq!(
2421                    values.get_item("limit").unwrap().extract::<i64>().unwrap(),
2422                    parameter
2423                );
2424                values.set_item("limit", 999).unwrap();
2425                assert_eq!(
2426                    bound
2427                        .getattr("params")
2428                        .unwrap()
2429                        .get_item("limit")
2430                        .unwrap()
2431                        .extract::<i64>()
2432                        .unwrap(),
2433                    parameter
2434                );
2435            } else {
2436                assert!(values.is_none());
2437            }
2438
2439            assert_eq!(bound.get_type().name().unwrap(), "SubscribeBookDepth");
2440            assert_eq!(
2441                bound
2442                    .get_type()
2443                    .getattr("__module__")
2444                    .unwrap()
2445                    .extract::<String>()
2446                    .unwrap(),
2447                "nautilus_trader.live"
2448            );
2449            assert_eq!(
2450                bound
2451                    .getattr("instrument_id")
2452                    .unwrap()
2453                    .extract::<InstrumentId>()
2454                    .unwrap(),
2455                command.instrument_id
2456            );
2457            assert_eq!(
2458                bound
2459                    .getattr("client_id")
2460                    .unwrap()
2461                    .extract::<ClientId>()
2462                    .unwrap(),
2463                command.client_id.unwrap()
2464            );
2465            assert_eq!(
2466                bound.getattr("venue").unwrap().extract::<Venue>().unwrap(),
2467                command.venue.unwrap()
2468            );
2469            assert_eq!(
2470                bound
2471                    .getattr("book_type")
2472                    .unwrap()
2473                    .extract::<BookType>()
2474                    .unwrap(),
2475                command.book_type
2476            );
2477            assert_eq!(
2478                bound
2479                    .getattr("command_id")
2480                    .unwrap()
2481                    .extract::<UUID4>()
2482                    .unwrap(),
2483                command.command_id
2484            );
2485            assert_eq!(
2486                bound
2487                    .getattr("correlation_id")
2488                    .unwrap()
2489                    .extract::<UUID4>()
2490                    .unwrap(),
2491                command.correlation_id.unwrap()
2492            );
2493            assert_eq!(
2494                bound.getattr("ts_init").unwrap().extract::<u64>().unwrap(),
2495                9_007_199_254_740_993
2496            );
2497            assert_eq!(
2498                bound
2499                    .getattr("depth")
2500                    .unwrap()
2501                    .extract::<Option<usize>>()
2502                    .unwrap(),
2503                depth
2504            );
2505            assert!(bound.getattr("managed").unwrap().extract::<bool>().unwrap());
2506            assert!(
2507                bound
2508                    .setattr("ts_init", 1)
2509                    .unwrap_err()
2510                    .is_instance_of::<PyAttributeError>(py)
2511            );
2512        });
2513    }
2514
2515    #[rstest]
2516    fn test_batch_modify_getter_returns_owned_native_commands() {
2517        Python::initialize();
2518
2519        let first = ModifyOrder::new(
2520            TraderId::from("TRADER-001"),
2521            Some(ClientId::from("CLIENT")),
2522            StrategyId::from("STRATEGY-001"),
2523            InstrumentId::from("AUD/USD.SIM"),
2524            ClientOrderId::from("ORDER-001"),
2525            Some(VenueOrderId::from("VENUE-001")),
2526            Some(Quantity::from("3.25")),
2527            Some(Price::from("0.65123")),
2528            Some(Price::from("0.65234")),
2529            UUID4::new(),
2530            271.into(),
2531            None,
2532            Some(UUID4::new()),
2533        );
2534        let mut second = first.clone();
2535        second.client_order_id = ClientOrderId::from("ORDER-002");
2536        second.command_id = UUID4::new();
2537        second.ts_init = 283.into();
2538        second.causation_id = Some(UUID4::new());
2539        let expected = vec![first, second];
2540
2541        let batch = BatchModifyOrders::new(
2542            TraderId::from("TRADER-001"),
2543            Some(ClientId::from("CLIENT")),
2544            StrategyId::from("STRATEGY-001"),
2545            InstrumentId::from("AUD/USD.SIM"),
2546            expected.clone(),
2547            UUID4::new(),
2548            293.into(),
2549            None,
2550            Some(UUID4::new()),
2551        );
2552        Python::attach(|py| {
2553            let bound = Py::new(py, batch).unwrap().into_bound(py);
2554            let children = bound.getattr("modifies").unwrap();
2555            let children = children.cast::<PyList>().unwrap();
2556            assert_eq!(children.extract::<Vec<ModifyOrder>>().unwrap(), expected);
2557            let child = children.get_item(1).unwrap();
2558            assert_eq!(child.get_type().name().unwrap(), "ModifyOrder");
2559            assert_eq!(
2560                child.getattr("ts_init").unwrap().extract::<u64>().unwrap(),
2561                283
2562            );
2563            assert_eq!(
2564                child.getattr("price").unwrap().extract::<Price>().unwrap(),
2565                Price::from("0.65123")
2566            );
2567            assert_eq!(
2568                child
2569                    .getattr("trigger_price")
2570                    .unwrap()
2571                    .extract::<Price>()
2572                    .unwrap(),
2573                Price::from("0.65234")
2574            );
2575            assert_eq!(
2576                child
2577                    .getattr("quantity")
2578                    .unwrap()
2579                    .extract::<Quantity>()
2580                    .unwrap(),
2581                Quantity::from("3.25")
2582            );
2583            assert_eq!(
2584                child
2585                    .getattr("causation_id")
2586                    .unwrap()
2587                    .extract::<UUID4>()
2588                    .unwrap(),
2589                expected[1].causation_id.unwrap()
2590            );
2591            assert!(
2592                child
2593                    .setattr("price", Price::from("1.00"))
2594                    .unwrap_err()
2595                    .is_instance_of::<PyAttributeError>(py)
2596            );
2597            children.del_item(0).unwrap();
2598            assert_eq!(
2599                bound
2600                    .getattr("modifies")
2601                    .unwrap()
2602                    .extract::<Vec<ModifyOrder>>()
2603                    .unwrap(),
2604                expected
2605            );
2606        });
2607    }
2608}