Skip to main content

nautilus_bybit/python/
config.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 bindings for Bybit configuration.
17
18use nautilus_model::identifiers::AccountId;
19use nautilus_network::websocket::TransportBackend;
20use pyo3::pymethods;
21
22use crate::{
23    common::enums::{BybitEnvironment, BybitMarginMode, BybitProductType},
24    config::{BybitDataClientConfig, BybitExecutionClientConfig},
25};
26
27#[pymethods]
28#[pyo3_stub_gen::derive::gen_stub_pymethods]
29impl BybitDataClientConfig {
30    /// Configuration for the Bybit live data client.
31    #[new]
32    #[pyo3(signature = (
33        product_types = None,
34        environment = None,
35        api_key = None,
36        api_secret = None,
37        base_url_http = None,
38        base_url_ws_public = None,
39        base_url_ws_private = None,
40        proxy_url = None,
41        http_timeout_secs = None,
42        max_retries = None,
43        retry_delay_initial_ms = None,
44        retry_delay_max_ms = None,
45        heartbeat_interval_secs = None,
46        recv_window_ms = None,
47        update_instruments_interval_mins = None,
48        instrument_status_poll_secs = None,
49        transport_backend = None,
50    ))]
51    #[expect(clippy::too_many_arguments)]
52    fn py_new(
53        product_types: Option<Vec<BybitProductType>>,
54        environment: Option<BybitEnvironment>,
55        api_key: Option<String>,
56        api_secret: Option<String>,
57        base_url_http: Option<String>,
58        base_url_ws_public: Option<String>,
59        base_url_ws_private: Option<String>,
60        proxy_url: Option<String>,
61        http_timeout_secs: Option<u64>,
62        max_retries: Option<u32>,
63        retry_delay_initial_ms: Option<u64>,
64        retry_delay_max_ms: Option<u64>,
65        heartbeat_interval_secs: Option<u64>,
66        recv_window_ms: Option<u64>,
67        update_instruments_interval_mins: Option<u64>,
68        instrument_status_poll_secs: Option<u64>,
69        transport_backend: Option<TransportBackend>,
70    ) -> Self {
71        let defaults = Self::default();
72        Self {
73            api_key,
74            api_secret,
75            product_types: product_types.unwrap_or(defaults.product_types),
76            environment: environment.unwrap_or(defaults.environment),
77            base_url_http,
78            base_url_ws_public,
79            base_url_ws_private,
80            proxy_url,
81            http_timeout_secs: http_timeout_secs.unwrap_or(defaults.http_timeout_secs),
82            max_retries: max_retries.unwrap_or(defaults.max_retries),
83            retry_delay_initial_ms: retry_delay_initial_ms
84                .unwrap_or(defaults.retry_delay_initial_ms),
85            retry_delay_max_ms: retry_delay_max_ms.unwrap_or(defaults.retry_delay_max_ms),
86            heartbeat_interval_secs: heartbeat_interval_secs
87                .unwrap_or(defaults.heartbeat_interval_secs),
88            recv_window_ms: recv_window_ms.unwrap_or(defaults.recv_window_ms),
89            update_instruments_interval_mins: update_instruments_interval_mins
90                .or(defaults.update_instruments_interval_mins),
91            instrument_poll_interval_secs: instrument_status_poll_secs
92                .or(defaults.instrument_poll_interval_secs),
93            transport_backend: transport_backend.unwrap_or(defaults.transport_backend),
94        }
95    }
96
97    #[getter]
98    const fn instrument_status_poll_secs(&self) -> Option<u64> {
99        self.instrument_poll_interval_secs
100    }
101
102    #[getter]
103    const fn has_proxy_url(&self) -> bool {
104        self.proxy_url.is_some()
105    }
106
107    fn __repr__(&self) -> String {
108        stringify!(BybitDataClientConfig).to_string()
109    }
110}
111
112#[pymethods]
113#[pyo3_stub_gen::derive::gen_stub_pymethods]
114impl BybitExecutionClientConfig {
115    /// Configuration for the Bybit live execution client.
116    #[new]
117    #[pyo3(signature = (
118        product_types = None,
119        environment = None,
120        api_key = None,
121        api_secret = None,
122        base_url_http = None,
123        base_url_ws_private = None,
124        base_url_ws_trade = None,
125        proxy_url = None,
126        http_timeout_secs = None,
127        max_retries = None,
128        retry_delay_initial_ms = None,
129        retry_delay_max_ms = None,
130        heartbeat_interval_secs = None,
131        auth_timeout_secs = None,
132        recv_window_ms = None,
133        account_id = None,
134        use_spot_position_reports = None,
135        auto_repay_spot_borrows = None,
136        margin_mode = None,
137        transport_backend = None,
138    ))]
139    #[expect(clippy::too_many_arguments)]
140    fn py_new(
141        product_types: Option<Vec<BybitProductType>>,
142        environment: Option<BybitEnvironment>,
143        api_key: Option<String>,
144        api_secret: Option<String>,
145        base_url_http: Option<String>,
146        base_url_ws_private: Option<String>,
147        base_url_ws_trade: Option<String>,
148        proxy_url: Option<String>,
149        http_timeout_secs: Option<u64>,
150        max_retries: Option<u32>,
151        retry_delay_initial_ms: Option<u64>,
152        retry_delay_max_ms: Option<u64>,
153        heartbeat_interval_secs: Option<u64>,
154        auth_timeout_secs: Option<u64>,
155        recv_window_ms: Option<u64>,
156        account_id: Option<AccountId>,
157        use_spot_position_reports: Option<bool>,
158        auto_repay_spot_borrows: Option<bool>,
159        margin_mode: Option<BybitMarginMode>,
160        transport_backend: Option<TransportBackend>,
161    ) -> Self {
162        let defaults = Self::default();
163        Self {
164            api_key,
165            api_secret,
166            product_types: product_types.unwrap_or(defaults.product_types),
167            environment: environment.unwrap_or(defaults.environment),
168            base_url_http,
169            base_url_ws_private,
170            base_url_ws_trade,
171            proxy_url,
172            http_timeout_secs: http_timeout_secs.unwrap_or(defaults.http_timeout_secs),
173            max_retries: max_retries.unwrap_or(defaults.max_retries),
174            retry_delay_initial_ms: retry_delay_initial_ms
175                .unwrap_or(defaults.retry_delay_initial_ms),
176            retry_delay_max_ms: retry_delay_max_ms.unwrap_or(defaults.retry_delay_max_ms),
177            heartbeat_interval_secs: heartbeat_interval_secs
178                .unwrap_or(defaults.heartbeat_interval_secs),
179            auth_timeout_secs,
180            recv_window_ms: recv_window_ms.unwrap_or(defaults.recv_window_ms),
181            account_id,
182            use_spot_position_reports: use_spot_position_reports
183                .unwrap_or(defaults.use_spot_position_reports),
184            auto_repay_spot_borrows: auto_repay_spot_borrows
185                .unwrap_or(defaults.auto_repay_spot_borrows),
186            futures_leverages: None,
187            position_mode: None,
188            margin_mode,
189            transport_backend: transport_backend.unwrap_or(defaults.transport_backend),
190        }
191    }
192
193    #[getter]
194    const fn has_proxy_url(&self) -> bool {
195        self.proxy_url.is_some()
196    }
197
198    fn __repr__(&self) -> String {
199        stringify!(BybitExecutionClientConfig).to_string()
200    }
201}