nautilus_binance/python/
mod.rs1pub mod arrow;
19pub mod config;
20pub mod enums;
21pub mod factories;
22pub mod types;
23
24mod data;
25mod instruments;
26
27use nautilus_common::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
28use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
29use nautilus_model::data::ensure_rust_extractor_registered;
30use nautilus_serialization::ensure_custom_data_registered;
31use nautilus_system::get_global_pyo3_registry;
32use pyo3::prelude::*;
33
34use crate::{
35 common::{
36 bar::BinanceBar,
37 consts::{
38 BINANCE, BINANCE_CLIENT_ID, BINANCE_NAUTILUS_FUTURES_BROKER_ID,
39 BINANCE_NAUTILUS_SPOT_BROKER_ID, BINANCE_VENUE,
40 },
41 encoder::decode_broker_id,
42 enums::{BinanceEnvironment, BinanceMarginType, BinancePositionSide, BinanceProductType},
43 },
44 config::{
45 BinanceDataClientConfig, BinanceExecutionClientConfig, BinanceInstrumentProviderConfig,
46 BinanceSpotMarketDataMode,
47 },
48 data_types::{
49 BinanceFuturesLiquidation, BinanceFuturesMarkPriceUpdate, BinanceFuturesOpenInterest,
50 BinanceFuturesOpenInterestHist, BinanceFuturesOpenInterestHistPoint, BinanceFuturesTicker,
51 BinanceSpotTicker, register_binance_custom_data,
52 },
53 factories::{BinanceDataClientFactory, BinanceExecutionClientFactory},
54};
55
56#[expect(clippy::needless_pass_by_value)]
57fn extract_binance_data_factory(
58 py: Python<'_>,
59 factory: Py<PyAny>,
60) -> PyResult<Box<dyn DataClientFactory>> {
61 match factory.extract::<BinanceDataClientFactory>(py) {
62 Ok(f) => Ok(Box::new(f)),
63 Err(e) => Err(to_pyvalue_err(format!(
64 "Failed to extract BinanceDataClientFactory: {e}"
65 ))),
66 }
67}
68
69#[expect(clippy::needless_pass_by_value)]
70fn extract_binance_exec_factory(
71 py: Python<'_>,
72 factory: Py<PyAny>,
73) -> PyResult<Box<dyn ExecutionClientFactory>> {
74 match factory.extract::<BinanceExecutionClientFactory>(py) {
75 Ok(f) => Ok(Box::new(f)),
76 Err(e) => Err(to_pyvalue_err(format!(
77 "Failed to extract BinanceExecutionClientFactory: {e}"
78 ))),
79 }
80}
81
82#[expect(clippy::needless_pass_by_value)]
83fn extract_binance_data_config(
84 py: Python<'_>,
85 config: Py<PyAny>,
86) -> PyResult<Box<dyn ClientConfig>> {
87 match config.extract::<BinanceDataClientConfig>(py) {
88 Ok(c) => Ok(Box::new(c)),
89 Err(e) => Err(to_pyvalue_err(format!(
90 "Failed to extract BinanceDataClientConfig: {e}"
91 ))),
92 }
93}
94
95#[expect(clippy::needless_pass_by_value)]
96fn extract_binance_exec_config(
97 py: Python<'_>,
98 config: Py<PyAny>,
99) -> PyResult<Box<dyn ClientConfig>> {
100 match config.extract::<BinanceExecutionClientConfig>(py) {
101 Ok(c) => Ok(Box::new(c)),
102 Err(e) => Err(to_pyvalue_err(format!(
103 "Failed to extract BinanceExecutionClientConfig: {e}"
104 ))),
105 }
106}
107
108#[pyfunction]
116#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.adapters.binance")]
117#[pyo3(name = "decode_binance_spot_client_order_id")]
118fn py_decode_binance_spot_client_order_id(encoded: &str) -> String {
119 decode_broker_id(encoded, BINANCE_NAUTILUS_SPOT_BROKER_ID)
120}
121
122#[pyfunction]
130#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.adapters.binance")]
131#[pyo3(name = "decode_binance_futures_client_order_id")]
132fn py_decode_binance_futures_client_order_id(encoded: &str) -> String {
133 decode_broker_id(encoded, BINANCE_NAUTILUS_FUTURES_BROKER_ID)
134}
135
136#[pymodule]
144pub fn binance(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
145 m.add(stringify!(BINANCE), BINANCE)?;
146 m.add(stringify!(BINANCE_CLIENT_ID), *BINANCE_CLIENT_ID)?;
147 m.add(stringify!(BINANCE_VENUE), *BINANCE_VENUE)?;
148 m.add_class::<BinanceProductType>()?;
149 m.add_class::<BinanceEnvironment>()?;
150 m.add_class::<BinanceMarginType>()?;
151 m.add_class::<BinancePositionSide>()?;
152 m.add_class::<BinanceBar>()?;
153 m.add_class::<BinanceFuturesLiquidation>()?;
154 m.add_class::<BinanceFuturesTicker>()?;
155 m.add_class::<BinanceSpotTicker>()?;
156 m.add_class::<BinanceFuturesMarkPriceUpdate>()?;
157 m.add_class::<BinanceFuturesOpenInterest>()?;
158 m.add_class::<BinanceFuturesOpenInterestHistPoint>()?;
159 m.add_class::<BinanceFuturesOpenInterestHist>()?;
160 m.add_function(wrap_pyfunction!(arrow::get_binance_arrow_schema_map, m)?)?;
161 m.add_function(wrap_pyfunction!(
162 arrow::py_binance_bar_to_arrow_record_batch_bytes,
163 m
164 )?)?;
165 m.add_function(wrap_pyfunction!(
166 arrow::py_binance_bar_from_arrow_record_batch_bytes,
167 m
168 )?)?;
169 m.add_class::<BinanceDataClientConfig>()?;
170 m.add_class::<BinanceDataClientFactory>()?;
171 m.add_class::<BinanceExecutionClientConfig>()?;
172 m.add_class::<BinanceExecutionClientFactory>()?;
173 m.add_class::<BinanceInstrumentProviderConfig>()?;
174 m.add_class::<BinanceSpotMarketDataMode>()?;
175 m.add_function(wrap_pyfunction!(py_decode_binance_spot_client_order_id, m)?)?;
176 m.add_function(wrap_pyfunction!(
177 py_decode_binance_futures_client_order_id,
178 m
179 )?)?;
180 m.add_function(wrap_pyfunction!(
181 instruments::py_load_binance_instruments,
182 m
183 )?)?;
184 m.add_function(wrap_pyfunction!(
185 data::py_load_binance_order_book_deltas,
186 m
187 )?)?;
188
189 ensure_custom_data_registered::<BinanceBar>();
191 let _result = ensure_rust_extractor_registered::<BinanceBar>();
192 register_binance_custom_data();
193 let _result = ensure_rust_extractor_registered::<BinanceFuturesLiquidation>();
194 let _result = ensure_rust_extractor_registered::<BinanceFuturesTicker>();
195 let _result = ensure_rust_extractor_registered::<BinanceSpotTicker>();
196 let _result = ensure_rust_extractor_registered::<BinanceFuturesMarkPriceUpdate>();
197 let _result = ensure_rust_extractor_registered::<BinanceFuturesOpenInterest>();
198 let _result = ensure_rust_extractor_registered::<BinanceFuturesOpenInterestHist>();
199
200 let registry = get_global_pyo3_registry();
201
202 if let Err(e) =
203 registry.register_factory_extractor(BINANCE.to_string(), extract_binance_data_factory)
204 {
205 return Err(to_pyruntime_err(format!(
206 "Failed to register Binance data factory extractor: {e}"
207 )));
208 }
209
210 if let Err(e) =
211 registry.register_exec_factory_extractor(BINANCE.to_string(), extract_binance_exec_factory)
212 {
213 return Err(to_pyruntime_err(format!(
214 "Failed to register Binance exec factory extractor: {e}"
215 )));
216 }
217
218 if let Err(e) = registry.register_config_extractor(
219 "BinanceDataClientConfig".to_string(),
220 extract_binance_data_config,
221 ) {
222 return Err(to_pyruntime_err(format!(
223 "Failed to register Binance data config extractor: {e}"
224 )));
225 }
226
227 if let Err(e) = registry.register_config_extractor(
228 "BinanceExecutionClientConfig".to_string(),
229 extract_binance_exec_config,
230 ) {
231 return Err(to_pyruntime_err(format!(
232 "Failed to register Binance exec config extractor: {e}"
233 )));
234 }
235
236 Ok(())
237}