-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathtypes.rs
More file actions
130 lines (110 loc) · 3.68 KB
/
types.rs
File metadata and controls
130 lines (110 loc) · 3.68 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#[derive(Default, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
/// Defines a taker trade
pub struct Trade {
/// Timestamp, assumed to be in milliseconds
pub timestamp: i64,
/// Price of the asset
pub price: f64,
/// Size of the trade
/// negative values indicate a taker Sell order
pub size: f64,
}
impl TakerTrade for Trade {
#[inline(always)]
fn timestamp(&self) -> i64 {
self.timestamp
}
#[inline(always)]
fn price(&self) -> f64 {
self.price
}
#[inline(always)]
fn size(&self) -> f64 {
self.size
}
}
/// Defines how to aggregate trade size
/// either by Base currency or Quote Currency
/// assumes trades sizes are denoted in Quote
/// e.g.: buy 10 contracts of BTC would be trade size of 10
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum By {
/// when aggregating by Base, divide size by price for volume sum
Base,
/// when aggregating by Quote, take the raw trade size for volume sum
/// as the assumption is that Trade size is denoted in Quote
Quote,
}
/// Trait to enable third party types to be passed into aggregators.
pub trait TakerTrade {
/// The timestamp of a trade,
fn timestamp(&self) -> i64;
/// units for the timestamp integer returned by [`TakerTrade.timestamp()`] method
/// A default implementation is included and assumes milliseconds
fn timestamp_resolution(&self) -> TimestampResolution {
TimestampResolution::Millisecond
}
/// Fill price of the transaction
fn price(&self) -> f64;
/// Number of shares or contracts in this trade.
/// A negative value indicates
/// that the trade was a sell order, taking liquidity from the bid.
fn size(&self) -> f64;
}
/// The resolution of the "TakerTrade" timestamps
#[derive(Debug, Clone, Copy)]
pub enum TimestampResolution {
/// The timestamp of the TakerTrade is measured in milliseconds
Millisecond,
/// The timestamp of the TakerTrade is measured in microseconds
Microsecond,
/// The timestamp of the TakerTrade is measured in nanoseconds
Nanosecond,
}
/// A period measured in milliseconds which must be non-zero.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct MillisecondPeriod(u64);
impl MillisecondPeriod {
/// Try to create the `MillisecondPeriod` from millisecond units.
/// # Panics:
/// If `millis` is zero, the contract was violated.
pub const fn from_non_zero(millis: u64) -> Self {
assert!(millis > 0, "`millis` must be non-zero that was the deal");
Self(millis)
}
/// Try to create the `MillisecondPeriod` from seconds.
/// # Panics:
/// Because this is used in a const context, it is not yet possible to do `Option::unwrap` and thus
/// it is asserted that `seconds` is non-zero
pub const fn from_non_zero_secs(seconds: u64) -> Self {
assert!(seconds > 0, "`seconds` must be non-zero that was the deal");
Self(seconds * 1_000)
}
/// Get the inner value
pub fn get(self) -> u64 {
self.0
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
#[should_panic]
fn millisecond_period_from_non_zero_secs_panic() {
// panics as it cannot be zero
MillisecondPeriod::from_non_zero_secs(0);
}
#[test]
fn millisecond_period_from_non_zero_secs() {
assert_eq!(
MillisecondPeriod::from_non_zero_secs(1),
MillisecondPeriod(1_000)
);
assert_eq!(
MillisecondPeriod::from_non_zero_secs(60),
MillisecondPeriod(60_000)
);
}
}