barter_data/exchange/bitfinex/
trade.rs1use crate::{
2 event::{MarketEvent, MarketIter},
3 subscription::trade::PublicTrade,
4};
5use barter_instrument::{Side, exchange::ExchangeId};
6use barter_integration::de::{datetime_utc_from_epoch_duration, extract_next};
7use chrono::{DateTime, Utc};
8use serde::Serialize;
9
10#[derive(Clone, Copy, PartialEq, PartialOrd, Debug, Serialize)]
37pub struct BitfinexTrade {
38 pub id: u64,
39 pub time: DateTime<Utc>,
40 pub side: Side,
41 pub price: f64,
42 pub amount: f64,
43}
44
45impl<InstrumentKey> From<(ExchangeId, InstrumentKey, BitfinexTrade)>
46 for MarketIter<InstrumentKey, PublicTrade>
47{
48 fn from((exchange_id, instrument, trade): (ExchangeId, InstrumentKey, BitfinexTrade)) -> Self {
49 Self(vec![Ok(MarketEvent {
50 time_exchange: trade.time,
51 time_received: Utc::now(),
52 exchange: exchange_id,
53 instrument,
54 kind: PublicTrade {
55 id: trade.id.to_string(),
56 price: trade.price,
57 amount: trade.amount,
58 side: trade.side,
59 },
60 })])
61 }
62}
63
64impl<'de> serde::Deserialize<'de> for BitfinexTrade {
65 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66 where
67 D: serde::de::Deserializer<'de>,
68 {
69 struct SeqVisitor;
70
71 impl<'de> serde::de::Visitor<'de> for SeqVisitor {
72 type Value = BitfinexTrade;
73
74 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 formatter.write_str("BitfinexTrade struct from the Bitfinex WebSocket API")
76 }
77
78 fn visit_seq<SeqAccessor>(
79 self,
80 mut seq: SeqAccessor,
81 ) -> Result<Self::Value, SeqAccessor::Error>
82 where
83 SeqAccessor: serde::de::SeqAccess<'de>,
84 {
85 let id = extract_next(&mut seq, "id")?;
87 let time_millis = extract_next(&mut seq, "time")?;
88 let amount: f64 = extract_next(&mut seq, "amount")?;
89 let price = extract_next(&mut seq, "price")?;
90 let side = match amount.is_sign_positive() {
91 true => Side::Buy,
92 false => Side::Sell,
93 };
94
95 while seq.next_element::<serde::de::IgnoredAny>()?.is_some() {}
98
99 Ok(BitfinexTrade {
100 id,
101 time: datetime_utc_from_epoch_duration(std::time::Duration::from_millis(
102 time_millis,
103 )),
104 price,
105 amount: amount.abs(),
106 side,
107 })
108 }
109 }
110
111 deserializer.deserialize_seq(SeqVisitor)
113 }
114}