matching_engine/model/
domain.rs

1use std::collections::{HashMap, VecDeque};
2use std::fmt::{Display, Formatter};
3use std::hash::{Hash, Hasher};
4
5
6use colored::Colorize;
7use prettytable::{row, Table};
8use serde::{Deserialize, Serialize};
9
10use crate::model::domain::OrderType::{Limit, Market};
11use crate::model::domain::Side::{Buy, Sell};
12use crate::model::domain::Status::{Filled, New, PartialFill, PendingNew, Rejected, Replaced, UNKNOWN};
13use crate::utils::{Aggregator, generate_id, Sigma};
14
15///Order TYpe . Can be either Limit or Market
16#[derive(PartialEq, Debug, Eq, Clone, Copy, Serialize, Deserialize)]
17pub enum OrderType {
18    Market,
19    Limit,
20}
21
22impl OrderType {
23    pub fn string_value(&self) -> String {
24        match self {
25            Limit => "Limit".to_owned(),
26            Market => "Market".to_owned()
27        }
28    }
29
30    pub fn from(str: &String) -> Self {
31        if str == "Limit" {
32            OrderType::Limit
33        } else {
34            OrderType::Market
35        }
36    }
37}
38
39impl Default for OrderType {
40    fn default() -> Self {
41        Limit
42    }
43}
44
45#[derive(PartialEq, Debug, Eq, Clone, Copy, Serialize, Deserialize)]
46pub enum Side {
47    Buy,
48    Sell,
49}
50
51/// Side of the order. Can be either Buy or Sell
52impl Side {
53    pub fn string_value(&self) -> String {
54        match self {
55            Buy => "Buy".to_owned(),
56            Sell => "Sell".to_owned()
57        }
58    }
59
60    pub fn from(str: &String) -> Self {
61        if str == "Buy" {
62            Side::Buy
63        } else {
64            Side::Sell
65        }
66    }
67}
68
69impl Default for Side {
70    fn default() -> Self {
71        Buy
72    }
73}
74
75///Order Status and Execution Status. Can be one of New,
76///    PendingNew,
77///    PartialFill,
78///    Filled,
79///     Rejected,
80///     Replaced,
81#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
82pub enum Status {
83    New,
84    PendingNew,
85    PartialFill,
86    Filled,
87    Rejected,
88    Replaced,
89    UNKNOWN,
90}
91
92impl Status {
93    ///Returns the FIX specific character for the status as per FIX specification
94    pub fn char_value(&self) -> char {
95        match self {
96            New => '0',
97            PendingNew => 'A',
98            PartialFill => '1',
99            Filled => '2',
100            Rejected => '4',
101            Replaced => '5',
102            UNKNOWN => 'U'
103        }
104    }
105
106    pub fn string_value(&self) -> &str {
107        match self {
108            New => "New",
109            PendingNew => "Pending",
110            PartialFill => "PartialFill",
111            Filled => "Filled",
112            Rejected => "Rejected",
113            Replaced => "Replaced",
114            UNKNOWN => "???"
115        }
116    }
117}
118
119impl Eq for Status {}
120
121impl PartialEq for Status {
122    fn eq(&self, other: &Self) -> bool {
123        self.char_value() == other.char_value()
124    }
125}
126
127///Defines an order.
128#[derive(Debug, Clone, Default, Serialize, Deserialize)]
129pub struct OrderSingle {
130    qty: u32,
131    symbol: String,
132    price: f64,
133    side: Side,
134    order_type: OrderType,
135    cl_ord_id: String,
136}
137
138///Defines a Fill from an Execution
139#[derive(Debug, Clone,
140Serialize, Deserialize)]
141pub struct Fill {
142    symbol: String,
143    order_id: String,
144    execution_id: String,
145    exec_type: Status,
146    qty: u32,
147    leaves_qty: u32,
148    cum_qty: u32,
149    price: f64,
150    side: Side,
151    cl_ord_id: String,
152    secondary_cl_ord_id: String,
153    status: Status,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct OrderBookKey {
158    price: f64,
159    symbol: String,
160}
161
162///The key on which [`OrderSingle`] instances are stored in the [`OrderBook`]
163impl OrderBookKey {
164    pub fn new(price: f64, symbol: String) -> Self {
165        Self { price, symbol }
166    }
167
168    pub fn is_valid(&self) -> bool {
169        self.price > 0.0 && self.symbol.len() > 0
170    }
171}
172
173impl Eq for OrderBookKey {}
174
175impl PartialEq for OrderBookKey {
176    fn eq(&self, other: &Self) -> bool {
177        self.price == other.price && self.symbol == other.symbol
178    }
179}
180
181
182impl Hash for OrderBookKey {
183    fn hash<H>(&self, state: &mut H)
184        where
185            H: Hasher,
186    {
187        let float_bits: u64 = unsafe { std::mem::transmute(self.price) };
188        float_bits.hash(state);
189        self.symbol.as_bytes().hash(state);
190    }
191}
192
193impl OrderBookKey {
194    pub fn price(&self) -> f64 {
195        self.price
196    }
197    pub fn symbol(&self) -> &str {
198        &self.symbol
199    }
200
201    pub fn set_price(&mut self, price: f64) {
202        self.price = price;
203    }
204    pub fn set_symbol(&mut self, symbol: String) {
205        self.symbol = symbol;
206    }
207}
208
209
210impl Fill {
211    pub fn new(
212        symbol: String,
213        order_id: String,
214        execution_id: String,
215        exec_type: Status,
216        qty: u32,
217        leaves_qty: u32,
218        cum_qty: u32,
219        price: f64,
220        side: Side,
221        cl_ord_id: String,
222        status: Status) -> Self {
223        Self {
224            symbol,
225            order_id,
226            execution_id,
227            exec_type,
228            qty,
229            leaves_qty,
230            cum_qty,
231            price,
232            side,
233            cl_ord_id,
234            secondary_cl_ord_id: "".to_string(),
235            status,
236        }
237    }
238
239    ///Returns a string formatted a table of all the fills in the `fills` argument
240    pub fn pretty_print(fills: &Vec<Fill>) -> String {
241        if fills.is_empty() {
242            return "No fills".to_string();
243        }
244
245        let title = format!("{}", "Fills".reversed().bold());
246        println!("{}", title);
247
248
249        let mut table = Table::new();
250        table.add_row(row!["Symbol","Qty","Price","client_order_id","exchange_order_id","Side","Order Status"]);
251        for fill in fills {
252            table.add_row(row![fill.symbol,fill.qty,fill.price,fill.cl_ord_id,fill.secondary_cl_ord_id,fill.side.string_value(),fill.status.string_value()]);
253        }
254
255        table.printstd();
256        let f_str = format!("{}","Fills:");
257        let mut titled_fills = String::from(f_str);
258        titled_fills.push_str("\n");
259        titled_fills.push_str(table.to_string().as_str());
260        titled_fills
261    }
262
263    pub fn set_qty(&mut self, qty: u32) {
264        self.qty = qty;
265    }
266
267    pub fn price(&self) -> f64 {
268        self.price
269    }
270
271    pub fn set_cum_qty(&mut self, cum_qty: u32) {
272        self.cum_qty = cum_qty;
273    }
274
275    pub fn set_leaves_qty(&mut self, leaves_qty: u32) {
276        self.leaves_qty = leaves_qty;
277    }
278    pub fn set_symbol(&mut self, symbol: String) {
279        self.symbol = symbol;
280    }
281
282    pub fn qty(&self) -> u32 {
283        self.qty
284    }
285
286    pub fn symbol(&self) -> &String {
287        &self.symbol
288    }
289
290    pub fn cum_qty(&self) -> u32 {
291        self.cum_qty
292    }
293
294    pub fn leaves_qty(&self) -> u32 {
295        self.leaves_qty
296    }
297    pub fn cl_ord_id(&self) -> &str {
298        &self.cl_ord_id
299    }
300
301    pub fn secondary_cl_ord_id(&self) -> String {
302        self.secondary_cl_ord_id.clone()
303    }
304
305    pub fn set_secondary_cl_ord_id(&mut self, matching_side_id: String) {
306        self.secondary_cl_ord_id = matching_side_id;
307    }
308
309    pub fn set_status(&mut self, status: Status) {
310        self.status = status;
311    }
312
313    pub fn set_order_id(&mut self, order_id: String) {
314        self.order_id = order_id;
315    }
316
317    pub fn status(&self) -> &Status {
318        &self.status
319    }
320
321    pub fn side(&self) -> Side {
322        self.side.clone()
323    }
324    pub fn set_side(&mut self, side: Side) {
325        self.side = side
326    }
327
328    pub fn from(order: &OrderSingle) -> Self {
329        Self {
330            qty: order.qty(),
331            cum_qty: 0,
332            leaves_qty: order.qty(),
333            order_id: generate_id(),
334            execution_id: generate_id(),
335            price: order.price(),
336            symbol: order.symbol().clone(),
337            status: Status::Filled,
338            side: order.side(),
339            cl_ord_id: order.cl_ord_id().clone(),
340            secondary_cl_ord_id: "".to_string(),
341            exec_type: Status::New,
342
343        }
344    }
345}
346
347
348impl OrderSingle {
349    pub fn new(qty: u32,
350               symbol: String,
351               price: f64,
352               side: Side,
353               order_type: OrderType,
354               cl_ord_id: String) -> Self {
355        Self {
356            qty,
357            symbol,
358            price,
359            side,
360            order_type,
361            cl_ord_id,
362        }
363    }
364
365    /// Returns `true` if the order is valid. `false` otherwise. As you can see Market orders are
366    /// not supported as af now
367    ///
368    /// # Example
369    /// self.symbol.trim().len() > 0 &&
370    ///             self.price() > 0.0 &&
371    ///             self.qty() > 0 &&
372    ///             (self.side.string_value() == "Buy" || self.side.string_value() == "Sell") &&
373    ///            self.order_type.string_value() == "Limit
374    pub fn is_valid(&self) -> bool {
375        self.symbol.trim().len() > 0 &&
376            self.price() > 0.0 &&
377            self.qty() > 0 &&
378            (self.side.string_value() == "Buy" || self.side.string_value() == "Sell") &&
379            self.order_type.string_value() == "Limit" &&
380            self.cl_ord_id.trim().len() > 0
381    }
382
383    pub fn get_order_book_key(&self) -> OrderBookKey {
384        OrderBookKey::new(self.price, self.symbol.clone())
385    }
386
387    pub fn set_qty(&mut self, qty: u32) {
388        self.qty = qty;
389    }
390    pub fn set_price(&mut self, price: f64) {
391        self.price = price;
392    }
393
394    pub fn set_side(&mut self, side: Side) {
395        self.side = side;
396    }
397
398    pub fn matching_side(&self) -> Side {
399        match self.side {
400            Buy => Sell,
401            Sell => Buy,
402        }
403    }
404
405    pub fn qty(&self) -> u32 {
406        self.qty.clone()
407    }
408
409
410    pub fn symbol(&self) -> &String {
411        &self.symbol
412    }
413
414    pub fn side(&self) -> Side {
415        self.side.clone()
416    }
417
418    pub fn order_type(&self) -> OrderType {
419        self.order_type.clone()
420    }
421
422    pub fn cl_ord_id(&self) -> &String {
423        &self.cl_ord_id
424    }
425
426    pub fn price(&self) -> f64 {
427        self.price
428    }
429}
430
431impl Display for OrderSingle {
432    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
433        write!(f, "OrderSingle:: symbol: {}, quantity: {} , price: {}, side: {}, cl_ord_id: {}",
434               self.symbol, self.qty, self.price, self.side.string_value(), self.cl_ord_id)
435    }
436}
437
438impl Eq for OrderSingle {}
439
440impl PartialEq for OrderSingle {
441    fn eq(&self, other: &Self) -> bool {
442        self.cl_ord_id() == other.cl_ord_id()
443    }
444}
445
446
447impl Hash for OrderSingle {
448    fn hash<H: Hasher>(&self, state: &mut H) {
449        self.cl_ord_id.as_bytes().hash(state);
450    }
451}
452
453#[derive(Clone, Debug, Serialize, Deserialize)]
454pub struct OrderBook {
455    buy_orders: HashMap<OrderBookKey, VecDeque<OrderSingle>>,
456    sell_orders: HashMap<OrderBookKey, VecDeque<OrderSingle>>,
457}
458
459impl Default for OrderBook {
460    fn default() -> Self {
461        Self {
462            buy_orders: HashMap::new(),
463            sell_orders: HashMap::new(),
464        }
465    }
466}
467
468impl OrderBook {
469    pub fn new(buy_orders: HashMap<OrderBookKey, VecDeque<OrderSingle>>,
470               sell_orders: HashMap<OrderBookKey, VecDeque<OrderSingle>>) -> Self {
471        Self {
472            buy_orders,
473            sell_orders,
474
475        }
476    }
477
478
479    pub fn update_self(&mut self, order_book: &mut Self) {
480        self.buy_orders = order_book.buy_orders.clone();
481        self.sell_orders = order_book.sell_orders.clone();
482    }
483
484    pub fn update_order_book(&mut self, orders: HashMap<OrderBookKey, VecDeque<OrderSingle>>, side: Side) {
485        match side {
486            Buy => self.buy_orders = orders,
487            Sell => self.sell_orders = orders,
488        }
489    }
490
491    pub fn get_order_book(&self) -> Self {
492        self.clone()
493    }
494
495    pub fn get_orders_for(&self, side: Side) -> HashMap<OrderBookKey, VecDeque<OrderSingle>> {
496        match side {
497            Buy => self.buy_orders.clone(),
498            Sell => self.sell_orders.clone(),
499        }
500    }
501
502    pub fn print_order_book(&self) {
503        println!("Buy Orders >> {:#?}", self.buy_orders);
504        println!("Sell Orders >> {:#?}", self.sell_orders);
505    }
506
507    pub fn is_empty(&self) -> bool {
508        self.buy_orders.is_empty() && self.sell_orders.is_empty()
509    }
510
511
512    pub fn add_order_to_order_book(&mut self, order: OrderSingle) {
513        let side = order.side();
514        let key = OrderBookKey::new(order.price(), order.symbol().to_owned());
515        let order_map = self.order_map(side);
516        if order_map.contains_key(&key) {
517            order_map.entry(key).and_modify(|dequue| dequue.push_back(order));
518        } else {
519            let mut deque = VecDeque::new();
520            deque.push_back(order);
521            order_map.insert(key, deque);
522        }
523    }
524
525    pub fn order_map(&mut self, side: Side) -> &mut HashMap<OrderBookKey, VecDeque<OrderSingle>> {
526        if side == Sell {
527            &mut self.sell_orders
528        } else {
529            &mut self.buy_orders
530        }
531    }
532
533    pub fn pretty_print_self(&self) -> String {
534        let keys = self.get_excl_keys();
535        let mut strings = String::new();
536        for key in &keys {
537            let s = self.print_market_depth_for(key);
538            strings.push_str(s.as_str());
539        }
540        strings
541    }
542
543
544    pub fn get_excl_keys(&self) -> Vec<&str> {
545        let mut all_keys = vec![];
546        for (key, _) in &self.buy_orders {
547            all_keys.push(key.symbol());
548        }
549        for (key, _) in &self.sell_orders {
550            all_keys.push(key.symbol());
551        }
552        let mut excl_keys: Vec<&str> = vec![];
553        for symbol in all_keys {
554            if !excl_keys.contains(&symbol) {
555                excl_keys.push(&symbol)
556            }
557        }
558        excl_keys
559    }
560    pub fn print_market_depth_for(&self, symbol: &str) -> String {
561        let mut md_buy = self.get_md(symbol, &self.buy_orders,Buy).clone();
562        let mut md_sell = self.get_md(symbol, &self.sell_orders,Sell ).clone();
563        let s = format!("market depth for {}", symbol);
564        let mut strings = String::new();
565        println!("\n{}", s.reversed());
566        println!();
567        println!("{}", "Bids:".green().bold());
568        strings.push_str("Bids:\n");
569        strings.push_str(self.print_md(&mut md_buy).as_str());
570        println!();
571        println!("{}", "Offers:\n".red().bold());
572        strings.push_str("Offers:\n");
573        strings.push_str(self.print_md(&mut md_sell).as_str());
574        strings
575    }
576
577    fn print_md(&self, mds_buy: &Vec<MarketDepth>) -> String {
578        let mut table = Table::new();
579        table.add_row(row!["Symbol","Quantity","Price" , "Side"]);
580        for md in mds_buy {
581            table.add_row(row![md.symbol(),md.qty(), md.price(),md.side().string_value()]);
582        }
583
584       table.printstd();
585        table.to_string()
586    }
587
588
589    fn get_md(&self, symbol: &str, order_map: &HashMap<OrderBookKey, VecDeque<OrderSingle>>, side: Side) -> Vec<MarketDepth> {
590        let mut depths = vec![];
591
592        for (key, orders) in order_map {
593            let side = &orders[0].side();
594            if key.symbol() == symbol {
595                let orders: Vec<OrderSingle> = orders.clone().into_iter().collect();
596                let aggregate = Aggregator::sigma(&orders);
597                let md = MarketDepth::new(key.price, aggregate, side.clone(),symbol.to_string());
598                depths.push(md);
599            }
600        }
601        depths.sort_by(|md1,md2| md1.price().partial_cmp(&md2.price()).unwrap());
602        if side == Buy{
603            depths.reverse();
604        }
605
606        depths
607
608
609    }
610}
611
612#[derive(Clone, Debug)]
613struct MarketDepth {
614    price: f64,
615    qty: u32,
616    side: Side,
617    symbol: String,
618}
619
620impl MarketDepth {
621    fn new(price: f64, qty: u32, side: Side,symbol:String) -> Self {
622        Self { price, qty, side,symbol }
623    }
624
625
626    pub fn price(&self) -> f64 {
627        self.price
628    }
629    pub fn qty(&self) -> u32 {
630        self.qty
631    }
632
633    pub fn symbol(&self) -> &String {
634    &self.symbol
635}
636    pub fn side(&self) -> Side {
637        self.side.clone()
638    }
639}
640
641mod tests {
642    use std::collections::hash_map::DefaultHasher;
643    use std::hash::{Hash, Hasher};
644
645    use log::debug;
646
647    use crate::common::utils::{create_order_book, read_input};
648    use crate::matchers::fifo_matcher::FIFOMatcher;
649    use crate::matchers::matcher::Matcher;
650    use crate::model::domain::{Fill, OrderBook, OrderBookKey};
651
652    #[test]
653    fn test_partial_equals() {
654        let ok1 = OrderBookKey::new(101.5, "infy".to_string());
655        let ok2 = OrderBookKey::new(101.1, "infy".to_string());
656        let ok3 = OrderBookKey::new(101.5, "infy".to_string());
657
658        assert_ne!(ok1, ok2);
659        assert_eq!(ok1, ok3);
660    }
661
662    #[test]
663    fn test_orderbookkey_hash() {
664        let ok1 = OrderBookKey::new(101.5, "infy".to_string());
665        let ok2 = OrderBookKey::new(101.5, "infy".to_string());
666        let ok3 = OrderBookKey::new(101.45, "infy".to_string());
667
668        let mut hasher = DefaultHasher::new();
669
670        ok1.hash(&mut hasher);
671        let hash1 = hasher.finish();
672
673        hasher = DefaultHasher::new();
674
675        ok2.hash(&mut hasher);
676        let hash2 = hasher.finish();
677
678        hasher = DefaultHasher::new();
679
680        ok3.hash(&mut hasher);
681        let hash3 = hasher.finish();
682
683
684        debug!("{hash1} {hash2} {hash3}");
685
686        assert_eq!(hash1, hash2);
687        assert_ne!(hash1, hash3);
688        assert_ne!(hash2, hash3);
689    }
690
691    #[test]
692    fn test_print_md() {
693        let mut ob = create_order_book(read_input("test_data/orders.txt"));
694        let key = &String::from("IBM");
695        let s = ob.pretty_print_self();
696
697        println!("{}", s);
698    }
699
700    #[test]
701    fn test_fill_str(){
702        let mut order_book = create_order_book(read_input("test_data/orders.txt"));
703        let mut matcher = FIFOMatcher;
704        let fills = matcher.match_order_book(&mut order_book);
705        let s = Fill::pretty_print(&fills);
706        println!("{}",s);
707
708    }
709}
710
711
712   
713
714
715
716