1use std::{collections::{BTreeMap, HashMap, btree_map::Entry}, time::Instant};
2use crate::order_book::types::{BookDepth, EngineCancelOrder, EngineModifyOrder, ModifyOutcome, OrderBookError, OrderNode, PriceLevel, PriceLevelDepth};
3
4#[derive(Debug)]
5pub struct OrderBook{
6 pub ask : HalfBook,
7 pub bid : HalfBook
8}
9impl OrderBook {
10 pub fn new () -> Self{
11 Self { ask : HalfBook::new(), bid : HalfBook::new() }
12 }
13
14 pub fn create_buy_order(&mut self, resting_order : OrderNode) -> Result<usize, OrderBookError>{
15
16 let mut order = resting_order;
17 let order_quantity = order.current_quantity;
18 let price = order.market_limit;
19 let order_id = resting_order.order_id;
20
21 match self.bid.price_map.entry(price){ Entry::Occupied(mut entry) => {
23 let price_level = entry.get_mut();
24 if price_level.total_quantity == 0 || price_level.head == None || price_level.tail == None{
25 entry.remove();
26 } else {
27 order.prev = price_level.tail;
28 if let Some(free_index) = self.bid.free_list.pop(){
29 self.bid.order_registry.insert(order_id, free_index);
30 self.bid.order_pool[free_index] = Some(order);
31 let prev_tail_idx = price_level.tail.unwrap();
32 price_level.tail = Some(free_index);
33 price_level.total_quantity += order_quantity;
34 price_level.order_count += 1;
35 if let Some(prev_order) = self.bid.order_pool.get_mut(prev_tail_idx).unwrap(){
36 prev_order.next = Some(free_index);
37 };
38 return Ok(free_index);
39 }
40 else {
41 self.bid.order_pool.push(Some(order));
42 let new_tail = self.bid.order_pool.len() - 1;
43 self.bid.order_registry.insert(order_id, new_tail);
44 let pre_tail_idx = price_level.tail.unwrap();
45 price_level.tail = Some(new_tail);
46 price_level.total_quantity += order_quantity;
47 price_level.order_count += 1;
48 if let Some(prev_order) = self.bid.order_pool.get_mut(pre_tail_idx).unwrap(){
49 prev_order.next = Some(new_tail);
50 };
51 return Ok(new_tail);
52 }
53 }
54 }
55 Entry::Vacant(_) => {
56 }
58 }
59
60 let mut new_price_level = PriceLevel{
61 head : None,
62 tail : None,
63 order_count : 0,
64 total_quantity : 0
65 };
66 if let Some(free_index) = self.bid.free_list.pop(){
67 self.bid.order_registry.insert(order_id, free_index);
68 self.bid.order_pool[free_index] = Some(order);
69 new_price_level.head = Some(free_index);
70 new_price_level.tail = Some(free_index);
71 new_price_level.order_count += 1;
72 new_price_level.total_quantity += order_quantity;
73 self.bid.price_map.entry(price).or_insert(new_price_level);
74 return Ok(free_index)
75 }
76 self.bid.order_pool.push(Some(order));
77 let new_index = self.bid.order_pool.len()-1;
78 self.bid.order_registry.insert(order_id, new_index);
79 new_price_level.head = Some(new_index);
80 new_price_level.tail = Some(new_index);
81 new_price_level.order_count += 1;
82 new_price_level.total_quantity += order_quantity;
83 self.bid.price_map.entry(price).or_insert(new_price_level);
84
85 Ok(new_index)
86 }
87
88 pub fn create_sell_order(&mut self, resting_order : OrderNode) -> Result<usize, OrderBookError>{
89 let mut order = resting_order;
90 let order_quantity = order.current_quantity;
91 let price = order.market_limit;
92 let order_id = resting_order.order_id;
93
94 match self.ask.price_map.entry(price){
95 Entry::Occupied(mut entry) => {
96 let price_level = entry.get_mut();
97 if price_level.total_quantity == 0 || price_level.head == None || price_level.tail == None{
98 entry.remove();
99 }else {
100 order.prev = price_level.tail;
101 if let Some(free_index) = self.ask.free_list.pop(){
102 self.ask.order_registry.insert(order_id, free_index);
103 self.ask.order_pool[free_index] = Some(order);
104 let prev_tail_idx = price_level.tail.unwrap();
105 price_level.tail = Some(free_index);
106 price_level.total_quantity += order_quantity;
107 price_level.order_count += 1;
108 if let Some(prev_order) = self.ask.order_pool.get_mut(prev_tail_idx).unwrap(){
109 prev_order.next = Some(free_index);
110 };
111 return Ok(free_index);
112 }
113 else {
114 self.ask.order_pool.push(Some(order));
115 let new_tail = self.ask.order_pool.len() - 1;
116 self.ask.order_registry.insert(order_id, new_tail);
117 let prev_tail_idx = price_level.tail.unwrap();
118 price_level.tail = Some(new_tail);
119 price_level.total_quantity += order_quantity;
120 price_level.order_count += 1;
121 if let Some(prev_order) = self.ask.order_pool.get_mut(prev_tail_idx).unwrap(){
122 prev_order.next = Some(new_tail);
123 };
124 return Ok(new_tail);
125 }
126 }
127 }
128 Entry::Vacant(_) => {
129 }
131 }
132
133 let mut new_price_level = PriceLevel{
134 head : None,
135 tail : None,
136 order_count : 0,
137 total_quantity : 0
138 };
139 if let Some(free_index) = self.ask.free_list.pop(){
140 self.ask.order_registry.insert(order_id, free_index);
141 self.ask.order_pool[free_index] = Some(order);
142 new_price_level.head = Some(free_index);
143 new_price_level.tail = Some(free_index);
144 new_price_level.order_count += 1;
145 new_price_level.total_quantity += order_quantity;
146 self.ask.price_map.entry(price).or_insert(new_price_level);
147 return Ok(free_index)
148 }
149 self.ask.order_pool.push(Some(order));
150 let new_index = self.ask.order_pool.len()-1;
151 self.ask.order_registry.insert(order_id, new_index);
152 new_price_level.head = Some(new_index);
153 new_price_level.tail = Some(new_index);
154 new_price_level.order_count += 1;
155 new_price_level.total_quantity += order_quantity;
156 self.ask.price_map.entry(price).or_insert(new_price_level);
157
158 Ok(new_index)
159 }
160
161 pub fn cancel_order(&mut self, order_id : u64, order : EngineCancelOrder) -> Result<(), OrderBookError>{
162 if order.is_buy_side {
163 let existing_index = self.bid.order_registry.get(&order_id);
164 if existing_index.is_none(){
165 return Err(OrderBookError::OrderNotFound);
166 }
167 let (prev, next, old_price, old_quantity) = {
168 match self.bid.order_pool[*existing_index.unwrap()].as_ref(){
169 Some(node) => {
170 (node.prev, node.next, node.market_limit, node.current_quantity)
171 }
172 None => {
173 return Err(OrderBookError::OrderNotFound);
174 }
175 }
176 };
177 if let Some(price_level) = self.bid.price_map.get_mut(&old_price){
178
179 if price_level.head.is_some() && price_level.tail.is_some(){
180 if *existing_index.unwrap() == price_level.head.unwrap() && *existing_index.unwrap() == price_level.tail.unwrap(){
181 self.bid.order_pool[*existing_index.unwrap()] = None;
182 price_level.head = None;
183 price_level.tail = None;
184 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
185 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
186 self.bid.free_list.push(*existing_index.unwrap());
187 return Ok(());
188 }
189 else if *existing_index.unwrap() == price_level.tail.unwrap() {
190 if let Some(prev_index) = prev{
191 if let Some(possible_prev_node) = self.bid.order_pool.get_mut(prev_index){
192 if let Some(prev_node) = possible_prev_node{
193 prev_node.next = None;
194 price_level.tail = Some(prev_index);
195 }
196 }
197 self.bid.order_pool[*existing_index.unwrap()] = None;
198 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
199 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
200 self.bid.free_list.push(*existing_index.unwrap());
201 return Ok(());
202 } else {
203 return Err(OrderBookError::PrevNotFound);
204 }
205 }
206 else if *existing_index.unwrap() == price_level.head.unwrap() {
207 if let Some(next_index) = next{
208 if let Some(possible_next_node) = self.bid.order_pool.get_mut(next_index){
209 if let Some(next_node) = possible_next_node{
210 next_node.prev = None;
211 price_level.head = Some(next_index);
212 }
213 }
214 self.bid.order_pool[*existing_index.unwrap()] = None;
215 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
216 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
217 self.bid.free_list.push(*existing_index.unwrap());
218 return Ok(());
219 } else {
220 return Err(OrderBookError::NextNotFound);
221 }
222 }
223 else {
224 if let Some(prev_index) = prev{
225 if let Some(possible_prev_node) = self.bid.order_pool.get_mut(prev_index){
226 if let Some(prev_node) = possible_prev_node{
227 prev_node.next = next
228 }
229 }
230 }
231 else {
232 return Err(OrderBookError::PrevNotFound);
233 }
234 if let Some(next_index) = next{
235 if let Some(possible_next_node) = self.bid.order_pool.get_mut(next_index){
236 if let Some(next_node) = possible_next_node{
237 next_node.prev = prev
238 }
239 }
240 }
241 else {
242 return Err(OrderBookError::NextNotFound);
243 }
244 self.bid.order_pool[*existing_index.unwrap()] = None;
245 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
246 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
247 self.bid.free_list.push(*existing_index.unwrap());
248 return Ok(());
249 }
250 } else {
251 self.bid.price_map.remove(&old_price);
252 return Err(OrderBookError::HeadTailCorrupted);
253 }
254 } else {
255 return Err(OrderBookError::NodeNotFound);
256 }
257 } else {
258 let existing_index = self.ask.order_registry.get(&order_id);
259 if existing_index.is_none(){
260 return Err(OrderBookError::OrderNotFound);
261 }
262 let (prev, next, old_price, old_quantity) = {
263 match self.ask.order_pool[*existing_index.unwrap()].as_ref(){
264 Some(node) => {
265 (node.prev, node.next, node.market_limit, node.current_quantity)
266 }
267 None => {
268 return Err(OrderBookError::NodeNotFound);
269 }
270 }
271 };
272 if let Some(price_level) = self.ask.price_map.get_mut(&old_price){
273
274 if price_level.head.is_some() && price_level.tail.is_some(){
275 if *existing_index.unwrap() == price_level.head.unwrap() && *existing_index.unwrap() == price_level.tail.unwrap(){
276 self.ask.order_pool[*existing_index.unwrap()] = None;
277 price_level.head = None;
278 price_level.tail = None;
279 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
280 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
281 self.ask.free_list.push(*existing_index.unwrap());
282 return Ok(());
283 }
284 else if *existing_index.unwrap() == price_level.tail.unwrap() {
285 if let Some(prev_index) = prev{
286 if let Some(possible_prev_node) = self.ask.order_pool.get_mut(prev_index){
287 if let Some(prev_node) = possible_prev_node{
288 prev_node.next = None;
289 price_level.tail = Some(prev_index);
290 }
291 }
292 self.ask.order_pool[*existing_index.unwrap()] = None;
293 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
294 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
295 self.ask.free_list.push(*existing_index.unwrap());
296 return Ok(());
297 } else {
298 return Err(OrderBookError::PrevNotFound);
299 }
300 }
301 else if *existing_index.unwrap() == price_level.head.unwrap() {
302 if let Some(next_index) = next{
303 if let Some(possible_next_node) = self.ask.order_pool.get_mut(next_index){
304 if let Some(next_node) = possible_next_node{
305 next_node.prev = None;
306 price_level.head = Some(next_index);
307 }
308 }
309 self.ask.order_pool[*existing_index.unwrap()] = None;
310 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
311 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
312 self.ask.free_list.push(*existing_index.unwrap());
313 return Ok(());
314 } else {
315 return Err(OrderBookError::NextNotFound);
316 }
317 }
318 else {
319 if let Some(prev_index) = prev{
320 if let Some(possible_prev_node) = self.ask.order_pool.get_mut(prev_index){
321 if let Some(prev_node) = possible_prev_node{
322 prev_node.next = next
323 }
324 }
325 }
326 else {
327 return Err(OrderBookError::PrevNotFound);
328 }
329 if let Some(next_index) = next{
330 if let Some(possible_next_node) = self.ask.order_pool.get_mut(next_index){
331 if let Some(next_node) = possible_next_node{
332 next_node.prev = prev
333 }
334 }
335 }
336 else {
337 return Err(OrderBookError::NextNotFound);
338 }
339 self.ask.order_pool[*existing_index.unwrap()] = None;
340 price_level.total_quantity = price_level.total_quantity.checked_sub(old_quantity).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
341 price_level.order_count = price_level.order_count.checked_sub(1).ok_or_else(|| OrderBookError::QuantityUnderflow)?;
342 self.ask.free_list.push(*existing_index.unwrap());
343 return Ok(());
344 }
345 } else {
346 self.ask.price_map.remove(&old_price);
347 return Err(OrderBookError::HeadTailCorrupted);
348 }
349 } else {
350 return Err(OrderBookError::NodeNotFound);
351 }
352 }
353 }
354
355 pub fn modify_order(&mut self, order_id : u64, order : EngineModifyOrder) -> Result<Option<ModifyOutcome>, OrderBookError>{
356 if order.is_buy_side{
357 let existing_index = self.bid.order_registry.get(&order_id);
358 if existing_index.is_none(){
359 return Err(OrderBookError::OrderNotFound);
360 }
361 let (old_initial_qty, old_current_qty, old_price) = {
362 match self.bid.order_pool[*existing_index.unwrap()].as_ref(){
363 Some(node) => {
364 (node.initial_quantity, node.current_quantity, node.market_limit)
365 }
366 None => {
367 return Err(OrderBookError::NodeNotFound);
368 }
369 }
370 };
371 if let Some(new_price) = order.new_price && let Some(new_qty) = order.new_quantity{
372 if new_price != old_price{
373 if let Ok(_) = self.cancel_order(order_id ,EngineCancelOrder { order_id : order.order_id, security_id : order.security_id, is_buy_side: order.is_buy_side,}){
374 return Ok(Some(ModifyOutcome::Both {new_price, new_initial_qty: new_qty, old_current_qty }));
375 }
376 }
377 return Ok(None);
378 } else if let Some(new_qty) = order.new_quantity {
379 if new_qty > old_initial_qty{
380 if let Ok(_) = self.cancel_order(order_id ,EngineCancelOrder { order_id : order.order_id,security_id : order.security_id, is_buy_side: order.is_buy_side,}){
381 return Ok(Some(ModifyOutcome::Requantized {old_price, new_initial_qty: new_qty, old_current_qty }))
382 }
383 return Ok(None);
384 }
385 else {
386 match self.bid.order_pool[*existing_index.unwrap()].as_mut(){
387 Some(order_node) => {
388 order_node.initial_quantity = new_qty;
389 return Ok(Some(ModifyOutcome::Inplace));
390 }
391 None => {
392 return Err(OrderBookError::NodeNotFound);
393 }
394 }
395 }
396 } else {
397 if let Ok(_) = self.cancel_order(order_id ,EngineCancelOrder { order_id : order.order_id,security_id : order.security_id, is_buy_side: order.is_buy_side,}){
398 return Ok(Some(ModifyOutcome::Repriced {new_price : order.new_price.unwrap(), old_initial_qty, old_current_qty }));
399 }
400 return Ok(None);
401 }
402 } else {
403 let existing_index = self.ask.order_registry.get(&order_id);
404 if existing_index.is_none(){
405 return Err(OrderBookError::OrderNotFound);
406 }
407 let (old_initial_qty, old_current_qty, old_price) = {
408 match self.ask.order_pool[*existing_index.unwrap()].as_ref(){
409 Some(node) => {
410 (node.initial_quantity, node.current_quantity, node.market_limit)
411 }
412 None => {
413 return Err(OrderBookError::NodeNotFound);
414 }
415 }
416 };
417
418 if let Some(new_price) = order.new_price && let Some(new_qty) = order.new_quantity{
419 if new_price != old_price{
420 if let Ok(_) = self.cancel_order(order_id ,EngineCancelOrder { order_id : order.order_id,security_id : order.security_id, is_buy_side: order.is_buy_side,}){
421 return Ok(Some(ModifyOutcome::Requantized {old_price, new_initial_qty: new_qty, old_current_qty }))
422 }
423 }
424 return Ok(None);
425 } else if let Some(new_qty) = order.new_quantity {
426 if new_qty > old_initial_qty{
427 if let Ok(_) = self.cancel_order(order_id ,EngineCancelOrder { order_id : order.order_id, security_id : order.security_id, is_buy_side: order.is_buy_side,}){
428 return Ok(Some(ModifyOutcome::Requantized { old_price, new_initial_qty: new_qty, old_current_qty }))
429 }
430 return Ok(None);
431 }
432 else {
433 match self.ask.order_pool[*existing_index.unwrap()].as_mut(){
434 Some(order_node) => {
435 order_node.initial_quantity = new_qty;
436 return Ok(Some(ModifyOutcome::Inplace));
437 }
438 None => {
439 return Err(OrderBookError::NodeNotFound);
440 }
441 }
442 }
443 }else {
444 if let Ok(_) = self.cancel_order(order_id ,EngineCancelOrder { order_id : order.order_id, security_id : order.security_id, is_buy_side: order.is_buy_side,}){
445 return Ok(Some(ModifyOutcome::Repriced { new_price : order.new_price.unwrap(), old_initial_qty, old_current_qty }));
446 }
447 return Ok(None);
448 }
449 }
450 }
451
452 pub fn depth(&self, levels_count : Option<u32>) -> Result<BookDepth, anyhow::Error>{
453 let timer = Instant::now();
454
455 let ask_iter = self.ask.price_map.iter().rev();
456 let bid_iter = self.bid.price_map.iter();
457
458 let ask_depth : Vec<_> = match levels_count {
459 Some(n) => ask_iter.take(n as usize)
460 .map(|(price, price_level)| PriceLevelDepth {
461 price_level : *price,
462 quantity : price_level.total_quantity
463 })
464 .collect(),
465 None => ask_iter.map(|(price, price_level)| PriceLevelDepth {
466 price_level : *price,
467 quantity : price_level.total_quantity
468 }).collect()
469 };
470 let bid_depth = match levels_count {
471 Some(n) => bid_iter.take(n as usize)
472 .map(|(price, price_level)| PriceLevelDepth {
473 price_level : *price,
474 quantity : price_level.total_quantity
475 })
476 .collect(),
477 None => bid_iter.map(|(price, price_level)| PriceLevelDepth {
478 price_level : *price,
479 quantity : price_level.total_quantity
480 }).collect()
481 };
482 let elapsed_time = timer.elapsed().as_micros() as f64;
483 Ok(BookDepth { bid_depth, ask_depth, timer : elapsed_time })
484 }
485}
486
487#[derive(Debug)]
488pub struct HalfBook{
489 pub price_map : BTreeMap<u32, PriceLevel>,
490 pub order_registry : HashMap<u64, usize>,
491 pub order_pool : Vec<Option<OrderNode>>,
492 pub free_list : Vec<usize>, }
494
495impl HalfBook {
496 pub fn new() -> Self{
497 Self { price_map: BTreeMap::new(), order_registry : HashMap::new(), order_pool: Vec::new(), free_list: Vec::new()}
498 }
499}