nautilus_bitmex/python/
mod.rs1pub mod canceller;
19pub mod config;
20pub mod enums;
21pub mod factories;
22pub mod http;
23pub mod submitter;
24pub mod urls;
25pub mod websocket;
26
27use nautilus_common::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
28use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
29use nautilus_system::get_global_pyo3_registry;
30use pyo3::prelude::*;
31
32use crate::{
33 common::consts::BITMEX,
34 config::{BitmexDataClientConfig, BitmexExecClientConfig},
35 factories::{BitmexDataClientFactory, BitmexExecFactoryConfig, BitmexExecutionClientFactory},
36};
37
38#[expect(clippy::needless_pass_by_value)]
39fn extract_bitmex_data_factory(
40 py: Python<'_>,
41 factory: Py<PyAny>,
42) -> PyResult<Box<dyn DataClientFactory>> {
43 match factory.extract::<BitmexDataClientFactory>(py) {
44 Ok(f) => Ok(Box::new(f)),
45 Err(e) => Err(to_pyvalue_err(format!(
46 "Failed to extract BitmexDataClientFactory: {e}"
47 ))),
48 }
49}
50
51#[expect(clippy::needless_pass_by_value)]
52fn extract_bitmex_exec_factory(
53 py: Python<'_>,
54 factory: Py<PyAny>,
55) -> PyResult<Box<dyn ExecutionClientFactory>> {
56 match factory.extract::<BitmexExecutionClientFactory>(py) {
57 Ok(f) => Ok(Box::new(f)),
58 Err(e) => Err(to_pyvalue_err(format!(
59 "Failed to extract BitmexExecutionClientFactory: {e}"
60 ))),
61 }
62}
63
64#[expect(clippy::needless_pass_by_value)]
65fn extract_bitmex_data_config(
66 py: Python<'_>,
67 config: Py<PyAny>,
68) -> PyResult<Box<dyn ClientConfig>> {
69 match config.extract::<BitmexDataClientConfig>(py) {
70 Ok(c) => Ok(Box::new(c)),
71 Err(e) => Err(to_pyvalue_err(format!(
72 "Failed to extract BitmexDataClientConfig: {e}"
73 ))),
74 }
75}
76
77#[expect(clippy::needless_pass_by_value)]
78fn extract_bitmex_exec_config(
79 py: Python<'_>,
80 config: Py<PyAny>,
81) -> PyResult<Box<dyn ClientConfig>> {
82 match config.extract::<BitmexExecFactoryConfig>(py) {
83 Ok(c) => Ok(Box::new(c)),
84 Err(e) => Err(to_pyvalue_err(format!(
85 "Failed to extract BitmexExecFactoryConfig: {e}"
86 ))),
87 }
88}
89
90#[pymodule]
96pub fn bitmex(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
97 m.add("BITMEX_HTTP_URL", crate::common::consts::BITMEX_HTTP_URL)?;
98 m.add("BITMEX_WS_URL", crate::common::consts::BITMEX_WS_URL)?;
99 m.add_class::<crate::common::enums::BitmexEnvironment>()?;
100 m.add_class::<crate::http::client::BitmexHttpClient>()?;
101 m.add_class::<crate::broadcast::canceller::CancelBroadcaster>()?;
102 m.add_class::<crate::broadcast::submitter::SubmitBroadcaster>()?;
103 m.add_class::<websocket::PyBitmexWebSocketClient>()?;
104 m.add_class::<BitmexDataClientConfig>()?;
105 m.add_class::<BitmexExecClientConfig>()?;
106 m.add_class::<BitmexExecFactoryConfig>()?;
107 m.add_class::<BitmexDataClientFactory>()?;
108 m.add_class::<BitmexExecutionClientFactory>()?;
109 m.add_function(wrap_pyfunction!(urls::get_bitmex_http_base_url, m)?)?;
110 m.add_function(wrap_pyfunction!(urls::get_bitmex_ws_url, m)?)?;
111
112 let registry = get_global_pyo3_registry();
113
114 if let Err(e) =
115 registry.register_factory_extractor(BITMEX.to_string(), extract_bitmex_data_factory)
116 {
117 return Err(to_pyruntime_err(format!(
118 "Failed to register BitMEX data factory extractor: {e}"
119 )));
120 }
121
122 if let Err(e) =
123 registry.register_exec_factory_extractor(BITMEX.to_string(), extract_bitmex_exec_factory)
124 {
125 return Err(to_pyruntime_err(format!(
126 "Failed to register BitMEX exec factory extractor: {e}"
127 )));
128 }
129
130 if let Err(e) = registry.register_config_extractor(
131 "BitmexDataClientConfig".to_string(),
132 extract_bitmex_data_config,
133 ) {
134 return Err(to_pyruntime_err(format!(
135 "Failed to register BitMEX data config extractor: {e}"
136 )));
137 }
138
139 if let Err(e) = registry.register_config_extractor(
140 "BitmexExecFactoryConfig".to_string(),
141 extract_bitmex_exec_config,
142 ) {
143 return Err(to_pyruntime_err(format!(
144 "Failed to register BitMEX exec config extractor: {e}"
145 )));
146 }
147
148 Ok(())
149}