borderbook/
side.rs

1use {Direction, Order};
2
3use std::hash::Hash;
4use std::cmp::{Ordering::Equal, min};
5use std::collections::{HashMap, VecDeque};
6
7// One side of an orderbook
8// Need:
9// - Fast iteration up to value
10pub struct Side<K>
11where
12    K: Hash + Eq + Clone,
13{
14    pub direction: Direction,
15
16    map: HashMap<K, usize>,
17    inverse_map: HashMap<usize, K>,
18
19    orders: Vec<Option<Order>>,
20    sorting: VecDeque<usize>,
21
22    free_list: Vec<usize>,
23}
24
25
26impl<K: Hash + Eq + Clone> Side<K> {
27    pub fn new(dir: Direction) -> Self {
28        Self {
29            direction: dir,
30            map: Default::default(),
31            inverse_map: Default::default(),
32            orders: Default::default(),
33            sorting: Default::default(),
34
35            free_list: Default::default(),
36        }
37    }
38
39    pub fn get_order(&self, key: &K) -> Option<Order> {
40        if let Some(&res) = self.map.get(key) {
41            self.orders[res]
42        } else {
43            None
44        }
45    }
46
47    pub fn get_key(&self, position: usize) -> &K {
48        &self.inverse_map[&self.sorting[position]]
49    }
50
51    pub fn len(&self) -> usize {
52        self.sorting.len()
53    }
54
55    pub fn is_empty(&self) -> bool {
56        self.sorting.is_empty()
57    }
58
59    pub fn get_order_by_index(&self, index: usize) -> Option<Order> {
60        self.orders[self.sorting[index]]
61    }
62
63    fn find_index_for_order(&self, order: Order) -> usize {
64        let factor = match self.direction {
65            Direction::Ask => 1.0,
66            Direction::Bid => -1.0,
67        };
68
69        let price = order.price * factor;
70
71        match deque_binary_search_by(&self.sorting, |index| {
72            let other_order = self.orders[*index].unwrap();
73            let other_price = other_order.price * factor;
74            price.partial_cmp(&other_price).unwrap_or(Equal)
75        }) {
76            Ok(i) => i + 1,
77            Err(i) => i,
78        }
79    }
80
81    pub fn insert(&mut self, key: K, order: Order) -> usize {
82        let sorting_index = self.find_index_for_order(order);
83
84        // Insert before or after depending on direction
85        let index = if let Some(i) = self.free_list.pop() {
86            self.orders[i] = Some(order);
87            i
88        } else {
89            self.orders.push(Some(order));
90            self.orders.len() - 1
91        };
92
93        self.sorting.insert(sorting_index, index);
94        self.map.insert(key.clone(), index);
95        self.inverse_map.insert(index, key);
96
97        sorting_index
98    }
99
100    pub fn remove(&mut self, key: &K) {
101        if let Some(&index) = self.map.get(key) {
102            let mut sorting_index = 0;
103
104            for i in 0..self.sorting.len() {
105                if self.sorting[i] == index {
106                    sorting_index = i;
107                    break;
108                }
109            }
110
111            self.sorting.remove(sorting_index);
112            self.orders[index] = None;
113            {
114                let key = &self.inverse_map[&index];
115                self.map.remove(&key);
116            }
117            self.inverse_map.remove(&index);
118            self.free_list.push(index);
119        }
120    }
121
122    pub fn remove_first_n(&mut self, n: usize) {
123        let n = min(n, self.len());
124        for i in 0..n {
125            let index = self.sorting[i];
126            let key = &self.inverse_map[&index];
127            self.map.remove(&key);
128            self.orders[index] = None;
129            self.free_list.push(index);
130        }
131        for _ in 0..n {
132            self.sorting.pop_front();
133        }
134    }
135
136    pub fn set_first_volume(&mut self, volume: f64) {
137        if self.is_empty() { return }
138
139        if let Some(ref mut order) = self.orders[self.sorting[0]] {
140            order.volume = volume;
141        }
142    }
143}
144
145
146pub struct SideIterator<'a, K>
147where
148    K: 'a + Clone + Hash + Eq
149{
150    side: &'a Side<K>,
151    index: usize,
152}
153
154impl<'a, K> IntoIterator for &'a Side<K>
155where
156    K: 'a + Clone + Hash + Eq
157{
158    type Item = (&'a K, Order);
159    type IntoIter = SideIterator<'a, K>;
160
161    fn into_iter(self) -> Self::IntoIter {
162        SideIterator {
163            side: &self,
164            index: 0,
165        }
166    }
167}
168
169impl<'a, K> Iterator for SideIterator<'a, K>
170where
171    K: 'a + Clone + Hash + Eq
172{
173    type Item = (&'a K, Order);
174
175    fn next(&mut self) -> Option<Self::Item> {
176        if self.index < self.side.len() {
177            let index = self.index;
178            self.index += 1;
179            self.side.get_order_by_index(index).map(
180                |order| (self.side.get_key(index), order)
181            )
182        } else {
183            None
184        }
185    }
186}
187
188
189use std::cmp::{Ordering};
190
191fn deque_binary_search_by<'a, T, F>(q: &'a VecDeque<T>, f: F) -> Result<usize, usize>
192where
193    F: FnMut(&'a T) -> Ordering + Clone
194{
195    let (first, second) = q.as_slices();
196    if let Ok(res) = first.binary_search_by(f.clone()) {
197        Ok(res)
198    }
199    else {
200        let first_len = first.len();
201        match second.binary_search_by(f) {
202            Ok(res) => Ok(res + first_len),
203            Err(res) => Err(res + first_len),
204        }
205    }
206}
207
208
209#[cfg(test)]
210mod tests {
211    use super::*;
212
213    #[test]
214    fn it_works() {
215        let mut ob = Side::new(Direction::Bid);
216
217        ob.insert(
218            "first",
219            Order {
220                price: 10.0,
221                volume: 10.0,
222            },
223        );
224        ob.insert(
225            "second",
226            Order {
227                price: 50.0,
228                volume: 10.0,
229            },
230        );
231        ob.insert(
232            "third",
233            Order {
234                price: 5.0,
235                volume: 10.0,
236            },
237        );
238        ob.insert(
239            "fourth",
240            Order {
241                price: 20.0,
242                volume: 10.0,
243            },
244        );
245        ob.insert(
246            "fifth",
247            Order {
248                price: 13.0,
249                volume: 10.0,
250            },
251        );
252
253        ob.remove(&"fourth");
254
255        for order in ob.into_iter() {
256            println!("{:?}", order);
257        }
258    }
259
260    #[test]
261    fn test_set_first_volume() {
262        let mut side = Side::<u32>::new(Direction::Ask);
263
264        side.set_first_volume(5.0);
265
266        assert_eq!(side.len(), 0);
267
268        side.insert(
269            0,
270            Order {
271                price: 10.0,
272                volume: 1.0
273            }
274        );
275
276        assert_eq!(side.len(), 1);
277
278        let first = side.into_iter().next().unwrap().1;
279        assert_eq!(first.volume, 1.0);
280
281        side.set_first_volume(2.0);
282        let first = side.into_iter().next().unwrap().1;
283        assert_eq!(first.volume, 2.0);
284    }
285}