1use serde::{Deserialize, Serialize};
19use std::cmp::min;
20use std::fmt;
21use std::path::Path;
22
23use super::side::{get_ask_key, get_bid_key, AskSide, BidSide, SideFunctionality};
24use super::types::{
25 Event, Level1Data, Level2Data, Nanos, Order, OrderCount, OrderId, OrderKey, Price, Side,
26 Status, Trade, TraderId, Vol,
27};
28
29#[derive(Copy, Clone, Serialize, Deserialize)]
35pub struct OrderEntry {
36 order: Order,
38 key: OrderKey,
40}
41
42#[derive(Serialize, Deserialize)]
60#[serde(try_from = "OrderBookState<N>")]
61pub struct OrderBook<const N: usize = 10> {
62 t: Nanos,
66 tick_size: Price,
68 trade_vol: Vol,
70 #[serde(skip_serializing)]
72 ask_side: AskSide,
73 #[serde(skip_serializing)]
75 bid_side: BidSide,
76 orders: Vec<OrderEntry>,
80 trades: Vec<Trade>,
82 trading: bool,
87}
88
89#[derive(Debug, Clone)]
93pub enum OrderError {
94 PriceError { price: Price, tick_size: Price },
96}
97
98impl fmt::Display for OrderError {
99 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100 match self {
101 OrderError::PriceError { price, tick_size } => write!(
102 f,
103 "Price {} was not a multiple of tick-size {}",
104 price, tick_size
105 ),
106 }
107 }
108}
109
110impl<const N: usize> OrderBook<N> {
111 pub fn new(start_time: Nanos, tick_size: Price, trading: bool) -> Self {
125 Self {
126 t: start_time,
127 tick_size,
128 trade_vol: 0,
129 ask_side: AskSide::new(),
130 bid_side: BidSide::new(),
131 orders: Vec::new(),
132 trades: Vec::new(),
133 trading,
134 }
135 }
136
137 pub fn get_time(&self) -> Nanos {
139 self.t
140 }
141
142 pub fn set_time(&mut self, t: Nanos) {
146 self.t = t;
147 }
148
149 pub fn enable_trading(&mut self) {
151 self.trading = true;
152 }
153
154 pub fn disable_trading(&mut self) {
159 self.trading = false;
160 }
161
162 pub fn get_trade_vol(&self) -> Vol {
164 self.trade_vol
165 }
166
167 pub fn reset_trade_vol(&mut self) {
169 self.trade_vol = 0;
170 }
171
172 pub fn ask_vol(&self) -> Vol {
174 self.ask_side.vol()
175 }
176
177 pub fn ask_best_vol(&self) -> Vol {
179 self.ask_side.best_vol()
180 }
181
182 pub fn ask_best_vol_and_orders(&self) -> (Vol, OrderCount) {
184 self.ask_side.best_vol_and_orders()
185 }
186
187 pub fn ask_levels(&self) -> [(Vol, OrderCount); N] {
192 let start = self.bid_ask().1;
193 core::array::from_fn(|i| {
194 self.ask_side.vol_and_orders_at_price(
195 start.wrapping_add(Price::try_from(i).unwrap() * self.tick_size),
196 )
197 })
198 }
199
200 pub fn bid_vol(&self) -> Vol {
202 self.bid_side.vol()
203 }
204
205 pub fn bid_best_vol(&self) -> Vol {
207 self.bid_side.best_vol()
208 }
209
210 pub fn bid_best_vol_and_orders(&self) -> (Vol, OrderCount) {
212 self.bid_side.best_vol_and_orders()
213 }
214
215 pub fn bid_levels(&self) -> [(Vol, OrderCount); N] {
220 let start = self.bid_ask().0;
221 core::array::from_fn(|i| {
222 self.bid_side.vol_and_orders_at_price(
223 start.wrapping_sub(Price::try_from(i).unwrap() * self.tick_size),
224 )
225 })
226 }
227
228 pub fn bid_ask(&self) -> (Price, Price) {
230 (self.bid_side.best_price(), self.ask_side.best_price())
231 }
232
233 pub fn mid_price(&self) -> f64 {
235 let (bid, ask) = self.bid_ask();
236 let spread = ask - bid;
237 f64::from(bid) + 0.5 * f64::from(spread)
238 }
239
240 pub fn level_1_data(&self) -> Level1Data {
250 let (bid_price, ask_price) = self.bid_ask();
251 let (bid_touch_vol, bid_touch_orders) = self.bid_best_vol_and_orders();
252 let (ask_touch_vol, ask_touch_orders) = self.ask_best_vol_and_orders();
253 Level1Data {
254 bid_price,
255 ask_price,
256 bid_vol: self.bid_vol(),
257 ask_vol: self.ask_vol(),
258 bid_touch_vol,
259 ask_touch_vol,
260 bid_touch_orders,
261 ask_touch_orders,
262 }
263 }
264
265 pub fn level_2_data(&self) -> Level2Data<N> {
277 let (bid_price, ask_price) = self.bid_ask();
278 Level2Data {
279 bid_price,
280 ask_price,
281 bid_vol: self.bid_vol(),
282 ask_vol: self.ask_vol(),
283 bid_price_levels: self.bid_levels(),
284 ask_price_levels: self.ask_levels(),
285 }
286 }
287
288 fn current_order_id(&self) -> OrderId {
290 self.orders.len()
291 }
292
293 pub fn order(&self, order_id: OrderId) -> &Order {
300 &self.orders[order_id].order
301 }
302
303 pub fn create_order(
319 &mut self,
320 side: Side,
321 vol: Vol,
322 trader_id: TraderId,
323 price: Option<Price>,
324 ) -> Result<OrderId, OrderError> {
325 let order_id = self.current_order_id();
326
327 let order = match (side, price) {
328 (Side::Bid, Some(p)) => {
329 if p % self.tick_size != 0 {
330 return Err(OrderError::PriceError {
331 price: p,
332 tick_size: self.tick_size,
333 });
334 }
335 Order::buy_limit(self.t, vol, p, trader_id, order_id)
336 }
337 (Side::Bid, None) => Order::buy_market(self.t, vol, trader_id, order_id),
338 (Side::Ask, Some(p)) => {
339 if p % self.tick_size != 0 {
340 return Err(OrderError::PriceError {
341 price: p,
342 tick_size: self.tick_size,
343 });
344 }
345 Order::sell_limit(self.t, vol, p, trader_id, order_id)
346 }
347 (Side::Ask, None) => Order::sell_market(self.t, vol, trader_id, order_id),
348 };
349
350 let key = match side {
351 Side::Bid => get_bid_key(0, order.price),
352 Side::Ask => get_ask_key(0, order.price),
353 };
354
355 self.orders.push(OrderEntry { order, key });
356
357 Ok(order_id)
358 }
359
360 pub fn create_and_place_order(
374 &mut self,
375 side: Side,
376 vol: Vol,
377 trader_id: TraderId,
378 price: Option<Price>,
379 ) -> Result<OrderId, OrderError> {
380 let order_id = self.create_order(side, vol, trader_id, price)?;
381 self.place_order(order_id);
382 Ok(order_id)
383 }
384
385 fn match_bid(&mut self, order_entry: &mut OrderEntry) {
392 while (order_entry.order.vol > 0) & (order_entry.order.price >= self.ask_side.best_price())
393 {
394 let next_order_id = self.ask_side.best_order_idx();
395 match next_order_id {
396 Some(id) => {
397 let match_order = &mut self.orders.get_mut(id).unwrap();
398 let trade_vol = match_orders(
399 self.t,
400 &mut order_entry.order,
401 &mut match_order.order,
402 &mut self.trades,
403 );
404 self.trade_vol += trade_vol;
405 if match_order.order.status == Status::Filled {
406 self.ask_side.remove_order(match_order.key, trade_vol);
407 } else {
408 self.ask_side.remove_vol(match_order.key.1, trade_vol);
409 }
410 }
411 None => {
412 break;
413 }
414 }
415 }
416 }
417
418 fn match_ask(&mut self, order_entry: &mut OrderEntry) {
425 while (order_entry.order.vol > 0) & (order_entry.order.price <= self.bid_side.best_price())
426 {
427 let next_order_id = self.bid_side.best_order_idx();
428 match next_order_id {
429 Some(id) => {
430 let match_order = &mut self.orders.get_mut(id).unwrap();
431 let trade_vol = match_orders(
432 self.t,
433 &mut order_entry.order,
434 &mut match_order.order,
435 &mut self.trades,
436 );
437 self.trade_vol += trade_vol;
438 if match_order.order.status == Status::Filled {
439 self.bid_side.remove_order(match_order.key, trade_vol);
440 } else {
441 self.bid_side.remove_vol(match_order.key.1, trade_vol);
442 }
443 }
444 None => {
445 break;
446 }
447 }
448 }
449 }
450
451 fn place_bid_limit(&mut self, order_entry: &mut OrderEntry) {
458 if self.trading {
459 self.match_bid(order_entry);
460 }
461 if order_entry.order.status != Status::Filled {
462 let key: OrderKey = (Side::Bid, order_entry.key.1, self.t);
463 order_entry.key = key;
464 self.bid_side
465 .insert_order(key, order_entry.order.order_id, order_entry.order.vol)
466 }
467 }
468
469 fn place_bid_market(&mut self, order_entry: &mut OrderEntry) {
480 match self.trading {
481 true => {
482 self.match_bid(order_entry);
483 if order_entry.order.status != Status::Filled {
484 order_entry.order.status = Status::Cancelled;
485 order_entry.order.end_time = self.t;
486 }
487 }
488 false => {
489 order_entry.order.status = Status::Rejected;
490 order_entry.order.end_time = self.t;
491 }
492 }
493 }
494
495 fn place_ask_limit(&mut self, order_entry: &mut OrderEntry) {
501 if self.trading {
502 self.match_ask(order_entry);
503 }
504 if order_entry.order.status != Status::Filled {
505 let key: OrderKey = (Side::Ask, order_entry.key.1, self.t);
506 order_entry.key = key;
507 self.ask_side
508 .insert_order(key, order_entry.order.order_id, order_entry.order.vol)
509 }
510 }
511
512 fn place_ask_market(&mut self, order_entry: &mut OrderEntry) {
523 match self.trading {
524 true => {
525 self.match_ask(order_entry);
526 if order_entry.order.status != Status::Filled {
527 order_entry.order.status = Status::Cancelled;
528 order_entry.order.end_time = self.t;
529 }
530 }
531 false => {
532 order_entry.order.status = Status::Rejected;
533 order_entry.order.end_time = self.t;
534 }
535 }
536 }
537
538 pub fn place_order(&mut self, order_id: OrderId) {
546 let mut order_entry = self.orders[order_id];
547
548 if order_entry.order.status != Status::New {
549 return;
550 }
551
552 order_entry.order.status = Status::Active;
553 order_entry.order.arr_time = self.t;
554
555 match order_entry.order.side {
556 Side::Bid => {
557 if order_entry.order.price == Price::MAX {
558 self.place_bid_market(&mut order_entry)
559 } else {
560 self.place_bid_limit(&mut order_entry)
561 }
562 }
563 Side::Ask => {
564 if order_entry.order.price == 0 {
565 self.place_ask_market(&mut order_entry)
566 } else {
567 self.place_ask_limit(&mut order_entry)
568 }
569 }
570 }
571
572 self.orders[order_id] = order_entry;
573 }
574
575 pub fn cancel_order(&mut self, order_id: OrderId) {
585 let cancelled_order = self.orders.get_mut(order_id);
586
587 match cancelled_order {
588 Some(order_entry) => {
589 if order_entry.order.status == Status::Active {
590 order_entry.order.status = Status::Cancelled;
591 order_entry.order.end_time = self.t;
592 match order_entry.key.0 {
593 Side::Bid => {
594 self.bid_side
595 .remove_order(order_entry.key, order_entry.order.vol);
596 }
597 Side::Ask => {
598 self.ask_side
599 .remove_order(order_entry.key, order_entry.order.vol);
600 }
601 }
602 }
603 }
604 None => panic!("No order with id {} exists", order_id),
605 }
606 }
607
608 fn reduce_order_vol(&mut self, order_entry: &mut OrderEntry, reduce_vol: Vol) {
619 match order_entry.key.0 {
620 Side::Bid => {
621 order_entry.order.vol -= reduce_vol;
622 self.bid_side.remove_vol(order_entry.key.1, reduce_vol)
623 }
624 Side::Ask => {
625 order_entry.order.vol -= reduce_vol;
626 self.ask_side.remove_vol(order_entry.key.1, reduce_vol)
627 }
628 }
629 }
630
631 fn replace_order(&mut self, order_entry: &mut OrderEntry, new_price: Price, new_vol: Vol) {
642 match order_entry.key.0 {
643 Side::Bid => self
644 .bid_side
645 .remove_order(order_entry.key, order_entry.order.vol),
646 Side::Ask => self
647 .ask_side
648 .remove_order(order_entry.key, order_entry.order.vol),
649 }
650
651 order_entry.order.vol = new_vol;
652 order_entry.order.price = new_price;
653
654 if self.trading {
655 match order_entry.key.0 {
656 Side::Bid => self.match_bid(order_entry),
657 Side::Ask => self.match_ask(order_entry),
658 }
659 }
660
661 if order_entry.order.status != Status::Filled {
662 match order_entry.key.0 {
663 crate::types::Side::Bid => {
664 let key: OrderKey = get_bid_key(self.t, new_price);
665 order_entry.key = key;
666
667 self.bid_side.insert_order(
668 key,
669 order_entry.order.order_id,
670 order_entry.order.vol,
671 );
672 }
673 crate::types::Side::Ask => {
674 let key: OrderKey = get_ask_key(self.t, new_price);
675 order_entry.key = key;
676
677 self.ask_side.insert_order(
678 key,
679 order_entry.order.order_id,
680 order_entry.order.vol,
681 );
682 }
683 }
684 }
685 }
686
687 pub fn modify_order(
706 &mut self,
707 order_id: OrderId,
708 new_price: Option<Price>,
709 new_vol: Option<Price>,
710 ) {
711 let mut order_entry = self.orders[order_id];
712
713 if order_entry.order.status == Status::Active {
714 match (new_price, new_vol) {
715 (None, None) => (),
716 (None, Some(v)) => {
717 if v < order_entry.order.vol {
718 let reduce_vol = order_entry.order.vol - v;
719 self.reduce_order_vol(&mut order_entry, reduce_vol);
720 } else {
721 let p = order_entry.order.price;
722 self.replace_order(&mut order_entry, p, v)
723 }
724 }
725 (Some(p), None) => {
726 let v = order_entry.order.vol;
727 self.replace_order(&mut order_entry, p, v);
728 }
729 (Some(p), Some(v)) => self.replace_order(&mut order_entry, p, v),
730 }
731 }
732
733 self.orders[order_id] = order_entry;
734 }
735
736 pub fn process_event(&mut self, event: Event) {
745 match event {
746 Event::New { order_id } => self.place_order(order_id),
747 Event::Cancellation { order_id } => self.cancel_order(order_id),
748 Event::Modify {
749 order_id,
750 new_price,
751 new_vol,
752 } => self.modify_order(order_id, new_price, new_vol),
753 }
754 }
755
756 pub fn get_orders(&self) -> Vec<&Order> {
758 self.orders.iter().map(|x| &x.order).collect()
759 }
760
761 pub fn get_trades(&self) -> &Vec<Trade> {
763 &self.trades
764 }
765
766 pub fn save_json<P: AsRef<Path>>(&self, path: P, pretty: bool) -> std::io::Result<()> {
774 let file = std::fs::File::create(path)?;
775 let file = std::io::BufWriter::new(file);
776 match pretty {
777 true => serde_json::to_writer_pretty(file, self)?,
778 false => serde_json::to_writer(file, self)?,
779 }
780 Ok(())
781 }
782
783 pub fn load_json<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
790 let file = std::fs::File::open(path)?;
791 let file = std::io::BufReader::new(file);
792 let order_book: Self = serde_json::from_reader(file)?;
793 Ok(order_book)
794 }
795}
796
797fn match_orders(
806 t: Nanos,
807 agg_order: &mut Order,
808 pass_order: &mut Order,
809 trades: &mut Vec<Trade>,
810) -> Vol {
811 let trade_vol = min(agg_order.vol, pass_order.vol);
812 agg_order.vol -= trade_vol;
813 pass_order.vol -= trade_vol;
814 trades.push(Trade {
815 t,
816 side: pass_order.side,
817 price: pass_order.price,
818 vol: trade_vol,
819 active_order_id: agg_order.order_id,
820 passive_order_id: pass_order.order_id,
821 });
822 if pass_order.vol == 0 {
823 pass_order.end_time = t;
824 pass_order.status = Status::Filled;
825 };
826 if agg_order.vol == 0 {
827 agg_order.end_time = t;
828 agg_order.status = Status::Filled;
829 };
830
831 trade_vol
832}
833
834#[derive(Deserialize)]
836struct OrderBookState<const N: usize = 10> {
837 t: Nanos,
838 tick_size: Price,
839 trade_vol: Vol,
840 orders: Vec<OrderEntry>,
841 trades: Vec<Trade>,
842 trading: bool,
843}
844
845struct OrderBookConversionErrror;
846
847impl fmt::Display for OrderBookConversionErrror {
848 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
849 write!(f, "Failed to convert OrderBookState to an OrderBook")
850 }
851}
852
853impl<const N: usize> std::convert::TryFrom<OrderBookState<N>> for OrderBook<{ N }> {
854 type Error = OrderBookConversionErrror;
855
856 fn try_from(state: OrderBookState<N>) -> Result<Self, Self::Error> {
857 let mut bid_side = BidSide::default();
858 let mut ask_side = AskSide::default();
859
860 for OrderEntry { order, key } in state.orders.iter() {
861 if order.status == Status::Active {
862 match order.side {
863 Side::Bid => bid_side.insert_order(*key, order.order_id, order.vol),
864 Side::Ask => ask_side.insert_order(*key, order.order_id, order.vol),
865 }
866 }
867 }
868
869 Ok(Self {
870 t: state.t,
871 tick_size: state.tick_size,
872 trade_vol: state.trade_vol,
873 ask_side,
874 bid_side,
875 orders: state.orders,
876 trades: state.trades,
877 trading: state.trading,
878 })
879 }
880}
881
882#[cfg(test)]
883mod tests {
884
885 use super::*;
886
887 #[test]
888 fn test_init() {
889 let book: OrderBook = OrderBook::new(0, 1, true);
890
891 assert!(book.bid_vol() == 0);
892 assert!(book.ask_vol() == 0);
893 assert!(book.bid_best_vol() == 0);
894 assert!(book.bid_best_vol_and_orders() == (0, 0));
895 assert!(book.bid_best_vol() == 0);
896 assert!(book.ask_best_vol_and_orders() == (0, 0));
897 assert!(book.bid_ask() == (0, Price::MAX))
898 }
899
900 #[test]
901 fn test_insert_order() {
902 let mut book: OrderBook = OrderBook::new(0, 1, true);
903
904 book.create_and_place_order(Side::Ask, 10, 0, Some(100))
905 .unwrap();
906 book.create_and_place_order(Side::Bid, 10, 0, Some(50))
907 .unwrap();
908
909 assert!(book.bid_ask() == (50, 100));
910 assert!(book.ask_vol() == 10);
911 assert!(book.bid_vol() == 10);
912 assert!(book.bid_best_vol() == 10);
913 assert!(book.bid_best_vol_and_orders() == (10, 1));
914 assert!(book.ask_best_vol() == 10);
915 assert!(book.ask_best_vol_and_orders() == (10, 1));
916
917 book.create_and_place_order(Side::Ask, 10, 0, Some(90))
918 .unwrap();
919 book.create_and_place_order(Side::Bid, 10, 0, Some(60))
920 .unwrap();
921
922 assert!(book.bid_ask() == (60, 90));
923 assert!(book.ask_vol() == 20);
924 assert!(book.bid_vol() == 20);
925 assert!(book.bid_best_vol() == 10);
926 assert!(book.bid_best_vol_and_orders() == (10, 1));
927 assert!(book.ask_best_vol() == 10);
928 assert!(book.ask_best_vol_and_orders() == (10, 1));
929
930 book.create_and_place_order(Side::Ask, 10, 0, Some(110))
931 .unwrap();
932 book.create_and_place_order(Side::Bid, 10, 0, Some(40))
933 .unwrap();
934
935 assert!(book.bid_ask() == (60, 90));
936 assert!(book.ask_vol() == 30);
937 assert!(book.bid_vol() == 30);
938 assert!(book.bid_best_vol() == 10);
939 assert!(book.bid_best_vol_and_orders() == (10, 1));
940 assert!(book.ask_best_vol() == 10);
941 assert!(book.ask_best_vol_and_orders() == (10, 1));
942 }
943
944 #[test]
945 fn test_level_data() {
946 let mut book = OrderBook::<4>::new(0, 2, true);
947
948 let bid_levels = book.bid_levels();
949
950 assert!(bid_levels.len() == 4);
951 assert!(bid_levels == [(0, 0), (0, 0), (0, 0), (0, 0)]);
952
953 let ask_levels = book.ask_levels();
954
955 assert!(ask_levels.len() == 4);
956 assert!(ask_levels == [(0, 0), (0, 0), (0, 0), (0, 0)]);
957
958 book.create_and_place_order(Side::Bid, 10, 0, Some(100))
959 .unwrap();
960 book.create_and_place_order(Side::Bid, 10, 0, Some(100))
961 .unwrap();
962 book.create_and_place_order(Side::Bid, 12, 0, Some(98))
963 .unwrap();
964 book.create_and_place_order(Side::Bid, 14, 0, Some(94))
965 .unwrap();
966
967 book.create_and_place_order(Side::Ask, 11, 0, Some(102))
968 .unwrap();
969 book.create_and_place_order(Side::Ask, 11, 0, Some(102))
970 .unwrap();
971 book.create_and_place_order(Side::Ask, 13, 0, Some(104))
972 .unwrap();
973 book.create_and_place_order(Side::Ask, 15, 0, Some(108))
974 .unwrap();
975
976 let bid_levels = book.bid_levels();
977
978 assert!(bid_levels.len() == 4);
979 assert!(bid_levels == [(20, 2), (12, 1), (0, 0), (14, 1)]);
980
981 let ask_levels = book.ask_levels();
982
983 assert!(ask_levels.len() == 4);
984 assert!(ask_levels == [(22, 2), (13, 1), (0, 0), (15, 1)]);
985
986 assert!(matches!(
987 book.level_1_data(),
988 Level1Data {
989 bid_price: 100,
990 ask_price: 102,
991 bid_vol: 46,
992 ask_vol: 50,
993 bid_touch_vol: 20,
994 ask_touch_vol: 22,
995 bid_touch_orders: 2,
996 ask_touch_orders: 2,
997 }
998 ));
999
1000 assert!(matches!(
1001 book.level_2_data(),
1002 Level2Data {
1003 bid_price: 100,
1004 ask_price: 102,
1005 bid_vol: 46,
1006 ask_vol: 50,
1007 bid_price_levels: [(20, 2), (12, 1), (0, 0), (14, 1)],
1008 ask_price_levels: [(22, 2), (13, 1), (0, 0), (15, 1)],
1009 }
1010 ));
1011 }
1012
1013 #[test]
1014 fn test_cancel_order() {
1015 let mut book: OrderBook = OrderBook::new(0, 1, true);
1016
1017 book.create_and_place_order(Side::Ask, 10, 0, Some(100))
1018 .unwrap();
1019 book.create_and_place_order(Side::Bid, 10, 0, Some(50))
1020 .unwrap();
1021 book.create_and_place_order(Side::Ask, 10, 0, Some(90))
1022 .unwrap();
1023 book.create_and_place_order(Side::Bid, 10, 0, Some(60))
1024 .unwrap();
1025
1026 assert!(book.bid_ask() == (60, 90));
1027 assert!(book.ask_vol() == 20);
1028 assert!(book.bid_vol() == 20);
1029 assert!(book.bid_best_vol() == 10);
1030 assert!(book.ask_best_vol() == 10);
1031 assert!(book.bid_best_vol_and_orders() == (10, 1));
1032 assert!(book.ask_best_vol_and_orders() == (10, 1));
1033
1034 book.cancel_order(0);
1035 book.cancel_order(3);
1036
1037 assert!(book.bid_ask() == (50, 90));
1038 assert!(book.ask_vol() == 10);
1039 assert!(book.bid_vol() == 10);
1040 assert!(book.bid_best_vol() == 10);
1041 assert!(book.ask_best_vol() == 10);
1042 assert!(book.bid_best_vol_and_orders() == (10, 1));
1043 assert!(book.ask_best_vol_and_orders() == (10, 1));
1044
1045 book.cancel_order(1);
1046 book.cancel_order(2);
1047
1048 assert!(book.bid_ask() == (0, Price::MAX));
1049 assert!(book.ask_vol() == 0);
1050 assert!(book.bid_vol() == 0);
1051 assert!(book.bid_best_vol() == 0);
1052 assert!(book.ask_best_vol() == 0);
1053 assert!(book.bid_best_vol_and_orders() == (0, 0));
1054 assert!(book.ask_best_vol_and_orders() == (0, 0));
1055
1056 assert!(matches!(book.orders[0].order.status, Status::Cancelled));
1057 assert!(matches!(book.orders[1].order.status, Status::Cancelled));
1058 assert!(matches!(book.orders[2].order.status, Status::Cancelled));
1059 assert!(matches!(book.orders[3].order.status, Status::Cancelled));
1060 }
1061
1062 #[test]
1063 fn test_mod_order_vol() {
1064 let mut book: OrderBook = OrderBook::new(0, 1, true);
1065
1066 book.create_and_place_order(Side::Ask, 10, 0, Some(100))
1067 .unwrap();
1068 book.create_and_place_order(Side::Bid, 10, 0, Some(50))
1069 .unwrap();
1070
1071 book.modify_order(0, None, Some(8));
1072 book.modify_order(1, None, Some(5));
1073
1074 assert!(book.ask_vol() == 8);
1075 assert!(book.ask_best_vol() == 8);
1076 assert!(book.ask_best_vol_and_orders() == (8, 1));
1077 assert!(book.bid_vol() == 5);
1078 assert!(book.bid_best_vol() == 5);
1079 assert!(book.bid_best_vol_and_orders() == (5, 1));
1080
1081 assert!(book.orders[0].order.vol == 8);
1082 assert!(book.orders[1].order.vol == 5);
1083 }
1084
1085 #[test]
1086 fn test_modify_order() {
1087 let mut book: OrderBook = OrderBook::new(0, 1, true);
1088
1089 book.create_and_place_order(Side::Ask, 10, 0, Some(100))
1090 .unwrap();
1091 book.create_and_place_order(Side::Bid, 10, 0, Some(50))
1092 .unwrap();
1093
1094 assert!(book.bid_ask() == (50, 100));
1095
1096 book.modify_order(0, Some(110), Some(15));
1097 book.modify_order(1, Some(60), Some(20));
1098
1099 assert!(book.ask_vol() == 15);
1100 assert!(book.ask_best_vol() == 15);
1101 assert!(book.bid_vol() == 20);
1102 assert!(book.bid_best_vol() == 20);
1103 assert!(book.bid_ask() == (60, 110));
1104 }
1105
1106 #[test]
1107 fn test_modify_order_crossing() {
1108 let mut book: OrderBook = OrderBook::new(0, 1, true);
1109
1110 book.create_and_place_order(Side::Ask, 10, 0, Some(100))
1111 .unwrap();
1112 book.create_and_place_order(Side::Bid, 10, 0, Some(50))
1113 .unwrap();
1114
1115 assert!(book.bid_ask() == (50, 100));
1116
1117 book.modify_order(1, Some(100), Some(20));
1118
1119 assert!(book.ask_vol() == 0);
1120 assert!(book.ask_best_vol() == 0);
1121 assert!(book.ask_best_vol_and_orders() == (0, 0));
1122 assert!(book.bid_vol() == 10);
1123 assert!(book.bid_best_vol() == 10);
1124 assert!(book.bid_best_vol_and_orders() == (10, 1));
1125 assert!(book.bid_ask() == (100, Price::MAX));
1126
1127 assert!(book.trades.len() == 1);
1128 assert!(book.trades[0].price == 100);
1129 assert!(book.trades[0].vol == 10);
1130 }
1131
1132 #[test]
1133 fn test_trades() {
1134 let mut book: OrderBook = OrderBook::new(0, 1, true);
1135
1136 book.create_order(Side::Ask, 101, 101, Some(20)).unwrap();
1137 book.create_order(Side::Ask, 101, 101, Some(18)).unwrap();
1138 book.create_order(Side::Bid, 202, 101, Some(12)).unwrap();
1139 book.create_order(Side::Bid, 202, 101, Some(14)).unwrap();
1140
1141 book.place_order(0);
1142 book.set_time(1);
1143 book.place_order(1);
1144 book.set_time(2);
1145 book.place_order(2);
1146 book.set_time(3);
1147 book.place_order(3);
1148 book.set_time(4);
1149
1150 book.create_order(Side::Bid, 102, 101, None).unwrap();
1151 book.place_order(4);
1152
1153 assert!(book.ask_vol() == 100);
1154 assert!(book.bid_ask() == (14, 20));
1155
1156 assert!(book.trades.len() == 2);
1157 assert!(book.trades[0].price == 18);
1158 assert!(book.trades[0].vol == 101);
1159 assert!(book.trades[1].price == 20);
1160 assert!(book.trades[1].vol == 1);
1161 assert!(book.get_trade_vol() == 102);
1162
1163 book.create_order(Side::Ask, 204, 101, Some(14)).unwrap();
1164 book.place_order(5);
1165
1166 assert!(book.bid_vol() == 202);
1167 assert!(book.ask_vol() == 102);
1168 assert!(book.bid_best_vol_and_orders() == (202, 1));
1169 assert!(book.ask_best_vol_and_orders() == (2, 1));
1170 assert!(book.bid_ask() == (12, 14));
1171
1172 assert!(book.trades.len() == 3);
1173 assert!(book.trades[2].price == 14);
1174 assert!(book.trades[2].vol == 202);
1175 assert!(book.get_trade_vol() == 304);
1176 }
1177
1178 #[test]
1179 fn test_market_order_no_trading() {
1180 let mut book: OrderBook = OrderBook::new(0, 1, false);
1181
1182 book.create_and_place_order(Side::Bid, 101, 101, None)
1183 .unwrap();
1184
1185 assert!(book.bid_ask() == (0, Price::MAX));
1186 assert!(book.bid_vol() == 0);
1187 assert!(book.ask_vol() == 0);
1188 assert!(book.orders[0].order.status == Status::Rejected);
1189 }
1190
1191 #[test]
1192 fn test_unfilled_market_order() {
1193 let mut book: OrderBook = OrderBook::new(0, 1, true);
1194
1195 book.create_and_place_order(Side::Ask, 10, 101, Some(50))
1196 .unwrap();
1197 book.create_and_place_order(Side::Bid, 20, 101, None)
1198 .unwrap();
1199
1200 assert!(book.bid_ask() == (0, Price::MAX));
1201 assert!(book.bid_vol() == 0);
1202 assert!(book.ask_vol() == 0);
1203 assert!(book.orders[1].order.status == Status::Cancelled);
1204 }
1205
1206 #[test]
1207 fn test_incorrect_price_err() {
1208 let mut book: OrderBook = OrderBook::new(0, 2, true);
1209
1210 let res = book.create_order(Side::Ask, 100, 101, Some(51));
1211
1212 assert!(res.is_err_and(|e| matches!(
1213 e,
1214 OrderError::PriceError {
1215 price: 51,
1216 tick_size: 2
1217 }
1218 )));
1219 }
1220
1221 #[test]
1222 fn test_no_double_place() {
1223 let mut book: OrderBook = OrderBook::new(0, 2, true);
1224
1225 let id = book.create_order(Side::Ask, 100, 101, Some(50)).unwrap();
1226
1227 book.place_order(id);
1228
1229 assert!(book.bid_ask() == (0, 50));
1230 assert!(book.ask_best_vol_and_orders() == (100, 1));
1231
1232 book.place_order(id);
1233
1234 assert!(book.bid_ask() == (0, 50));
1235 assert!(book.ask_best_vol_and_orders() == (100, 1));
1236 }
1237
1238 #[test]
1239 fn test_serialisation() {
1240 use rand::{seq::SliceRandom, Rng};
1241 use rand_xoshiro::rand_core::SeedableRng;
1242 use rand_xoshiro::Xoroshiro128Plus;
1243
1244 let mut book: OrderBook = OrderBook::new(0, 1, true);
1245
1246 let mut rng = Xoroshiro128Plus::seed_from_u64(101);
1247
1248 for i in (0..200).into_iter() {
1249 let side = [Side::Bid, Side::Ask].choose(&mut rng).unwrap();
1250 let price = rng.gen_range(20..40);
1251 let vol = rng.gen_range(5..20);
1252 book.create_and_place_order(*side, vol, 0, Some(price))
1253 .unwrap();
1254 book.set_time(i);
1255 }
1256
1257 let book_snapshot = serde_json::to_string(&book).unwrap();
1258 let loaded_book = serde_json::from_str::<OrderBook>(book_snapshot.as_str()).unwrap();
1259
1260 assert!(book.trading == loaded_book.trading);
1261 assert!(book.trade_vol == loaded_book.trade_vol);
1262
1263 assert!(book.bid_ask() == loaded_book.bid_ask());
1264
1265 assert!(book.bid_best_vol_and_orders() == loaded_book.bid_best_vol_and_orders());
1266 assert!(book.bid_vol() == loaded_book.bid_vol());
1267
1268 assert!(book.ask_best_vol_and_orders() == loaded_book.ask_best_vol_and_orders());
1269 assert!(book.bid_vol() == loaded_book.bid_vol());
1270
1271 assert!(book.current_order_id() == loaded_book.current_order_id());
1272
1273 assert!(book.bid_side.best_order_idx() == loaded_book.bid_side.best_order_idx());
1274 assert!(book.ask_side.best_order_idx() == loaded_book.ask_side.best_order_idx());
1275 }
1276}