Skip to main content

rust_okx/api/public_data/requests/
edge.rs

1use std::borrow::Cow;
2
3use serde::Serialize;
4
5/// Query parameters for `GET /api/v5/public/opt-summary`.
6#[derive(Debug, Clone, Serialize)]
7pub struct OptionSummaryRequest<'a> {
8    #[serde(rename = "instFamily")]
9    inst_family: Cow<'a, str>,
10    #[serde(rename = "expTime", skip_serializing_if = "Option::is_none")]
11    exp_time: Option<Cow<'a, str>>,
12}
13
14impl<'a> OptionSummaryRequest<'a> {
15    /// Create a query for an option instrument family, such as `BTC-USD`.
16    pub fn new(inst_family: impl Into<Cow<'a, str>>) -> Self {
17        Self {
18            inst_family: inst_family.into(),
19            exp_time: None,
20        }
21    }
22
23    /// Restrict the result to one expiration timestamp in milliseconds.
24    pub fn expiration(mut self, value: impl Into<Cow<'a, str>>) -> Self {
25        self.exp_time = Some(value.into());
26        self
27    }
28}
29
30/// Empty query for `GET /api/v5/public/interest-rate-loan-quota`.
31#[derive(Debug, Clone, Default, Serialize)]
32pub struct InterestRateLoanQuotaRequest {}
33
34impl InterestRateLoanQuotaRequest {
35    /// Create the parameterless query.
36    pub fn new() -> Self {
37        Self::default()
38    }
39}
40
41/// Query parameters for `GET /api/v5/public/instrument-tick-bands`.
42#[derive(Debug, Clone, Serialize)]
43pub struct InstrumentTickBandsRequest<'a> {
44    #[serde(rename = "instType")]
45    inst_type: Cow<'a, str>,
46}
47
48impl<'a> InstrumentTickBandsRequest<'a> {
49    /// Create a tick-band query for `FUTURES` or `OPTION` instruments.
50    pub fn new(inst_type: impl Into<Cow<'a, str>>) -> Self {
51        Self {
52            inst_type: inst_type.into(),
53        }
54    }
55}
56
57/// Query parameters for `GET /api/v5/public/underlying`.
58#[derive(Debug, Clone, Serialize)]
59pub struct UnderlyingRequest<'a> {
60    #[serde(rename = "instType")]
61    inst_type: Cow<'a, str>,
62}
63
64impl<'a> UnderlyingRequest<'a> {
65    /// Create a query for `SWAP`, `FUTURES`, or `OPTION` instruments.
66    pub fn new(inst_type: impl Into<Cow<'a, str>>) -> Self {
67        Self {
68            inst_type: inst_type.into(),
69        }
70    }
71}
72
73/// Query parameters for `GET /api/v5/public/option-trades`.
74#[derive(Debug, Clone, Default, Serialize)]
75pub struct PublicOptionTradesRequest<'a> {
76    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
77    inst_id: Option<Cow<'a, str>>,
78    #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
79    inst_family: Option<Cow<'a, str>>,
80    #[serde(rename = "optType", skip_serializing_if = "Option::is_none")]
81    option_type: Option<Cow<'a, str>>,
82}
83
84impl<'a> PublicOptionTradesRequest<'a> {
85    /// Create an unfiltered option-trades query.
86    pub fn new() -> Self {
87        Self::default()
88    }
89
90    /// Restrict results to one option instrument.
91    pub fn inst_id(mut self, value: impl Into<Cow<'a, str>>) -> Self {
92        self.inst_id = Some(value.into());
93        self
94    }
95
96    /// Restrict results to one option instrument family.
97    pub fn inst_family(mut self, value: impl Into<Cow<'a, str>>) -> Self {
98        self.inst_family = Some(value.into());
99        self
100    }
101
102    /// Restrict results to calls (`C`) or puts (`P`).
103    pub fn option_type(mut self, value: impl Into<Cow<'a, str>>) -> Self {
104        self.option_type = Some(value.into());
105        self
106    }
107}
108
109/// Query parameters for `GET /api/v5/public/market-data-history`.
110#[derive(Debug, Clone, Default, Serialize)]
111pub struct MarketDataHistoryRequest<'a> {
112    #[serde(skip_serializing_if = "Option::is_none")]
113    module: Option<Cow<'a, str>>,
114    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
115    inst_type: Option<Cow<'a, str>>,
116    #[serde(rename = "instIdList", skip_serializing_if = "Option::is_none")]
117    inst_id_list: Option<Cow<'a, str>>,
118    #[serde(rename = "dateAggrType", skip_serializing_if = "Option::is_none")]
119    date_aggr_type: Option<Cow<'a, str>>,
120    #[serde(skip_serializing_if = "Option::is_none")]
121    begin: Option<Cow<'a, str>>,
122    #[serde(skip_serializing_if = "Option::is_none")]
123    end: Option<Cow<'a, str>>,
124}
125
126impl<'a> MarketDataHistoryRequest<'a> {
127    /// Create an empty market-data-history query.
128    pub fn new() -> Self {
129        Self::default()
130    }
131
132    /// Set the OKX market-data module identifier.
133    pub fn module(mut self, value: impl Into<Cow<'a, str>>) -> Self {
134        self.module = Some(value.into());
135        self
136    }
137
138    /// Set the instrument type filter.
139    pub fn inst_type(mut self, value: impl Into<Cow<'a, str>>) -> Self {
140        self.inst_type = Some(value.into());
141        self
142    }
143
144    /// Set a comma-separated instrument-ID list.
145    pub fn inst_id_list(mut self, value: impl Into<Cow<'a, str>>) -> Self {
146        self.inst_id_list = Some(value.into());
147        self
148    }
149
150    /// Set the documented date aggregation type.
151    pub fn date_aggregation(mut self, value: impl Into<Cow<'a, str>>) -> Self {
152        self.date_aggr_type = Some(value.into());
153        self
154    }
155
156    /// Set the inclusive begin timestamp in milliseconds.
157    pub fn begin(mut self, value: impl Into<Cow<'a, str>>) -> Self {
158        self.begin = Some(value.into());
159        self
160    }
161
162    /// Set the inclusive end timestamp in milliseconds.
163    pub fn end(mut self, value: impl Into<Cow<'a, str>>) -> Self {
164        self.end = Some(value.into());
165        self
166    }
167}
168
169/// Query parameters for `GET /api/v5/public/mm-instrument-types`.
170#[derive(Debug, Clone, Default, Serialize)]
171pub struct MmInstrumentTypesRequest<'a> {
172    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
173    inst_type: Option<Cow<'a, str>>,
174    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
175    inst_id: Option<Cow<'a, str>>,
176}
177
178impl<'a> MmInstrumentTypesRequest<'a> {
179    /// Create an unfiltered MM instrument-types query.
180    pub fn new() -> Self {
181        Self::default()
182    }
183
184    /// Restrict results to one instrument type (`SPOT` or `SWAP`).
185    pub fn inst_type(mut self, value: impl Into<Cow<'a, str>>) -> Self {
186        self.inst_type = Some(value.into());
187        self
188    }
189
190    /// Restrict results to one instrument ID, e.g. `BTC-USDT-SWAP`.
191    pub fn inst_id(mut self, value: impl Into<Cow<'a, str>>) -> Self {
192        self.inst_id = Some(value.into());
193        self
194    }
195}
196
197/// Query parameters for `GET /api/v5/public/economic-calendar`.
198#[derive(Debug, Clone, Default, Serialize)]
199pub struct EconomicCalendarRequest<'a> {
200    #[serde(skip_serializing_if = "Option::is_none")]
201    region: Option<Cow<'a, str>>,
202    #[serde(skip_serializing_if = "Option::is_none")]
203    importance: Option<Cow<'a, str>>,
204    #[serde(skip_serializing_if = "Option::is_none")]
205    before: Option<Cow<'a, str>>,
206    #[serde(skip_serializing_if = "Option::is_none")]
207    after: Option<Cow<'a, str>>,
208    #[serde(skip_serializing_if = "Option::is_none")]
209    limit: Option<Cow<'a, str>>,
210}
211
212impl<'a> EconomicCalendarRequest<'a> {
213    /// Create an unfiltered economic-calendar query.
214    pub fn new() -> Self {
215        Self::default()
216    }
217
218    /// Restrict results to one country, region, or entity, e.g. `united_states`.
219    pub fn region(mut self, value: impl Into<Cow<'a, str>>) -> Self {
220        self.region = Some(value.into());
221        self
222    }
223
224    /// Restrict results to one importance level (`1` low, `2` medium, `3` high).
225    pub fn importance(mut self, value: impl Into<Cow<'a, str>>) -> Self {
226        self.importance = Some(value.into());
227        self
228    }
229
230    /// Return records newer than this `date` timestamp (Unix milliseconds).
231    pub fn before(mut self, value: impl Into<Cow<'a, str>>) -> Self {
232        self.before = Some(value.into());
233        self
234    }
235
236    /// Return records earlier than this `date` timestamp (Unix milliseconds).
237    pub fn after(mut self, value: impl Into<Cow<'a, str>>) -> Self {
238        self.after = Some(value.into());
239        self
240    }
241
242    /// Set the number of results per request. The maximum and default are 100.
243    pub fn limit(mut self, value: impl Into<Cow<'a, str>>) -> Self {
244        self.limit = Some(value.into());
245        self
246    }
247}
248
249#[cfg(test)]
250mod tests {
251    use super::*;
252
253    #[test]
254    fn market_history_uses_okx_field_names() {
255        let request = MarketDataHistoryRequest::new()
256            .module("2")
257            .inst_type("SPOT")
258            .inst_id_list("BTC-USDT")
259            .date_aggregation("daily");
260        let value = serde_json::to_value(request).unwrap();
261        assert_eq!(value["instType"], "SPOT");
262        assert_eq!(value["instIdList"], "BTC-USDT");
263        assert_eq!(value["dateAggrType"], "daily");
264    }
265}