1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#[derive(Debug, Clone, Copy)]
pub struct Margin {
wallet_balance: f64,
position_margin: f64,
order_margin: f64,
available_balance: f64,
}
impl Margin {
pub fn new_init(init_balance: f64) -> Self {
Margin {
wallet_balance: init_balance,
position_margin: 0.0,
order_margin: 0.0,
available_balance: init_balance,
}
}
pub fn new(
wallet_balance: f64,
position_margin: f64,
order_margin: f64,
available_balance: f64,
) -> Self {
Margin {
wallet_balance,
position_margin,
order_margin,
available_balance,
}
}
pub(crate) fn set_order_margin(&mut self, order_margin: f64) {
debug_assert!(order_margin >= 0.0);
self.order_margin = order_margin;
self.available_balance = self.wallet_balance - self.position_margin - self.order_margin;
debug_assert!(self.available_balance >= 0.0);
}
pub(crate) fn set_position_margin(&mut self, delta: f64) {
self.position_margin = delta;
self.available_balance = self.wallet_balance - self.order_margin - self.position_margin;
debug_assert!(self.position_margin >= 0.0);
debug_assert!(self.position_margin <= self.wallet_balance);
debug_assert!(self.available_balance >= 0.0);
debug_assert!(self.available_balance <= self.wallet_balance);
}
pub(crate) fn change_balance(&mut self, delta: f64) {
self.wallet_balance += delta;
self.available_balance += delta;
}
pub fn wallet_balance(&self) -> f64 {
self.wallet_balance
}
pub fn position_margin(&self) -> f64 {
self.position_margin
}
pub fn order_margin(&self) -> f64 {
self.order_margin
}
pub fn available_balance(&self) -> f64 {
self.available_balance
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn margin_set_order_margin() {
let mut margin = Margin::new_init(1.0);
margin.set_order_margin(1.0);
assert_eq!(margin.wallet_balance, 1.0);
assert_eq!(margin.position_margin, 0.0);
assert_eq!(margin.order_margin, 1.0);
assert_eq!(margin.available_balance, 0.0);
}
#[test]
fn margin_change_balance() {
let mut margin = Margin::new_init(1.0);
margin.change_balance(0.05);
assert_eq!(margin.wallet_balance, 1.05);
assert_eq!(margin.position_margin, 0.0);
assert_eq!(margin.order_margin, 0.0);
assert_eq!(margin.available_balance, 1.05);
}
}