Skip to main content

o2_api_types/domain/
bars.rs

1use crate::{
2    domain::book::MarketId,
3    fuel_types::Bytes32,
4    parse::HexDisplayFromStr,
5};
6use serde::{
7    Deserialize,
8    Serialize,
9};
10use serde_with::{
11    DisplayFromStr,
12    serde_as,
13};
14use std::{
15    fmt::Display,
16    str::FromStr,
17};
18
19#[derive(
20    Debug,
21    Clone,
22    Copy,
23    PartialEq,
24    Eq,
25    strum_macros::EnumCount,
26    enum_iterator::Sequence,
27    serde::Serialize,
28    Hash,
29)]
30pub enum BarResolution {
31    Second,
32    OneMinute,
33    TwoMinutes,
34    ThreeMinutes,
35    FiveMinutes,
36    FifteenMinutes,
37    ThirtyMinutes,
38    OneHour,
39    TwoHours,
40    FourHours,
41    SixHours,
42    EightHours,
43    TwelveHours,
44    OneDay,
45    ThreeDays,
46    OneWeek,
47    OneMonth,
48    ThreeMonths,
49}
50
51impl Display for BarResolution {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        match self {
54            BarResolution::Second => write!(f, "1s"),
55            BarResolution::OneMinute => write!(f, "1m"),
56            BarResolution::TwoMinutes => write!(f, "2m"),
57            BarResolution::ThreeMinutes => write!(f, "3m"),
58            BarResolution::FiveMinutes => write!(f, "5m"),
59            BarResolution::FifteenMinutes => write!(f, "15m"),
60            BarResolution::ThirtyMinutes => write!(f, "30m"),
61            BarResolution::OneHour => write!(f, "1h"),
62            BarResolution::TwoHours => write!(f, "2h"),
63            BarResolution::FourHours => write!(f, "4h"),
64            BarResolution::SixHours => write!(f, "6h"),
65            BarResolution::EightHours => write!(f, "8h"),
66            BarResolution::TwelveHours => write!(f, "12h"),
67            BarResolution::OneDay => write!(f, "1d"),
68            BarResolution::ThreeDays => write!(f, "3d"),
69            BarResolution::OneWeek => write!(f, "1w"),
70            BarResolution::OneMonth => write!(f, "1M"),
71            BarResolution::ThreeMonths => write!(f, "3M"),
72        }
73    }
74}
75
76impl BarResolution {
77    pub fn as_millis(&self) -> u128 {
78        match self {
79            BarResolution::Second => 1_000,
80            BarResolution::OneMinute => 60_000,
81            BarResolution::TwoMinutes => 120_000,
82            BarResolution::ThreeMinutes => 180_000,
83            BarResolution::FiveMinutes => 300_000,
84            BarResolution::FifteenMinutes => 900_000,
85            BarResolution::ThirtyMinutes => 1_800_000,
86            BarResolution::OneHour => 3_600_000,
87            BarResolution::TwoHours => 7_200_000,
88            BarResolution::FourHours => 14_400_000,
89            BarResolution::SixHours => 21_600_000,
90            BarResolution::EightHours => 28_800_000,
91            BarResolution::TwelveHours => 43_200_000,
92            BarResolution::OneDay => 86_400_000,
93            BarResolution::ThreeDays => 259_200_000,
94            BarResolution::OneWeek => 604_800_000,
95            BarResolution::OneMonth => 2_629_746_000,
96            BarResolution::ThreeMonths => 7_889_472_000,
97        }
98    }
99}
100
101impl FromStr for BarResolution {
102    type Err = anyhow::Error;
103
104    fn from_str(s: &str) -> Result<Self, Self::Err> {
105        match s {
106            "1s" => Ok(BarResolution::Second),
107            "1m" => Ok(BarResolution::OneMinute),
108            "2m" => Ok(BarResolution::TwoMinutes),
109            "3m" => Ok(BarResolution::ThreeMinutes),
110            "5m" => Ok(BarResolution::FiveMinutes),
111            "15m" => Ok(BarResolution::FifteenMinutes),
112            "30m" => Ok(BarResolution::ThirtyMinutes),
113            "1h" => Ok(BarResolution::OneHour),
114            "2h" => Ok(BarResolution::TwoHours),
115            "4h" => Ok(BarResolution::FourHours),
116            "6h" => Ok(BarResolution::SixHours),
117            "8h" => Ok(BarResolution::EightHours),
118            "12h" => Ok(BarResolution::TwelveHours),
119            "1d" => Ok(BarResolution::OneDay),
120            "3d" => Ok(BarResolution::ThreeDays),
121            "1w" => Ok(BarResolution::OneWeek),
122            "1M" => Ok(BarResolution::OneMonth),
123            "3M" => Ok(BarResolution::ThreeMonths),
124            s => Err(anyhow::anyhow!("Invalid bar resolution: {s}")),
125        }
126    }
127}
128
129#[serde_as]
130#[derive(Serialize, Deserialize, Debug)]
131pub struct GetBarsParams {
132    #[serde_as(as = "HexDisplayFromStr")]
133    pub market_id: MarketId,
134    #[serde_as(as = "DisplayFromStr")]
135    pub from: u128,
136    #[serde_as(as = "DisplayFromStr")]
137    pub to: u128,
138    pub count_back: Option<usize>,
139    #[serde_as(as = "DisplayFromStr")]
140    pub resolution: BarResolution,
141}
142
143#[serde_as]
144#[derive(serde::Serialize, serde::Deserialize, Copy, Clone, Debug, PartialEq, Eq)]
145pub struct BarResponse {
146    #[serde_as(as = "DisplayFromStr")]
147    pub open: u64,
148    #[serde_as(as = "DisplayFromStr")]
149    pub close: u64,
150    #[serde_as(as = "DisplayFromStr")]
151    pub high: u64,
152    #[serde_as(as = "DisplayFromStr")]
153    pub low: u64,
154    #[serde_as(as = "DisplayFromStr")]
155    pub buy_volume: u128,
156    #[serde_as(as = "DisplayFromStr")]
157    pub sell_volume: u128,
158    /// Segments start timestamp.
159    pub timestamp: u128,
160}
161
162#[serde_as]
163#[derive(serde::Serialize, serde::Deserialize, Debug)]
164pub struct GetBarsResponse {
165    pub action: String,
166    pub bars: Vec<BarResponse>,
167    #[serde_as(as = "HexDisplayFromStr")]
168    pub market_id: Bytes32,
169}
170
171/// Subscription frequency for depth views.
172#[derive(
173    Clone, Copy, Debug, PartialEq, Eq, strum_macros::EnumCount, enum_iterator::Sequence,
174)]
175pub enum SubscriptionFrequency {
176    HundredMillis,
177    FiveHundredMillis,
178    OneSecond,
179    ThreeSecond,
180}
181
182impl Display for SubscriptionFrequency {
183    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
184        match self {
185            SubscriptionFrequency::HundredMillis => write!(f, "100ms"),
186            SubscriptionFrequency::FiveHundredMillis => write!(f, "500ms"),
187            SubscriptionFrequency::OneSecond => write!(f, "1s"),
188            SubscriptionFrequency::ThreeSecond => write!(f, "3s"),
189        }
190    }
191}
192
193impl FromStr for SubscriptionFrequency {
194    type Err = anyhow::Error;
195
196    fn from_str(s: &str) -> Result<Self, Self::Err> {
197        match s {
198            "100ms" => Ok(SubscriptionFrequency::HundredMillis),
199            "500ms" => Ok(SubscriptionFrequency::FiveHundredMillis),
200            "1s" => Ok(SubscriptionFrequency::OneSecond),
201            "3s" => Ok(SubscriptionFrequency::ThreeSecond),
202            s => Err(anyhow::anyhow!("Invalid subscription frequency: {s}")),
203        }
204    }
205}