Skip to main content

o2_api_types/domain/
trade.rs

1use crate::{
2    OrderId,
3    primitives::Side,
4};
5use std::{
6    fmt::{
7        Display,
8        Formatter,
9    },
10    str::FromStr,
11};
12
13#[derive(
14    Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash, Default,
15)]
16pub struct TradeId {
17    pub maker_id: OrderId,
18    pub taker_id: OrderId,
19}
20
21impl TradeId {
22    pub fn new(maker_id: OrderId, taker_id: OrderId) -> Self {
23        Self { maker_id, taker_id }
24    }
25}
26
27impl Display for TradeId {
28    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29        f.write_fmt(format_args!("{}/{}", self.maker_id, self.taker_id))
30    }
31}
32
33impl FromStr for TradeId {
34    type Err = anyhow::Error;
35
36    fn from_str(s: &str) -> Result<Self, Self::Err> {
37        let parts: Vec<&str> = s.split('/').collect();
38        if parts.len() != 2 {
39            return Err(anyhow::anyhow!("Invalid TradeId format"));
40        }
41        let maker_id: OrderId = parts[0].parse().map_err(|e| anyhow::anyhow!("{}", e))?;
42        let taker_id: OrderId = parts[1].parse().map_err(|e| anyhow::anyhow!("{}", e))?;
43        Ok(TradeId { maker_id, taker_id })
44    }
45}
46
47#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
48pub struct Trade {
49    pub trade_id: TradeId,
50    pub side: Side,
51    pub total: u128,
52    pub quantity: u64,
53    pub price: u64,
54    pub timestamp: u128,
55    pub maker_fee: u64,
56    pub taker_fee: u64,
57}
58
59#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)]
60pub enum TradeSide {
61    Maker,
62    Taker,
63    Both,
64}
65
66impl Display for TradeSide {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        match self {
69            TradeSide::Maker => write!(f, "maker"),
70            TradeSide::Taker => write!(f, "taker"),
71            TradeSide::Both => write!(f, "both"),
72        }
73    }
74}
75
76impl FromStr for TradeSide {
77    type Err = anyhow::Error;
78
79    fn from_str(s: &str) -> Result<Self, Self::Err> {
80        match s {
81            "maker" => Ok(TradeSide::Maker),
82            "taker" => Ok(TradeSide::Taker),
83            "both" => Ok(TradeSide::Both),
84            _ => Err(anyhow::anyhow!("Invalid trade side: {s}")),
85        }
86    }
87}