nautilus_model/python/types/
balance.rs1use std::str::FromStr;
17
18use nautilus_core::python::{parsing::get_required_string, to_pyvalue_err};
19use pyo3::{prelude::*, types::PyDict};
20
21use crate::{
22 identifiers::InstrumentId,
23 types::{AccountBalance, Currency, MarginBalance, Money},
24};
25
26#[pymethods]
27impl AccountBalance {
28 #[new]
29 fn py_new(total: Money, locked: Money, free: Money) -> PyResult<Self> {
30 Self::new_checked(total, locked, free).map_err(to_pyvalue_err)
31 }
32
33 fn __repr__(&self) -> String {
34 format!("{self:?}")
35 }
36
37 fn __str__(&self) -> String {
38 self.to_string()
39 }
40
41 #[staticmethod]
51 #[pyo3(name = "from_dict")]
52 pub fn py_from_dict(values: &Bound<'_, PyDict>) -> PyResult<Self> {
53 let currency_str = get_required_string(values, "currency")?;
54 let total_str = get_required_string(values, "total")?;
55 let total: f64 = total_str.parse::<f64>().unwrap();
56 let free_str = get_required_string(values, "free")?;
57 let free: f64 = free_str.parse::<f64>().unwrap();
58 let locked_str = get_required_string(values, "locked")?;
59 let locked: f64 = locked_str.parse::<f64>().unwrap();
60 let currency = Currency::from_str(currency_str.as_str()).map_err(to_pyvalue_err)?;
61 Self::new_checked(
62 Money::new(total, currency),
63 Money::new(locked, currency),
64 Money::new(free, currency),
65 )
66 .map_err(to_pyvalue_err)
67 }
68
69 #[pyo3(name = "to_dict")]
75 pub fn py_to_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
76 let dict = PyDict::new(py);
77 dict.set_item("type", stringify!(AccountBalance))?;
78 dict.set_item(
79 "total",
80 format!(
81 "{:.*}",
82 self.total.currency.precision as usize,
83 self.total.as_f64()
84 ),
85 )?;
86 dict.set_item(
87 "locked",
88 format!(
89 "{:.*}",
90 self.locked.currency.precision as usize,
91 self.locked.as_f64()
92 ),
93 )?;
94 dict.set_item(
95 "free",
96 format!(
97 "{:.*}",
98 self.free.currency.precision as usize,
99 self.free.as_f64()
100 ),
101 )?;
102 dict.set_item("currency", self.currency.code.to_string())?;
103 Ok(dict.into())
104 }
105}
106
107#[pymethods]
108impl MarginBalance {
109 #[new]
110 fn py_new(initial: Money, maintenance: Money, instrument: InstrumentId) -> Self {
111 Self::new(initial, maintenance, instrument)
112 }
113
114 fn __repr__(&self) -> String {
115 format!("{self:?}")
116 }
117
118 fn __str__(&self) -> String {
119 self.to_string()
120 }
121
122 #[staticmethod]
132 #[pyo3(name = "from_dict")]
133 pub fn py_from_dict(values: &Bound<'_, PyDict>) -> PyResult<Self> {
134 let currency_str = get_required_string(values, "currency")?;
135 let initial_str = get_required_string(values, "initial")?;
136 let initial: f64 = initial_str.parse::<f64>().unwrap();
137 let maintenance_str = get_required_string(values, "maintenance")?;
138 let maintenance: f64 = maintenance_str.parse::<f64>().unwrap();
139 let instrument_id_str = get_required_string(values, "instrument_id")?;
140 let currency = Currency::from_str(currency_str.as_str()).map_err(to_pyvalue_err)?;
141 let account_balance = Self::new(
142 Money::new(initial, currency),
143 Money::new(maintenance, currency),
144 InstrumentId::from(instrument_id_str.as_str()),
145 );
146 Ok(account_balance)
147 }
148
149 #[pyo3(name = "to_dict")]
159 pub fn py_to_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
160 let dict = PyDict::new(py);
161 dict.set_item("type", stringify!(MarginBalance))?;
162 dict.set_item(
163 "initial",
164 format!(
165 "{:.*}",
166 self.initial.currency.precision as usize,
167 self.initial.as_f64()
168 ),
169 )?;
170 dict.set_item(
171 "maintenance",
172 format!(
173 "{:.*}",
174 self.maintenance.currency.precision as usize,
175 self.maintenance.as_f64()
176 ),
177 )?;
178 dict.set_item("currency", self.currency.code.to_string())?;
179 dict.set_item("instrument_id", self.instrument_id.to_string())?;
180 Ok(dict.into())
181 }
182}