1use nautilus_model::identifiers::{AccountId, TraderId};
19use pyo3::prelude::*;
20
21use crate::{
22 common::enums::{OKXEnvironment, OKXInstrumentType, OKXMarginMode, OKXRegion, OKXVipLevel},
23 config::{OKXDataClientConfig, OKXExecClientConfig},
24};
25
26#[pymethods]
27#[pyo3_stub_gen::derive::gen_stub_pymethods]
28impl OKXDataClientConfig {
29 #[new]
31 #[pyo3(signature = (
32 instrument_types = None,
33 environment = None,
34 region = None,
35 api_key = None,
36 api_secret = None,
37 api_passphrase = None,
38 base_url_http = None,
39 base_url_ws_public = None,
40 base_url_ws_business = None,
41 proxy_url = None,
42 http_timeout_secs = None,
43 max_retries = None,
44 retry_delay_initial_ms = None,
45 retry_delay_max_ms = None,
46 update_instruments_interval_mins = None,
47 vip_level = None,
48 load_spreads = false,
49 ))]
50 #[expect(clippy::too_many_arguments)]
51 fn py_new(
52 instrument_types: Option<Vec<OKXInstrumentType>>,
53 environment: Option<OKXEnvironment>,
54 region: Option<OKXRegion>,
55 api_key: Option<String>,
56 api_secret: Option<String>,
57 api_passphrase: Option<String>,
58 base_url_http: Option<String>,
59 base_url_ws_public: Option<String>,
60 base_url_ws_business: Option<String>,
61 proxy_url: Option<String>,
62 http_timeout_secs: Option<u64>,
63 max_retries: Option<u32>,
64 retry_delay_initial_ms: Option<u64>,
65 retry_delay_max_ms: Option<u64>,
66 update_instruments_interval_mins: Option<u64>,
67 vip_level: Option<OKXVipLevel>,
68 load_spreads: bool,
69 ) -> Self {
70 let defaults = Self::default();
71 Self {
72 api_key,
73 api_secret,
74 api_passphrase,
75 instrument_types: instrument_types.unwrap_or(defaults.instrument_types),
76 contract_types: None,
77 load_spreads,
78 instrument_families: None,
79 base_url_http,
80 base_url_ws_public,
81 base_url_ws_business,
82 proxy_url,
83 environment: environment.unwrap_or(defaults.environment),
84 region: region.unwrap_or(defaults.region),
85 http_timeout_secs: http_timeout_secs.unwrap_or(defaults.http_timeout_secs),
86 max_retries: max_retries.unwrap_or(defaults.max_retries),
87 retry_delay_initial_ms: retry_delay_initial_ms
88 .unwrap_or(defaults.retry_delay_initial_ms),
89 retry_delay_max_ms: retry_delay_max_ms.unwrap_or(defaults.retry_delay_max_ms),
90 update_instruments_interval_mins: update_instruments_interval_mins
91 .unwrap_or(defaults.update_instruments_interval_mins),
92 vip_level,
93 transport_backend: defaults.transport_backend,
94 }
95 }
96
97 fn __repr__(&self) -> String {
98 format!("{self:?}")
99 }
100}
101
102#[pymethods]
103#[pyo3_stub_gen::derive::gen_stub_pymethods]
104impl OKXExecClientConfig {
105 #[new]
107 #[pyo3(signature = (
108 trader_id,
109 account_id,
110 instrument_types = None,
111 environment = None,
112 region = None,
113 api_key = None,
114 api_secret = None,
115 api_passphrase = None,
116 base_url_http = None,
117 base_url_ws_private = None,
118 base_url_ws_business = None,
119 proxy_url = None,
120 http_timeout_secs = None,
121 max_retries = None,
122 retry_delay_initial_ms = None,
123 retry_delay_max_ms = None,
124 margin_mode = None,
125 load_spreads = false,
126 ))]
127 #[expect(clippy::too_many_arguments)]
128 fn py_new(
129 trader_id: TraderId,
130 account_id: AccountId,
131 instrument_types: Option<Vec<OKXInstrumentType>>,
132 environment: Option<OKXEnvironment>,
133 region: Option<OKXRegion>,
134 api_key: Option<String>,
135 api_secret: Option<String>,
136 api_passphrase: Option<String>,
137 base_url_http: Option<String>,
138 base_url_ws_private: Option<String>,
139 base_url_ws_business: Option<String>,
140 proxy_url: Option<String>,
141 http_timeout_secs: Option<u64>,
142 max_retries: Option<u32>,
143 retry_delay_initial_ms: Option<u64>,
144 retry_delay_max_ms: Option<u64>,
145 margin_mode: Option<OKXMarginMode>,
146 load_spreads: bool,
147 ) -> Self {
148 let defaults = Self::default();
149 Self {
150 trader_id,
151 account_id,
152 api_key,
153 api_secret,
154 api_passphrase,
155 instrument_types: instrument_types.unwrap_or(defaults.instrument_types),
156 contract_types: None,
157 instrument_families: None,
158 base_url_http,
159 base_url_ws_private,
160 base_url_ws_business,
161 proxy_url,
162 environment: environment.unwrap_or(defaults.environment),
163 region: region.unwrap_or(defaults.region),
164 http_timeout_secs: http_timeout_secs.unwrap_or(defaults.http_timeout_secs),
165 use_fills_channel: defaults.use_fills_channel,
166 use_mm_mass_cancel: defaults.use_mm_mass_cancel,
167 max_retries: max_retries.unwrap_or(defaults.max_retries),
168 retry_delay_initial_ms: retry_delay_initial_ms
169 .unwrap_or(defaults.retry_delay_initial_ms),
170 retry_delay_max_ms: retry_delay_max_ms.unwrap_or(defaults.retry_delay_max_ms),
171 margin_mode,
172 load_spreads,
173 use_spot_margin: defaults.use_spot_margin,
174 transport_backend: defaults.transport_backend,
175 }
176 }
177
178 fn __repr__(&self) -> String {
179 format!("{self:?}")
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use rstest::rstest;
186
187 use super::*;
188
189 #[rstest]
190 fn test_data_config_py_new_load_spreads() {
191 let config = OKXDataClientConfig::py_new(
192 None, None, None, None, None, None, None, None, None, None, None, None, None, None,
193 None, None, true,
194 );
195
196 assert!(config.load_spreads);
197 }
198
199 #[rstest]
200 fn test_exec_config_py_new_load_spreads() {
201 let config = OKXExecClientConfig::py_new(
202 TraderId::from("TRADER-001"),
203 AccountId::from("OKX-001"),
204 None,
205 None,
206 None,
207 None,
208 None,
209 None,
210 None,
211 None,
212 None,
213 None,
214 None,
215 None,
216 None,
217 None,
218 None,
219 true,
220 );
221
222 assert!(config.load_spreads);
223 }
224}