lnm_sdk/shared/models/
leverage.rs1use std::{cmp::Ordering, convert::TryFrom, fmt};
2
3use serde::{Deserialize, Serialize, de};
4
5use super::{
6 SATS_PER_BTC, error::LeverageValidationError, margin::Margin, price::Price, quantity::Quantity,
7 serde_util,
8};
9
10#[derive(Debug, Clone, Copy, PartialEq)]
34pub struct Leverage(f64);
35
36impl Leverage {
37 pub const MIN: Self = Self(1.);
39
40 pub const MAX: Self = Self(100.);
42
43 pub fn bounded<T>(value: T) -> Self
69 where
70 T: Into<f64>,
71 {
72 let as_f64: f64 = value.into();
73 let clamped = as_f64.clamp(Self::MIN.0, Self::MAX.0);
74
75 Self(clamped)
76 }
77
78 pub fn as_f64(&self) -> f64 {
89 self.0
90 }
91
92 pub fn try_calculate(
110 quantity: Quantity,
111 margin: Margin,
112 price: Price,
113 ) -> Result<Self, LeverageValidationError> {
114 let leverage_value = quantity.as_f64() * SATS_PER_BTC / (margin.as_f64() * price.as_f64());
115
116 Self::try_from(leverage_value)
117 }
118}
119
120impl From<Leverage> for f64 {
121 fn from(value: Leverage) -> f64 {
122 value.0
123 }
124}
125
126impl TryFrom<u8> for Leverage {
127 type Error = LeverageValidationError;
128
129 fn try_from(value: u8) -> Result<Self, Self::Error> {
130 Self::try_from(value as f64)
131 }
132}
133
134impl TryFrom<u16> for Leverage {
135 type Error = LeverageValidationError;
136
137 fn try_from(value: u16) -> Result<Self, Self::Error> {
138 Self::try_from(value as f64)
139 }
140}
141
142impl TryFrom<u32> for Leverage {
143 type Error = LeverageValidationError;
144
145 fn try_from(value: u32) -> Result<Self, Self::Error> {
146 Self::try_from(value as f64)
147 }
148}
149
150impl TryFrom<u64> for Leverage {
151 type Error = LeverageValidationError;
152
153 fn try_from(value: u64) -> Result<Self, Self::Error> {
154 Self::try_from(value as f64)
155 }
156}
157
158impl TryFrom<i8> for Leverage {
159 type Error = LeverageValidationError;
160
161 fn try_from(value: i8) -> Result<Self, Self::Error> {
162 Self::try_from(value as f64)
163 }
164}
165
166impl TryFrom<i16> for Leverage {
167 type Error = LeverageValidationError;
168
169 fn try_from(value: i16) -> Result<Self, Self::Error> {
170 Self::try_from(value as f64)
171 }
172}
173
174impl TryFrom<i32> for Leverage {
175 type Error = LeverageValidationError;
176
177 fn try_from(leverage: i32) -> Result<Self, Self::Error> {
178 Self::try_from(leverage as f64)
179 }
180}
181
182impl TryFrom<i64> for Leverage {
183 type Error = LeverageValidationError;
184
185 fn try_from(value: i64) -> Result<Self, Self::Error> {
186 Self::try_from(value as f64)
187 }
188}
189
190impl TryFrom<usize> for Leverage {
191 type Error = LeverageValidationError;
192
193 fn try_from(value: usize) -> Result<Self, Self::Error> {
194 Self::try_from(value as f64)
195 }
196}
197
198impl TryFrom<isize> for Leverage {
199 type Error = LeverageValidationError;
200
201 fn try_from(value: isize) -> Result<Self, Self::Error> {
202 Self::try_from(value as f64)
203 }
204}
205
206impl TryFrom<f32> for Leverage {
207 type Error = LeverageValidationError;
208
209 fn try_from(value: f32) -> Result<Self, Self::Error> {
210 Self::try_from(value as f64)
211 }
212}
213
214impl TryFrom<f64> for Leverage {
215 type Error = LeverageValidationError;
216
217 fn try_from(value: f64) -> Result<Self, Self::Error> {
218 if value < Self::MIN.0 {
219 return Err(LeverageValidationError::TooLow { value });
220 }
221
222 if value > Self::MAX.0 {
223 return Err(LeverageValidationError::TooHigh { value });
224 }
225
226 Ok(Leverage(value))
227 }
228}
229
230impl Eq for Leverage {}
231
232impl Ord for Leverage {
233 fn cmp(&self, other: &Self) -> Ordering {
234 self.0
235 .partial_cmp(&other.0)
236 .expect("`Leverage` must be finite")
237 }
238}
239
240impl PartialOrd for Leverage {
241 fn partial_cmp(&self, other: &Leverage) -> Option<Ordering> {
242 Some(self.cmp(other))
243 }
244}
245
246impl fmt::Display for Leverage {
247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248 self.0.fmt(f)
249 }
250}
251
252impl Serialize for Leverage {
253 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
254 where
255 S: serde::Serializer,
256 {
257 serde_util::float_without_decimal::serialize(&self.0, serializer)
258 }
259}
260
261impl<'de> Deserialize<'de> for Leverage {
262 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
263 where
264 D: serde::Deserializer<'de>,
265 {
266 let leverage_f64 = f64::deserialize(deserializer)?;
267 Leverage::try_from(leverage_f64).map_err(|e| de::Error::custom(e.to_string()))
268 }
269}