bitbank_api/public/
candlestick.rs1use super::*;
2
3mod raw {
4 use super::*;
5
6 #[derive(Deserialize, Debug)]
7 pub struct Response {
8 pub candlestick: Candlestick,
9 }
10 #[derive(Deserialize, Debug)]
11 pub struct Candlestick(
12 pub Ohlcv,
13 #[serde(skip)] (),
16 );
17
18 #[derive(Deserialize, Debug)]
19 pub struct Ohlcv {
20 pub ohlcv: Vec<OhlcvItem>,
21 }
22
23 #[serde_as]
24 #[derive(Deserialize, Debug)]
25 pub struct OhlcvItem(
26 #[serde_as(as = "DisplayFromStr")] pub f64,
27 #[serde_as(as = "DisplayFromStr")] pub f64,
28 #[serde_as(as = "DisplayFromStr")] pub f64,
29 #[serde_as(as = "DisplayFromStr")] pub f64,
30 #[serde_as(as = "DisplayFromStr")] pub f64,
31 #[serde_as(as = "TimestampMilliSeconds")] pub NaiveDateTime,
32 );
33}
34
35#[derive(Debug)]
36pub struct Candlestick {
37 pub start: f64,
38 pub high: f64,
39 pub low: f64,
40 pub end: f64,
41 pub volume: f64,
42 pub timestamp: NaiveDateTime,
43}
44impl Candlestick {
45 fn new(x: raw::OhlcvItem) -> Self {
46 Candlestick {
47 start: x.0,
48 high: x.1,
49 low: x.2,
50 end: x.3,
51 volume: x.4,
52 timestamp: x.5,
53 }
54 }
55}
56
57#[derive(derive_more::Display, Debug, Clone)]
58pub enum CandleType {
59 #[display(fmt = "1min")]
60 Min1,
61 #[display(fmt = "5min")]
62 Min5,
63 #[display(fmt = "15min")]
64 Min15,
65 #[display(fmt = "30min")]
66 Min30,
67 #[display(fmt = "1hour")]
68 Hour1,
69
70 #[display(fmt = "4hour")]
71 Hour4,
72 #[display(fmt = "8hour")]
73 Hour8,
74 #[display(fmt = "12hour")]
75 Hour12,
76 #[display(fmt = "1day")]
77 Day1,
78 #[display(fmt = "1week")]
79 Week1,
80 #[display(fmt = "1month")]
81 Month1,
82}
83
84#[derive(derive_more::Display, Clone)]
85pub enum Period {
86 #[display(fmt = "{_0}")]
87 YYYY(u16),
88 #[display(fmt = "{_0}{_1}{_2}")]
89 YYYYMMDD(u16, u8, u8),
90}
91
92#[derive(TypedBuilder)]
93pub struct Params {
94 pair: Pair,
95 candle_type: CandleType,
96 period: Period,
97}
98
99fn path(params: Params) -> String {
100 format!(
101 "/{}/candlestick/{}/{}",
102 params.pair, params.candle_type, params.period
103 )
104}
105
106pub async fn get(params: Params) -> anyhow::Result<Vec<Candlestick>> {
107 let resp: raw::Response = do_get(path(params)).await?;
108 let ohlcv = resp.candlestick.0;
109 Ok(ohlcv.ohlcv.into_iter().map(Candlestick::new).collect())
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 #[test]
116 fn test_path() -> anyhow::Result<()> {
117 let params = Params::builder()
118 .pair(Pair(XRP, JPY))
119 .candle_type(CandleType::Day1)
120 .period(Period::YYYY(2023))
121 .build();
122 let path = path(params);
123 assert_eq!(path, "/xrp_jpy/candlestick/1day/2023");
124 Ok(())
125 }
126
127 #[tokio::test]
128 async fn test_candlestick_yyyy() -> anyhow::Result<()> {
129 let params = Params::builder()
130 .pair(Pair(XRP, JPY))
131 .candle_type(CandleType::Month1)
132 .period(Period::YYYY(2022))
133 .build();
134 let resp = get(params).await?;
135 dbg!(&resp);
136 Ok(())
137 }
138
139 #[tokio::test]
140 async fn test_candlestick_yyyymmdd() -> anyhow::Result<()> {
141 let params = Params::builder()
142 .pair(Pair(XRP, JPY))
143 .candle_type(CandleType::Min15)
144 .period(Period::YYYYMMDD(2022, 12, 25))
145 .build();
146 let resp = get(params).await?;
147 dbg!(&resp);
148 Ok(())
149 }
150}