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