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