1extern crate log;
2
3use std::{env, io, process};
4use std::io::BufRead;
5use std::sync::mpsc::{Receiver, Sender};
6use std::thread::sleep;
7use std::time::Duration;
8
9use colored::Colorize;
10use log::{error, info};
11
12use crate::common::utils;
13use crate::matchers::fifo_matcher::FIFOMatcher;
14use crate::matchers::matcher::Matcher;
15use crate::matchers::prorata_matcher::ProrataMatcher;
16use crate::model::domain::OrderBook;
17
18pub mod model;
19pub mod matchers;
20pub mod formatters;
21pub mod common;
22
23
24
25
26pub struct CmdArgs {
27 pub file_path: String,
28 pub algo: String,
29}
30
31fn print_help() {
32 println!("Usage:");
33 println!("If using cargo:");
34 println!("cargo -- -h for help");
35 println!("cargo run <Enter> for starting without an orderbook or algo param");
36 println!("cargo run -- <order_file_path> <algo(FIFO|PRO>");
37 println!();
38 println!("If using executable:");
39 println!("exchange_simulator <Enter> for starting without an orderbook or algo param");
40 println!("exchange_simulator.exe -h for help");
41 println!("exchange_simulator.exe <order_file+path> <algo(FIFO|PRO>");
42 process::exit(0);
43}
44pub fn start_user(tx: &Sender<OrderBook>, rx: &Receiver<OrderBook>, file_path: String) {
47 if file_path == "-h" {
48 print_help();
49 }
50 let input = utils::read_input(&file_path);
51 let mut ob = utils::create_order_book(input);
52 if let Err(e) = tx.send(ob) {
53 error!("Error sending file {}",e);
54 }
55 sleep(Duration::from_secs(1));
56 loop {
57 let mut order_book = match rx.recv() {
58 Ok(ob) => ob,
59 Err(e) => {
60 error!("Error receiving order book {}",e);
61 OrderBook::default()
62 }
63 };
64
65 order_book.pretty_print_self();
66 println!("Enter an order({} ) to match or {} to quit","<id> <symbol> <qty> <price> <side(Buy|Sell)>".bold().reversed(), "q".bold().red());
67 println!("");
68 let mut line = String::new();
69 io::stdin().read_line(&mut line).unwrap();
70 if line.chars().nth(0) == Some('q') {
71 process::exit(0);
72 }
73 let order = utils::create_order_from_string(line.trim_end().to_string());
74 order_book.add_order_to_order_book(order);
75 if let Err(e) = tx.send(order_book) {
76 error!("Error sending order book {}",e);
77 };
78 sleep(Duration::from_secs(1));
79 }
80}
81
82pub fn start_matcher(tx: &Sender<OrderBook>, rx: &Receiver<OrderBook>, algo: String) {
85 if algo == "PRO" {
86 let mut matcher = ProrataMatcher;
87 matcher.start(&tx, &rx);
88 } else {
89 let mut matcher = FIFOMatcher;
90 matcher.start(&tx, &rx);
91 }
92}
93
94pub fn get_cmd_args() -> Result<CmdArgs, &'static str> {
95 let mut args = env::args();
96 args.next();
97 let file_path = match args.next() {
98 Some(path) => path,
99 None => return Err("No order file provided"),
100 };
101
102 let algo = match args.next() {
103 Some(arg) => arg,
104 None => String::from("FIFO")
105 };
106
107 let cmd_args = CmdArgs {
108 file_path: file_path,
109 algo: algo,
110 };
111 Ok(cmd_args)
112}
113
114
115