rustrade_data/exchange/gateio/perpetual/
trade.rs1use super::super::message::GateioMessage;
2use crate::{
3 Identifier,
4 event::{MarketEvent, MarketIter},
5 exchange::ExchangeSub,
6 subscription::trade::PublicTrade,
7};
8use chrono::{DateTime, Utc};
9use rustrade_instrument::{Side, exchange::ExchangeId};
10use rustrade_integration::subscription::SubscriptionId;
11use serde::{Deserialize, Serialize};
12use smol_str::format_smolstr;
13
14pub type GateioFuturesTrades = GateioMessage<Vec<GateioFuturesTradeInner>>;
17
18#[derive(Clone, PartialEq, PartialOrd, Debug, Deserialize, Serialize)]
48pub struct GateioFuturesTradeInner {
49 #[serde(rename = "contract")]
50 pub market: String,
51 #[serde(
52 rename = "create_time_ms",
53 deserialize_with = "rustrade_integration::serde::de::de_u64_epoch_ms_as_datetime_utc"
54 )]
55 pub time: DateTime<Utc>,
56 pub id: u64,
57 #[serde(deserialize_with = "rustrade_integration::serde::de::de_str")]
58 pub price: f64,
59 #[serde(rename = "size")]
60 pub amount: f64,
61}
62
63impl Identifier<Option<SubscriptionId>> for GateioFuturesTrades {
64 fn id(&self) -> Option<SubscriptionId> {
65 self.data
66 .first()
67 .map(|trade| ExchangeSub::from((&self.channel, &trade.market)).id())
68 }
69}
70
71impl<InstrumentKey: Clone> From<(ExchangeId, InstrumentKey, GateioFuturesTrades)>
72 for MarketIter<InstrumentKey, PublicTrade>
73{
74 fn from(
75 (exchange, instrument, trades): (ExchangeId, InstrumentKey, GateioFuturesTrades),
76 ) -> Self {
77 trades
78 .data
79 .into_iter()
80 .map(|trade| {
81 Ok(MarketEvent {
82 time_exchange: trade.time,
83 time_received: Utc::now(),
84 exchange,
85 instrument: instrument.clone(),
86 kind: PublicTrade {
87 id: format_smolstr!("{}", trade.id),
88 price: trade.price,
89 amount: trade.amount,
90 side: if trade.amount.is_sign_positive() {
91 Side::Buy
92 } else {
93 Side::Sell
94 },
95 },
96 })
97 })
98 .collect()
99 }
100}
101
102#[cfg(test)]
103#[allow(clippy::unwrap_used)] mod tests {
105 use super::*;
106
107 mod de {
108 use super::*;
109
110 #[test]
111 fn test_gateio_message_perpetual_trade() {
112 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}]}";
113 serde_json::from_str::<GateioFuturesTrades>(input).unwrap();
114 }
115
116 #[test]
117 fn test_gateio_message_futures_trade() {
118 let input = r#"
119 {
120 "channel": "futures.trades",
121 "event": "update",
122 "time": 1541503698,
123 "result": [
124 {
125 "size": -108,
126 "id": 27753479,
127 "create_time": 1545136464,
128 "create_time_ms": 1545136464123,
129 "price": "96.4",
130 "contract": "ETH_USDT_QUARTERLY_20201225"
131 }
132 ]
133 }"#;
134
135 serde_json::from_str::<GateioFuturesTrades>(input).unwrap();
136 }
137 }
138}