Skip to main content

brokapi_bybit/map/
mod.rs

1//! Mapping of the wire models of the exchange to the broker-independent types.
2//!
3//! Every function here is pure: no clock but the one passed in, no network.
4
5pub mod execution;
6pub mod instrument;
7pub mod market;
8pub mod order;
9pub mod portfolio;
10pub mod stop;
11
12use std::time::Instant;
13
14use brokapi_core::{Side, Timestamps, UnixNanos};
15
16/// The three clocks of an event: `now` is the local monotonic one, the wall clock is read here, the time of the
17/// exchange is given when the frame has it.
18pub fn timestamps(now: Instant, broker_ts: Option<UnixNanos>) -> Timestamps {
19    let rx_ts = UnixNanos::from_nanos(
20        std::time::SystemTime::now()
21            .duration_since(std::time::UNIX_EPOCH)
22            .map(|d| d.as_nanos() as i64)
23            .unwrap_or(0),
24    );
25    let mut ts = Timestamps::new(rx_ts, now);
26    if let Some(b) = broker_ts {
27        ts = ts.with_broker_ts(b);
28    }
29    ts
30}
31
32/// The wall clock now, as nanoseconds since the epoch.
33pub fn unix_now_nanos() -> UnixNanos {
34    UnixNanos::from_nanos(
35        std::time::SystemTime::now()
36            .duration_since(std::time::UNIX_EPOCH)
37            .map(|d| d.as_nanos() as i64)
38            .unwrap_or(0),
39    )
40}
41
42/// Nanoseconds from milliseconds since the epoch.
43pub fn ms_to_nanos(ms: i64) -> UnixNanos {
44    UnixNanos::from_nanos(ms.saturating_mul(1_000_000))
45}
46
47/// The time of the exchange as nanoseconds, `None` when the exchange gave none (zero).
48pub fn broker_ts(ms: i64) -> Option<UnixNanos> {
49    (ms > 0).then(|| ms_to_nanos(ms))
50}
51
52/// The word of the API for a side.
53pub fn side_word(side: Side) -> &'static str {
54    match side {
55        Side::Buy => "Buy",
56        Side::Sell => "Sell",
57    }
58}
59
60/// The side from the word of the API.
61pub fn side_of(raw: &str) -> Option<Side> {
62    match raw {
63        "Buy" => Some(Side::Buy),
64        "Sell" => Some(Side::Sell),
65        _ => None,
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn sides_and_times_round_trip() {
75        assert_eq!(side_of(side_word(Side::Buy)), Some(Side::Buy));
76        assert_eq!(side_of("Sell"), Some(Side::Sell));
77        assert_eq!(side_of(""), None);
78        assert_eq!(ms_to_nanos(2).as_nanos(), 2_000_000);
79        assert_eq!(broker_ts(0), None);
80    }
81}