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 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#[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}