crypto_com_exchange/model/
candlestick.rs1use serde::{Serialize, Deserialize};
2use serde_aux::prelude::deserialize_number_from_string;
3use chrono::{DateTime, Utc, serde::ts_milliseconds};
4use std::fmt;
5
6#[derive(Serialize,Deserialize, Debug)]
8pub struct CandlestickResult {
9 pub instrument_name: String,
11
12 pub subscription: String,
14
15 pub interval: TimeFrame,
29
30 pub data: Vec<Candlestick>
32}
33
34#[derive(Serialize, Deserialize, Debug)]
36pub struct Candlestick {
37
38 #[serde(rename = "o", deserialize_with = "deserialize_number_from_string")]
40 pub open: f32,
41
42 #[serde(rename = "c", deserialize_with = "deserialize_number_from_string")]
44 pub close: f32,
45
46 #[serde(rename = "h", deserialize_with = "deserialize_number_from_string")]
48 pub high: f32,
49
50 #[serde(rename = "l", deserialize_with = "deserialize_number_from_string")]
52 pub low: f32,
53
54 #[serde(rename = "v", deserialize_with = "deserialize_number_from_string")]
56 pub volume: f32,
57
58 #[serde(rename = "ut", with = "ts_milliseconds")]
60 pub update_time: DateTime<Utc>,
61
62 #[serde(rename = "t", with = "ts_milliseconds")]
64 pub start_time: DateTime<Utc>
65}
66
67#[derive(Serialize,Deserialize, Debug)]
68pub enum TimeFrame {
69 #[serde(rename = "1m")]
70 OneMinute,
71
72 #[serde(rename = "5m")]
73 FiveMinutes,
74
75 #[serde(rename = "15m")]
76 FiteenMinutes,
77
78 #[serde(rename = "30m")]
79 ThirtyMinutes,
80
81 #[serde(rename = "1h")]
82 OneHour,
83
84 #[serde(rename = "4h")]
85 FourHours,
86
87 #[serde(rename = "6h")]
88 SixHours,
89
90 #[serde(rename = "12h")]
91 TwelveHours,
92
93 #[serde(rename = "1D")]
94 OneDay,
95
96 #[serde(rename = "7D")]
97 OneWeek,
98
99 #[serde(rename = "14D")]
100 TwoWeeks,
101
102 #[serde(rename = "1M")]
103 OneMonth
104}
105
106impl fmt::Display for TimeFrame {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108 match *self {
109 TimeFrame::OneMinute => write!(f, "1m"),
110 TimeFrame::FiveMinutes => write!(f, "5m"),
111 TimeFrame::FiteenMinutes => write!(f, "15m"),
112 TimeFrame::ThirtyMinutes => write!(f, "30m"),
113 TimeFrame::OneHour => write!(f, "1h"),
114 TimeFrame::FourHours => write!(f, "4h"),
115 TimeFrame::SixHours => write!(f, "6h"),
116 TimeFrame::TwelveHours => write!(f, "12h"),
117 TimeFrame::OneDay => write!(f, "1D"),
118 TimeFrame::OneWeek => write!(f, "7D"),
119 TimeFrame::TwoWeeks => write!(f, "14D"),
120 TimeFrame::OneMonth => write!(f, "1M"),
121 }
122 }
123}
124
125pub fn candlestick(time_frame: TimeFrame, instrument_name: &str) -> String {
126 format!("candlestick.{time_frame}.{instrument_name}")
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use serde_json::from_str;
133
134 #[test]
135 fn check_structure() {
136 let json = "{
137 \"instrument_name\": \"ETH_CRO\",
138 \"subscription\": \"candlestick.1m.ETH_CRO\",
139 \"channel\": \"candlestick\",
140 \"depth\":300,
141 \"interval\": \"1m\",
142 \"data\":[
143 {
144 \"o\": \"162.03\",
145 \"c\": \"162.04\",
146 \"h\": \"161.96\",
147 \"l\": \"161.98\",
148 \"v\": \"336.452694\",
149 \"t\": 1589443241000,
150 \"ut\": 1589443242000
151 },
152 {
153 \"o\": \"163.03\",
154 \"c\": \"163.04\",
155 \"h\": \"162.96\",
156 \"l\": \"162.98\",
157 \"v\": \"336.452694\",
158 \"t\": 1589443241000,
159 \"ut\": 1589443242000
160 }
161 ]
162 }";
163
164 let candlestick_result = from_str::<CandlestickResult>(json).unwrap();
165 assert_eq!(candlestick_result.instrument_name, "ETH_CRO");
166 assert_eq!(candlestick_result.subscription, "candlestick.1m.ETH_CRO");
167 assert_eq!(candlestick_result.interval, "1m");
168 assert_eq!(candlestick_result.data.len(), 2);
169
170 let data = &candlestick_result.data[0];
172 assert_eq!(data.open, 162.03);
173 assert_eq!(data.close, 162.04);
174 assert_eq!(data.high, 161.96);
175 assert_eq!(data.low, 161.98);
176 assert_eq!(data.volume, 336.452694);
177 assert_eq!(data.start_time, DateTime::parse_from_rfc3339("2020-05-14T08:00:41+00:00").unwrap());
178 assert_eq!(data.update_time, DateTime::parse_from_rfc3339("2020-05-14T08:00:42+00:00").unwrap());
179
180 }
181}