barter_data/exchange/gateio/perpetual/
trade.rs

1use super::super::message::GateioMessage;
2use crate::{
3    Identifier,
4    event::{MarketEvent, MarketIter},
5    exchange::ExchangeSub,
6    subscription::trade::PublicTrade,
7};
8use barter_instrument::{Side, exchange::ExchangeId};
9use barter_integration::subscription::SubscriptionId;
10use chrono::{DateTime, Utc};
11use serde::{Deserialize, Serialize};
12
13/// Terse type alias for a `GateioFuturesUsdt`, `GateioFuturesBtc`, `GateioPerpetualUsdt` and
14/// `GateioPerpetualBtc` real-time trades WebSocket message.
15pub type GateioFuturesTrades = GateioMessage<Vec<GateioFuturesTradeInner>>;
16
17/// `GateioFuturesUsdt`, `GateioFuturesBtc`, `GateioPerpetualUsdt` and `GateioPerpetualBtc`
18/// real-time trade WebSocket message.
19///
20/// ### Raw Payload Examples
21/// #### Future Sell Trade
22/// See docs: <https://www.gate.io/docs/developers/delivery/ws/en/#trades-notification>
23/// ```json
24/// {
25///   "id": 27753479,
26///   "create_time": 1545136464,
27///   "create_time_ms": 1545136464123,
28///   "price": "96.4",
29///   "size": -108,
30///   "contract": "ETH_USDT_QUARTERLY_20201225"
31/// }
32/// ```
33///
34/// #### Future Perpetual Sell Trade
35/// See docs: <https://www.gate.io/docs/developers/futures/ws/en/#trades-api>
36/// ```json
37/// {
38///   "id": 27753479,
39///   "create_time": 1545136464,
40///   "create_time_ms": 1545136464123,
41///   "price": "96.4",
42///   "size": -108,
43///   "contract": "BTC_USD"
44/// }
45/// ```
46#[derive(Clone, PartialEq, PartialOrd, Debug, Deserialize, Serialize)]
47pub struct GateioFuturesTradeInner {
48    #[serde(rename = "contract")]
49    pub market: String,
50    #[serde(
51        rename = "create_time_ms",
52        deserialize_with = "barter_integration::de::de_u64_epoch_ms_as_datetime_utc"
53    )]
54    pub time: DateTime<Utc>,
55    pub id: u64,
56    #[serde(deserialize_with = "barter_integration::de::de_str")]
57    pub price: f64,
58    #[serde(rename = "size")]
59    pub amount: f64,
60}
61
62impl Identifier<Option<SubscriptionId>> for GateioFuturesTrades {
63    fn id(&self) -> Option<SubscriptionId> {
64        self.data
65            .first()
66            .map(|trade| ExchangeSub::from((&self.channel, &trade.market)).id())
67    }
68}
69
70impl<InstrumentKey: Clone> From<(ExchangeId, InstrumentKey, GateioFuturesTrades)>
71    for MarketIter<InstrumentKey, PublicTrade>
72{
73    fn from(
74        (exchange, instrument, trades): (ExchangeId, InstrumentKey, GateioFuturesTrades),
75    ) -> Self {
76        trades
77            .data
78            .into_iter()
79            .map(|trade| {
80                Ok(MarketEvent {
81                    time_exchange: trade.time,
82                    time_received: Utc::now(),
83                    exchange,
84                    instrument: instrument.clone(),
85                    kind: PublicTrade {
86                        id: trade.id.to_string(),
87                        price: trade.price,
88                        amount: trade.amount,
89                        side: if trade.amount.is_sign_positive() {
90                            Side::Buy
91                        } else {
92                            Side::Sell
93                        },
94                    },
95                })
96            })
97            .collect()
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104
105    mod de {
106        use super::*;
107
108        #[test]
109        fn test_gateio_message_perpetual_trade() {
110            let input = "{\"time\":1669843487,\"time_ms\":1669843487733,\"channel\":\"perpetual.trades\",\"event\":\"update\",\"result\":[{\"contract\":\"ETH_USDT\",\"create_time\":1669843487,\"create_time_ms\":1669843487724,\"id\":180276616,\"price\":\"1287\",\"size\":3}]}";
111            serde_json::from_str::<GateioFuturesTrades>(input).unwrap();
112        }
113
114        #[test]
115        fn test_gateio_message_futures_trade() {
116            let input = r#"
117            {
118              "channel": "futures.trades",
119              "event": "update",
120              "time": 1541503698,
121              "result": [
122                {
123                  "size": -108,
124                  "id": 27753479,
125                  "create_time": 1545136464,
126                  "create_time_ms": 1545136464123,
127                  "price": "96.4",
128                  "contract": "ETH_USDT_QUARTERLY_20201225"
129                }
130              ]
131            }"#;
132
133            serde_json::from_str::<GateioFuturesTrades>(input).unwrap();
134        }
135    }
136}