nautilus_kraken/python/
mod.rs1#![expect(
19 clippy::missing_errors_doc,
20 reason = "errors documented on underlying Rust methods"
21)]
22
23use nautilus_common::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
24use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
25use nautilus_system::get_global_pyo3_registry;
26use pyo3::prelude::*;
27
28use crate::{
29 common::{
30 consts::{KRAKEN, KRAKEN_CLIENT_ID, KRAKEN_VENUE},
31 enums::{KrakenEnvironment, KrakenProductType},
32 },
33 config::{KrakenDataClientConfig, KrakenExecutionClientConfig},
34 factories::{KrakenDataClientFactory, KrakenExecutionClientFactory},
35 http::{KrakenFuturesHttpClient, KrakenSpotHttpClient},
36};
37
38pub mod config;
39pub mod factories;
40pub mod http_futures;
41pub mod http_spot;
42
43#[pyfunction]
53#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.adapters.kraken")]
54#[pyo3(name = "kraken_product_type_from_symbol")]
55fn py_kraken_product_type_from_symbol(symbol: &str) -> KrakenProductType {
56 crate::common::enums::product_type_from_symbol(symbol)
57}
58
59#[expect(clippy::needless_pass_by_value)]
60fn extract_kraken_data_factory(
61 py: Python<'_>,
62 factory: Py<PyAny>,
63) -> PyResult<Box<dyn DataClientFactory>> {
64 match factory.extract::<KrakenDataClientFactory>(py) {
65 Ok(f) => Ok(Box::new(f)),
66 Err(e) => Err(to_pyvalue_err(format!(
67 "Failed to extract KrakenDataClientFactory: {e}"
68 ))),
69 }
70}
71
72#[expect(clippy::needless_pass_by_value)]
73fn extract_kraken_exec_factory(
74 py: Python<'_>,
75 factory: Py<PyAny>,
76) -> PyResult<Box<dyn ExecutionClientFactory>> {
77 match factory.extract::<KrakenExecutionClientFactory>(py) {
78 Ok(f) => Ok(Box::new(f)),
79 Err(e) => Err(to_pyvalue_err(format!(
80 "Failed to extract KrakenExecutionClientFactory: {e}"
81 ))),
82 }
83}
84
85#[expect(clippy::needless_pass_by_value)]
86fn extract_kraken_data_config(
87 py: Python<'_>,
88 config: Py<PyAny>,
89) -> PyResult<Box<dyn ClientConfig>> {
90 match config.extract::<KrakenDataClientConfig>(py) {
91 Ok(c) => Ok(Box::new(c)),
92 Err(e) => Err(to_pyvalue_err(format!(
93 "Failed to extract KrakenDataClientConfig: {e}"
94 ))),
95 }
96}
97
98#[expect(clippy::needless_pass_by_value)]
99fn extract_kraken_exec_config(
100 py: Python<'_>,
101 config: Py<PyAny>,
102) -> PyResult<Box<dyn ClientConfig>> {
103 match config.extract::<KrakenExecutionClientConfig>(py) {
104 Ok(c) => Ok(Box::new(c)),
105 Err(e) => Err(to_pyvalue_err(format!(
106 "Failed to extract KrakenExecutionClientConfig: {e}"
107 ))),
108 }
109}
110
111#[pymodule]
112pub fn kraken(m: &Bound<'_, PyModule>) -> PyResult<()> {
113 m.add(stringify!(KRAKEN), KRAKEN)?;
114 m.add(stringify!(KRAKEN_CLIENT_ID), *KRAKEN_CLIENT_ID)?;
115 m.add(stringify!(KRAKEN_VENUE), *KRAKEN_VENUE)?;
116 m.add_class::<KrakenEnvironment>()?;
117 m.add_class::<KrakenProductType>()?;
118 m.add_class::<KrakenSpotHttpClient>()?;
119 m.add_class::<KrakenFuturesHttpClient>()?;
120 m.add_class::<KrakenDataClientConfig>()?;
121 m.add_class::<KrakenDataClientFactory>()?;
122 m.add_class::<KrakenExecutionClientConfig>()?;
123 m.add_class::<KrakenExecutionClientFactory>()?;
124 m.add_function(wrap_pyfunction!(py_kraken_product_type_from_symbol, m)?)?;
125
126 let registry = get_global_pyo3_registry();
127
128 if let Err(e) =
129 registry.register_factory_extractor(KRAKEN.to_string(), extract_kraken_data_factory)
130 {
131 return Err(to_pyruntime_err(format!(
132 "Failed to register Kraken data factory extractor: {e}"
133 )));
134 }
135
136 if let Err(e) =
137 registry.register_exec_factory_extractor(KRAKEN.to_string(), extract_kraken_exec_factory)
138 {
139 return Err(to_pyruntime_err(format!(
140 "Failed to register Kraken exec factory extractor: {e}"
141 )));
142 }
143
144 if let Err(e) = registry.register_config_extractor(
145 "KrakenDataClientConfig".to_string(),
146 extract_kraken_data_config,
147 ) {
148 return Err(to_pyruntime_err(format!(
149 "Failed to register Kraken data config extractor: {e}"
150 )));
151 }
152
153 if let Err(e) = registry.register_config_extractor(
154 "KrakenExecutionClientConfig".to_string(),
155 extract_kraken_exec_config,
156 ) {
157 return Err(to_pyruntime_err(format!(
158 "Failed to register Kraken exec config extractor: {e}"
159 )));
160 }
161
162 Ok(())
163}