nautilus_bybit/python/
enums.rs1use std::str::FromStr;
19
20use nautilus_core::python::to_pyvalue_err;
21use pyo3::{PyTypeInfo, prelude::*, types::PyType};
22use strum::IntoEnumIterator;
23
24use crate::common::enums::{
25 BybitAccountType, BybitEnvironment, BybitMarginAction, BybitMarginMode, BybitPositionMode,
26 BybitProductType,
27};
28
29#[pymethods]
30impl BybitProductType {
31 #[new]
32 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
33 let t = Self::type_object(py);
34 Self::py_from_str(&t, value)
35 }
36
37 fn __hash__(&self) -> isize {
38 *self as isize
39 }
40
41 fn __repr__(&self) -> String {
42 format!(
43 "<{}.{}: '{}'>",
44 stringify!(BybitProductType),
45 self.name(),
46 self.value(),
47 )
48 }
49
50 fn __str__(&self) -> String {
51 self.to_string()
52 }
53
54 #[getter]
55 #[must_use]
56 pub fn name(&self) -> &str {
57 self.as_ref()
58 }
59
60 #[getter]
61 #[must_use]
62 pub fn value(&self) -> String {
63 self.to_string().to_lowercase()
64 }
65
66 #[staticmethod]
67 #[must_use]
68 fn variants() -> Vec<String> {
69 Self::iter().map(|x| x.to_string()).collect()
70 }
71
72 #[classmethod]
73 #[pyo3(name = "from_str")]
74 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
75 let data_str: String = data.str()?.extract()?;
76 Self::from_str(&data_str).map_err(to_pyvalue_err)
77 }
78
79 #[classattr]
80 #[pyo3(name = "SPOT")]
81 fn py_spot() -> Self {
82 Self::Spot
83 }
84
85 #[classattr]
86 #[pyo3(name = "LINEAR")]
87 fn py_linear() -> Self {
88 Self::Linear
89 }
90
91 #[classattr]
92 #[pyo3(name = "INVERSE")]
93 fn py_inverse() -> Self {
94 Self::Inverse
95 }
96
97 #[classattr]
98 #[pyo3(name = "OPTION")]
99 fn py_option() -> Self {
100 Self::Option
101 }
102}
103
104#[pymethods]
105impl BybitEnvironment {
106 #[new]
107 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
108 let t = Self::type_object(py);
109 Self::py_from_str(&t, value)
110 }
111
112 fn __hash__(&self) -> isize {
113 *self as isize
114 }
115
116 fn __repr__(&self) -> String {
117 format!(
118 "<{}.{}: {}>",
119 stringify!(BybitEnvironment),
120 self.name(),
121 *self as u8,
122 )
123 }
124
125 fn __str__(&self) -> String {
126 self.to_string()
127 }
128
129 #[getter]
130 #[must_use]
131 pub fn name(&self) -> &str {
132 self.as_ref()
133 }
134
135 #[getter]
136 #[must_use]
137 pub fn value(&self) -> String {
138 self.to_string().to_lowercase()
139 }
140
141 #[staticmethod]
142 #[must_use]
143 fn variants() -> Vec<String> {
144 Self::iter().map(|x| x.to_string()).collect()
145 }
146
147 #[classmethod]
148 #[pyo3(name = "from_str")]
149 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
150 let data_str: String = data.str()?.extract()?;
151 Self::from_str(&data_str).map_err(to_pyvalue_err)
152 }
153
154 #[classattr]
155 #[pyo3(name = "MAINNET")]
156 fn py_mainnet() -> Self {
157 Self::Mainnet
158 }
159
160 #[classattr]
161 #[pyo3(name = "DEMO")]
162 fn py_demo() -> Self {
163 Self::Demo
164 }
165
166 #[classattr]
167 #[pyo3(name = "TESTNET")]
168 fn py_testnet() -> Self {
169 Self::Testnet
170 }
171}
172
173#[pymethods]
174impl BybitAccountType {
175 #[new]
176 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
177 let t = Self::type_object(py);
178 Self::py_from_str(&t, value)
179 }
180
181 fn __hash__(&self) -> isize {
182 *self as isize
183 }
184
185 fn __repr__(&self) -> String {
186 format!(
187 "<{}.{}: {}>",
188 stringify!(BybitAccountType),
189 self.name(),
190 *self as u8,
191 )
192 }
193
194 fn __str__(&self) -> String {
195 self.to_string()
196 }
197
198 #[getter]
199 #[must_use]
200 pub fn name(&self) -> &str {
201 self.as_ref()
202 }
203
204 #[getter]
205 #[must_use]
206 pub fn value(&self) -> String {
207 self.to_string().to_uppercase()
208 }
209
210 #[staticmethod]
211 #[must_use]
212 fn variants() -> Vec<String> {
213 Self::iter().map(|x| x.to_string()).collect()
214 }
215
216 #[classmethod]
217 #[pyo3(name = "from_str")]
218 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
219 let data_str: String = data.str()?.extract()?;
220 Self::from_str(&data_str).map_err(to_pyvalue_err)
221 }
222
223 #[classattr]
224 #[pyo3(name = "UNIFIED")]
225 fn py_unified() -> Self {
226 Self::Unified
227 }
228}
229
230#[pymethods]
231impl BybitMarginMode {
232 #[new]
233 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
234 let t = Self::type_object(py);
235 Self::py_from_str(&t, value)
236 }
237
238 fn __hash__(&self) -> isize {
239 *self as isize
240 }
241
242 fn __repr__(&self) -> String {
243 format!(
244 "<{}.{}: '{}'>",
245 stringify!(BybitMarginMode),
246 self.name(),
247 self.value(),
248 )
249 }
250
251 fn __str__(&self) -> String {
252 self.to_string()
253 }
254
255 #[getter]
256 #[must_use]
257 pub fn name(&self) -> &str {
258 self.as_ref()
259 }
260
261 #[getter]
262 #[must_use]
263 pub fn value(&self) -> &'static str {
264 match self {
265 Self::IsolatedMargin => "ISOLATED_MARGIN",
266 Self::RegularMargin => "REGULAR_MARGIN",
267 Self::PortfolioMargin => "PORTFOLIO_MARGIN",
268 }
269 }
270
271 #[staticmethod]
272 #[must_use]
273 fn variants() -> Vec<String> {
274 Self::iter().map(|x| x.to_string()).collect()
275 }
276
277 #[classmethod]
278 #[pyo3(name = "from_str")]
279 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
280 let data_str: String = data.str()?.extract()?;
281 Self::from_str(&data_str).map_err(to_pyvalue_err)
282 }
283
284 #[classattr]
285 #[pyo3(name = "ISOLATED_MARGIN")]
286 fn py_isolated_margin() -> Self {
287 Self::IsolatedMargin
288 }
289
290 #[classattr]
291 #[pyo3(name = "REGULAR_MARGIN")]
292 fn py_regular_margin() -> Self {
293 Self::RegularMargin
294 }
295
296 #[classattr]
297 #[pyo3(name = "PORTFOLIO_MARGIN")]
298 fn py_portfolio_margin() -> Self {
299 Self::PortfolioMargin
300 }
301}
302
303#[pymethods]
304impl BybitPositionMode {
305 #[new]
306 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
307 let t = Self::type_object(py);
308 Self::py_from_str(&t, value)
309 }
310
311 fn __hash__(&self) -> isize {
312 *self as isize
313 }
314
315 fn __repr__(&self) -> String {
316 format!(
317 "<{}.{}: {}>",
318 stringify!(BybitPositionMode),
319 self.name(),
320 self.value(),
321 )
322 }
323
324 fn __str__(&self) -> String {
325 self.to_string()
326 }
327
328 #[getter]
329 #[must_use]
330 pub fn name(&self) -> &str {
331 self.as_ref()
332 }
333
334 #[getter]
335 #[must_use]
336 pub fn value(&self) -> i32 {
337 *self as i32
338 }
339
340 #[staticmethod]
341 #[must_use]
342 fn variants() -> Vec<String> {
343 Self::iter().map(|x| x.to_string()).collect()
344 }
345
346 #[classmethod]
347 #[pyo3(name = "from_str")]
348 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
349 if let Ok(int_val) = data.extract::<i32>() {
351 return match int_val {
352 0 => Ok(Self::MergedSingle),
353 3 => Ok(Self::BothSides),
354 _ => Err(to_pyvalue_err(anyhow::anyhow!(
355 "Invalid BybitPositionMode value: {int_val}"
356 ))),
357 };
358 }
359
360 let data_str: String = data.str()?.extract()?;
362 Self::from_str(&data_str).map_err(to_pyvalue_err)
363 }
364
365 #[classattr]
366 #[pyo3(name = "MERGED_SINGLE")]
367 fn py_merged_single() -> Self {
368 Self::MergedSingle
369 }
370
371 #[classattr]
372 #[pyo3(name = "BOTH_SIDES")]
373 fn py_both_sides() -> Self {
374 Self::BothSides
375 }
376}
377
378#[pymethods]
379impl BybitMarginAction {
380 #[new]
381 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
382 let t = Self::type_object(py);
383 Self::py_from_str(&t, value)
384 }
385
386 fn __repr__(&self) -> String {
387 format!(
388 "<{}.{}: '{}'>",
389 stringify!(BybitMarginAction),
390 self.name(),
391 self.value(),
392 )
393 }
394
395 fn __str__(&self) -> String {
396 self.to_string()
397 }
398
399 #[getter]
400 #[must_use]
401 pub fn name(&self) -> &str {
402 self.as_ref()
403 }
404
405 #[getter]
406 #[must_use]
407 pub fn value(&self) -> String {
408 self.to_string()
409 }
410
411 #[staticmethod]
412 #[must_use]
413 fn variants() -> Vec<String> {
414 Self::iter().map(|x| x.to_string()).collect()
415 }
416
417 #[classmethod]
418 #[pyo3(name = "from_str")]
419 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
420 let data_str: String = data.str()?.extract()?;
421 Self::from_str(&data_str).map_err(to_pyvalue_err)
422 }
423
424 #[classattr]
425 #[pyo3(name = "BORROW")]
426 fn py_borrow() -> Self {
427 Self::Borrow
428 }
429
430 #[classattr]
431 #[pyo3(name = "REPAY")]
432 fn py_repay() -> Self {
433 Self::Repay
434 }
435
436 #[classattr]
437 #[pyo3(name = "GET_BORROW_AMOUNT")]
438 fn py_get_borrow_amount() -> Self {
439 Self::GetBorrowAmount
440 }
441}