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
80#[pymethods]
81impl BybitEnvironment {
82 #[new]
83 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
84 let t = Self::type_object(py);
85 Self::py_from_str(&t, value)
86 }
87
88 fn __hash__(&self) -> isize {
89 *self as isize
90 }
91
92 fn __repr__(&self) -> String {
93 format!(
94 "<{}.{}: {}>",
95 stringify!(BybitEnvironment),
96 self.name(),
97 *self as u8,
98 )
99 }
100
101 fn __str__(&self) -> String {
102 self.to_string()
103 }
104
105 #[getter]
106 #[must_use]
107 pub fn name(&self) -> &str {
108 self.as_ref()
109 }
110
111 #[getter]
112 #[must_use]
113 pub fn value(&self) -> String {
114 self.to_string().to_lowercase()
115 }
116
117 #[staticmethod]
118 #[must_use]
119 fn variants() -> Vec<String> {
120 Self::iter().map(|x| x.to_string()).collect()
121 }
122
123 #[classmethod]
124 #[pyo3(name = "from_str")]
125 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
126 let data_str: String = data.str()?.extract()?;
127 Self::from_str(&data_str).map_err(to_pyvalue_err)
128 }
129}
130
131#[pymethods]
132impl BybitAccountType {
133 #[new]
134 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
135 let t = Self::type_object(py);
136 Self::py_from_str(&t, value)
137 }
138
139 fn __hash__(&self) -> isize {
140 *self as isize
141 }
142
143 fn __repr__(&self) -> String {
144 format!(
145 "<{}.{}: {}>",
146 stringify!(BybitAccountType),
147 self.name(),
148 *self as u8,
149 )
150 }
151
152 fn __str__(&self) -> String {
153 self.to_string()
154 }
155
156 #[getter]
157 #[must_use]
158 pub fn name(&self) -> &str {
159 self.as_ref()
160 }
161
162 #[getter]
163 #[must_use]
164 pub fn value(&self) -> String {
165 self.to_string().to_uppercase()
166 }
167
168 #[staticmethod]
169 #[must_use]
170 fn variants() -> Vec<String> {
171 Self::iter().map(|x| x.to_string()).collect()
172 }
173
174 #[classmethod]
175 #[pyo3(name = "from_str")]
176 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
177 let data_str: String = data.str()?.extract()?;
178 Self::from_str(&data_str).map_err(to_pyvalue_err)
179 }
180}
181
182#[pymethods]
183impl BybitMarginMode {
184 #[new]
185 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
186 let t = Self::type_object(py);
187 Self::py_from_str(&t, value)
188 }
189
190 fn __hash__(&self) -> isize {
191 *self as isize
192 }
193
194 fn __repr__(&self) -> String {
195 format!(
196 "<{}.{}: '{}'>",
197 stringify!(BybitMarginMode),
198 self.name(),
199 self.value(),
200 )
201 }
202
203 fn __str__(&self) -> String {
204 self.to_string()
205 }
206
207 #[getter]
208 #[must_use]
209 pub fn name(&self) -> &str {
210 self.as_ref()
211 }
212
213 #[getter]
214 #[must_use]
215 pub fn value(&self) -> &'static str {
216 match self {
217 Self::IsolatedMargin => "ISOLATED_MARGIN",
218 Self::RegularMargin => "REGULAR_MARGIN",
219 Self::PortfolioMargin => "PORTFOLIO_MARGIN",
220 }
221 }
222
223 #[staticmethod]
224 #[must_use]
225 fn variants() -> Vec<String> {
226 Self::iter().map(|x| x.to_string()).collect()
227 }
228
229 #[classmethod]
230 #[pyo3(name = "from_str")]
231 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
232 let data_str: String = data.str()?.extract()?;
233 Self::from_str(&data_str).map_err(to_pyvalue_err)
234 }
235}
236
237#[pymethods]
238impl BybitPositionMode {
239 #[new]
240 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
241 let t = Self::type_object(py);
242 Self::py_from_str(&t, value)
243 }
244
245 fn __hash__(&self) -> isize {
246 *self as isize
247 }
248
249 fn __repr__(&self) -> String {
250 format!(
251 "<{}.{}: {}>",
252 stringify!(BybitPositionMode),
253 self.name(),
254 self.value(),
255 )
256 }
257
258 fn __str__(&self) -> String {
259 self.to_string()
260 }
261
262 #[getter]
263 #[must_use]
264 pub fn name(&self) -> &str {
265 self.as_ref()
266 }
267
268 #[getter]
269 #[must_use]
270 pub fn value(&self) -> i32 {
271 *self as i32
272 }
273
274 #[staticmethod]
275 #[must_use]
276 fn variants() -> Vec<String> {
277 Self::iter().map(|x| x.to_string()).collect()
278 }
279
280 #[classmethod]
281 #[pyo3(name = "from_str")]
282 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
283 if let Ok(int_val) = data.extract::<i32>() {
285 return match int_val {
286 0 => Ok(Self::MergedSingle),
287 3 => Ok(Self::BothSides),
288 _ => Err(to_pyvalue_err(anyhow::anyhow!(
289 "Invalid BybitPositionMode value: {int_val}"
290 ))),
291 };
292 }
293
294 let data_str: String = data.str()?.extract()?;
296 Self::from_str(&data_str).map_err(to_pyvalue_err)
297 }
298}
299
300#[pymethods]
301impl BybitMarginAction {
302 #[new]
303 fn py_new(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<Self> {
304 let t = Self::type_object(py);
305 Self::py_from_str(&t, value)
306 }
307
308 fn __repr__(&self) -> String {
309 format!(
310 "<{}.{}: '{}'>",
311 stringify!(BybitMarginAction),
312 self.name(),
313 self.value(),
314 )
315 }
316
317 fn __str__(&self) -> String {
318 self.to_string()
319 }
320
321 #[getter]
322 #[must_use]
323 pub fn name(&self) -> &str {
324 self.as_ref()
325 }
326
327 #[getter]
328 #[must_use]
329 pub fn value(&self) -> String {
330 self.to_string()
331 }
332
333 #[staticmethod]
334 #[must_use]
335 fn variants() -> Vec<String> {
336 Self::iter().map(|x| x.to_string()).collect()
337 }
338
339 #[classmethod]
340 #[pyo3(name = "from_str")]
341 fn py_from_str(_cls: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
342 let data_str: String = data.str()?.extract()?;
343 Self::from_str(&data_str).map_err(to_pyvalue_err)
344 }
345}