rustrade_execution/
trade.rs1use crate::order::id::{OrderId, StrategyId};
2use chrono::{DateTime, Utc};
3use derive_more::{Constructor, From};
4use rust_decimal::Decimal;
5use rustrade_instrument::{Side, asset::QuoteAsset};
6use serde::{Deserialize, Serialize};
7use smol_str::SmolStr;
8use std::fmt::{Display, Formatter};
9
10#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, From)]
11pub struct TradeId<T = SmolStr>(pub T);
12
13impl TradeId {
14 pub fn new<S: AsRef<str>>(id: S) -> Self {
15 Self(SmolStr::new(id))
16 }
17}
18
19#[derive(
20 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
21)]
22pub struct Trade<AssetKey, InstrumentKey> {
23 pub id: TradeId,
24 pub order_id: OrderId,
25 pub instrument: InstrumentKey,
26 pub strategy: StrategyId,
27 pub time_exchange: DateTime<Utc>,
28 pub side: Side,
29 pub price: Decimal,
30 pub quantity: Decimal,
31 pub fees: AssetFees<AssetKey>,
32}
33
34impl<AssetKey, InstrumentKey> Trade<AssetKey, InstrumentKey> {
35 pub fn value_quote(&self) -> Decimal {
36 self.price * self.quantity.abs()
37 }
38}
39
40impl<AssetKey, InstrumentKey> Display for Trade<AssetKey, InstrumentKey>
41where
42 AssetKey: Display,
43 InstrumentKey: Display,
44{
45 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46 write!(
47 f,
48 "{{ instrument: {}, side: {}, price: {}, quantity: {}, time: {} }}",
49 self.instrument, self.side, self.price, self.quantity, self.time_exchange
50 )
51 }
52}
53
54#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
55pub struct AssetFees<AssetKey> {
56 pub asset: AssetKey,
57 pub fees: Decimal,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub fees_quote: Option<Decimal>,
64}
65
66impl<AssetKey> AssetFees<AssetKey> {
67 pub fn new(asset: AssetKey, fees: Decimal, fees_quote: Option<Decimal>) -> Self {
68 Self {
69 asset,
70 fees,
71 fees_quote,
72 }
73 }
74}
75
76impl AssetFees<QuoteAsset> {
77 pub fn quote_fees(fees: Decimal) -> Self {
80 Self {
81 asset: QuoteAsset,
82 fees,
83 fees_quote: Some(fees),
84 }
85 }
86}
87
88impl Default for AssetFees<QuoteAsset> {
89 fn default() -> Self {
90 Self {
91 asset: QuoteAsset,
92 fees: Decimal::ZERO,
93 fees_quote: Some(Decimal::ZERO),
94 }
95 }
96}
97
98impl<AssetKey> Default for AssetFees<Option<AssetKey>> {
99 fn default() -> Self {
100 Self {
101 asset: None,
102 fees: Decimal::ZERO,
103 fees_quote: None,
104 }
105 }
106}