summaryrefslogtreecommitdiff
path: root/rust_backend/src/market/trade.rs
blob: 362acbfc5bacc79a00b05d04ce15a92198f676ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::order::Order;

pub struct Trade<'a> {
    from: &'a Order,
    to: &'a Order,
    quantity: usize,
    gross_profit: f64,
}

const TAX_RATE: f64 = 0.08

impl<'a> Trade<'a> {
    pub fn new(from: &'a Order, to: &'a Order, quantity: usize) -> Self {
        Self { from, to, quantity }
    }

    pub fn create_trades(sell_orders: &'a [Order], buy_orders: &'a [Order]) -> Vec<Trade<'a>> {
        let mut trades: Vec<Trade<'a>> = Vec::new();
        let mut grouped_orders: HashMap<i32, (Vec<&'a Order>, Vec<&'a Order>)> = HashMap::new();

        // Grouping sell orders
        for order in sell_orders {
            grouped_orders.entry(order.type_id)
                .or_insert((Vec::new(), Vec::new()))
                .0
                .push(order);
        }

        // Grouping buy orders
        for order in buy_orders {
            grouped_orders.entry(order.type_id)
                .or_insert((Vec::new(), Vec::new()))
                .1
                .push(order);
        }

        // Iterating over each type_id's sell and buy orders to create trades
        for (_type_id, (sells, buys)) in grouped_orders {
            for &sell_order in sells {
                for &buy_order in buys {
                    let quantity = std::cmp::min(sell_order.volume_remain, buy_order.volume_remain);
                    let gross_profit = quantity as f64 * (buy_order.price * (1-TAX_RATE) - sell_order.price);

                    if gross_profit <= 0.0 {
                        continue;
                    }

                    let trade = Trade::new(
                        sell_order,  
                        buy_order,
                        quantity,
                        gross_profit,
                    );

                    trades.push(trade);
                }
            }
        }

        trades
    }

}