Skip to main content

rust_okx/api/market/
responses.rs

1use serde::Deserialize;
2
3use crate::{NumberString, model::InstType};
4
5/// The latest ticker snapshot for an instrument.
6#[derive(Debug, Clone, Deserialize)]
7#[serde(rename_all = "camelCase")]
8#[non_exhaustive]
9pub struct Ticker {
10    /// Instrument type.
11    pub inst_type: InstType,
12    /// Instrument ID, e.g. `BTC-USDT`.
13    pub inst_id: String,
14    /// Last traded price.
15    pub last: NumberString,
16    /// Last traded size.
17    #[serde(default)]
18    pub last_sz: NumberString,
19    /// Best ask price.
20    #[serde(default)]
21    pub ask_px: NumberString,
22    /// Best ask size.
23    #[serde(default)]
24    pub ask_sz: NumberString,
25    /// Best bid price.
26    #[serde(default)]
27    pub bid_px: NumberString,
28    /// Best bid size.
29    #[serde(default)]
30    pub bid_sz: NumberString,
31    /// Open price over the last 24 hours.
32    #[serde(default)]
33    pub open24h: NumberString,
34    /// Highest price over the last 24 hours.
35    #[serde(default)]
36    pub high24h: NumberString,
37    /// Lowest price over the last 24 hours.
38    #[serde(default)]
39    pub low24h: NumberString,
40    /// Trading volume (base ccy) over the last 24 hours.
41    #[serde(default)]
42    pub vol24h: NumberString,
43    /// Trading volume (quote ccy) over the last 24 hours.
44    #[serde(default)]
45    pub vol_ccy24h: NumberString,
46    /// Opening price (UTC 0).
47    #[serde(default)]
48    pub sod_utc0: NumberString,
49    /// Opening price (UTC 8).
50    #[serde(default)]
51    pub sod_utc8: NumberString,
52    /// Ticker timestamp (Unix milliseconds).
53    pub ts: NumberString,
54}
55
56/// The latest index ticker snapshot.
57#[derive(Debug, Clone, Deserialize)]
58#[serde(rename_all = "camelCase")]
59#[non_exhaustive]
60pub struct IndexTicker {
61    /// Index instrument ID, e.g. `BTC-USD`.
62    pub inst_id: String,
63    /// Index price.
64    #[serde(default)]
65    pub idx_px: NumberString,
66    /// Open price over the last 24 hours.
67    #[serde(default)]
68    pub open24h: NumberString,
69    /// Highest price over the last 24 hours.
70    #[serde(default)]
71    pub high24h: NumberString,
72    /// Lowest price over the last 24 hours.
73    #[serde(default)]
74    pub low24h: NumberString,
75    /// Opening price (UTC 0).
76    #[serde(default)]
77    pub sod_utc0: NumberString,
78    /// Opening price (UTC 8).
79    #[serde(default)]
80    pub sod_utc8: NumberString,
81    /// Timestamp (Unix milliseconds).
82    #[serde(default)]
83    pub ts: NumberString,
84}
85
86/// An order book snapshot.
87#[derive(Debug, Clone, Deserialize)]
88#[serde(rename_all = "camelCase")]
89#[non_exhaustive]
90pub struct OrderBook {
91    /// Ask levels, sorted from best (lowest) price.
92    pub asks: Vec<OrderBookLevel>,
93    /// Bid levels, sorted from best (highest) price.
94    pub bids: Vec<OrderBookLevel>,
95    /// Snapshot timestamp (Unix milliseconds).
96    pub ts: NumberString,
97    /// Sequence ID of the current message (returned as a JSON number).
98    #[serde(default)]
99    pub seq_id: i64,
100}
101
102/// A single price level in an [`OrderBook`].
103///
104/// On the wire OKX encodes a level as the array
105/// `[price, size, deprecated, order_count]`.
106#[derive(Debug, Clone, Deserialize)]
107#[serde(from = "BookLevelRaw")]
108#[non_exhaustive]
109pub struct OrderBookLevel {
110    /// Price at this level.
111    pub price: NumberString,
112    /// Aggregated size available at this level.
113    pub size: NumberString,
114    /// Deprecated field (always `0`), retained for wire compatibility.
115    pub deprecated: NumberString,
116    /// Number of orders aggregated at this level.
117    pub order_count: NumberString,
118}
119
120type BookLevelRaw = (NumberString, NumberString, NumberString, NumberString);
121
122impl From<BookLevelRaw> for OrderBookLevel {
123    fn from(raw: BookLevelRaw) -> Self {
124        Self {
125            price: raw.0,
126            size: raw.1,
127            deprecated: raw.2,
128            order_count: raw.3,
129        }
130    }
131}
132
133/// A single candlestick (OHLCV) bar.
134///
135/// On the wire OKX encodes a bar as a 9-element string array.
136#[derive(Debug, Clone, Deserialize)]
137#[serde(from = "CandleRaw")]
138#[non_exhaustive]
139pub struct Candle {
140    /// Opening timestamp (Unix milliseconds).
141    pub ts: NumberString,
142    /// Open price.
143    pub open: NumberString,
144    /// Highest price.
145    pub high: NumberString,
146    /// Lowest price.
147    pub low: NumberString,
148    /// Close price.
149    pub close: NumberString,
150    /// Trading volume in contracts / base currency.
151    pub vol: NumberString,
152    /// Trading volume in quote currency.
153    pub vol_ccy: NumberString,
154    /// Trading volume in quote currency (alternate calculation).
155    pub vol_ccy_quote: NumberString,
156    /// `1` if the bar is closed/confirmed, `0` otherwise.
157    pub confirm: NumberString,
158}
159
160type CandleRaw = (
161    NumberString,
162    NumberString,
163    NumberString,
164    NumberString,
165    NumberString,
166    NumberString,
167    NumberString,
168    NumberString,
169    NumberString,
170);
171
172impl From<CandleRaw> for Candle {
173    fn from(raw: CandleRaw) -> Self {
174        Self {
175            ts: raw.0,
176            open: raw.1,
177            high: raw.2,
178            low: raw.3,
179            close: raw.4,
180            vol: raw.5,
181            vol_ccy: raw.6,
182            vol_ccy_quote: raw.7,
183            confirm: raw.8,
184        }
185    }
186}
187
188/// A public trade record.
189#[derive(Debug, Clone, Deserialize)]
190#[serde(rename_all = "camelCase")]
191#[non_exhaustive]
192pub struct MarketTrade {
193    /// Instrument ID.
194    pub inst_id: String,
195    /// Trade ID.
196    #[serde(default)]
197    pub trade_id: String,
198    /// Trade price.
199    #[serde(default)]
200    pub px: NumberString,
201    /// Trade size.
202    #[serde(default)]
203    pub sz: NumberString,
204    /// Trade side (`buy` or `sell`).
205    #[serde(default)]
206    pub side: String,
207    /// Trade source.
208    #[serde(default)]
209    pub source: String,
210    /// Trade timestamp (Unix milliseconds).
211    #[serde(default)]
212    pub ts: NumberString,
213}
214
215/// A block-trading ticker snapshot.
216///
217/// OKX block ticker rows are sparser than regular ticker rows, so fields that
218/// are required by [`Ticker`] are optional/defaulted here.
219#[derive(Debug, Clone, Deserialize)]
220#[serde(rename_all = "camelCase")]
221#[non_exhaustive]
222pub struct BlockTicker {
223    /// Instrument type, when present.
224    #[serde(default)]
225    pub inst_type: String,
226    /// Instrument ID, e.g. `BTC-USDT-SWAP`.
227    #[serde(default)]
228    pub inst_id: String,
229    /// Last traded price, when present.
230    #[serde(default)]
231    pub last: NumberString,
232    /// Last traded size, when present.
233    #[serde(default)]
234    pub last_sz: NumberString,
235    /// Best ask price, when present.
236    #[serde(default)]
237    pub ask_px: NumberString,
238    /// Best ask size, when present.
239    #[serde(default)]
240    pub ask_sz: NumberString,
241    /// Best bid price, when present.
242    #[serde(default)]
243    pub bid_px: NumberString,
244    /// Best bid size, when present.
245    #[serde(default)]
246    pub bid_sz: NumberString,
247    /// Open price over the last 24 hours, when present.
248    #[serde(default)]
249    pub open24h: NumberString,
250    /// Highest price over the last 24 hours, when present.
251    #[serde(default)]
252    pub high24h: NumberString,
253    /// Lowest price over the last 24 hours, when present.
254    #[serde(default)]
255    pub low24h: NumberString,
256    /// Trading volume over the last 24 hours, when present.
257    #[serde(default)]
258    pub vol24h: NumberString,
259    /// Trading volume in currency units over the last 24 hours, when present.
260    #[serde(default)]
261    pub vol_ccy24h: NumberString,
262    /// Opening price (UTC 0), when present.
263    #[serde(default)]
264    pub sod_utc0: NumberString,
265    /// Opening price (UTC 8), when present.
266    #[serde(default)]
267    pub sod_utc8: NumberString,
268    /// Ticker timestamp (Unix milliseconds), when present.
269    #[serde(default)]
270    pub ts: NumberString,
271}
272
273/// A public block-trade record.
274pub type BlockTrade = MarketTrade;
275
276/// A public option trade record grouped by instrument family.
277#[derive(Debug, Clone, Deserialize)]
278#[serde(rename_all = "camelCase")]
279#[non_exhaustive]
280pub struct OptionInstrumentFamilyTrade {
281    /// Instrument ID, when present.
282    #[serde(default)]
283    pub inst_id: String,
284    /// Instrument family, when present.
285    #[serde(default)]
286    pub inst_family: String,
287    /// Trade ID, when present.
288    #[serde(default)]
289    pub trade_id: String,
290    /// Trade price.
291    #[serde(default)]
292    pub px: NumberString,
293    /// Trade size.
294    #[serde(default)]
295    pub sz: NumberString,
296    /// Trade side (`buy` or `sell`), when present.
297    #[serde(default)]
298    pub side: String,
299    /// Trade timestamp (Unix milliseconds), when present.
300    #[serde(default)]
301    pub ts: NumberString,
302}
303
304/// OKX platform 24-hour trading volume.
305#[derive(Debug, Clone, Deserialize)]
306#[serde(rename_all = "camelCase")]
307#[non_exhaustive]
308pub struct PlatformVolume {
309    /// 24-hour volume in USD.
310    #[serde(default)]
311    pub vol_usd: NumberString,
312    /// 24-hour volume in CNY.
313    #[serde(default)]
314    pub vol_cny: NumberString,
315    /// Timestamp (Unix milliseconds).
316    #[serde(default)]
317    pub ts: NumberString,
318}
319
320/// The components that make up an OKX index.
321#[derive(Debug, Clone, Deserialize)]
322#[serde(rename_all = "camelCase")]
323#[non_exhaustive]
324pub struct IndexComponents {
325    /// Index name.
326    #[serde(default)]
327    pub index: String,
328    /// Latest index price.
329    #[serde(default)]
330    pub last: NumberString,
331    /// Component list.
332    #[serde(default)]
333    pub components: Vec<IndexComponent>,
334    /// Timestamp (Unix milliseconds).
335    #[serde(default)]
336    pub ts: NumberString,
337}
338
339/// A single index component.
340#[derive(Debug, Clone, Deserialize)]
341#[serde(rename_all = "camelCase")]
342#[non_exhaustive]
343pub struct IndexComponent {
344    /// Exchange name.
345    #[serde(default)]
346    pub exch: String,
347    /// Symbol used by the component exchange.
348    #[serde(default)]
349    pub symbol: String,
350    /// Component price.
351    #[serde(default)]
352    pub sym_px: NumberString,
353    /// Component weight.
354    #[serde(default)]
355    pub wgt: NumberString,
356    /// Conversion price.
357    #[serde(default)]
358    pub cnv_px: NumberString,
359}
360
361/// The USD/CNY exchange rate.
362#[derive(Debug, Clone, Deserialize)]
363#[serde(rename_all = "camelCase")]
364#[non_exhaustive]
365pub struct ExchangeRate {
366    /// USD/CNY rate.
367    #[serde(default)]
368    pub usd_cny: NumberString,
369}
370
371/// A single candlestick bar for index/mark-price endpoints (6-element array).
372#[derive(Debug, Clone, Deserialize)]
373#[serde(from = "IndexCandleRaw")]
374#[non_exhaustive]
375pub struct IndexCandle {
376    /// Opening timestamp (Unix milliseconds).
377    pub ts: NumberString,
378    /// Open price.
379    pub open: NumberString,
380    /// Highest price.
381    pub high: NumberString,
382    /// Lowest price.
383    pub low: NumberString,
384    /// Close price.
385    pub close: NumberString,
386    /// `1` if the bar is closed/confirmed, `0` otherwise.
387    pub confirm: NumberString,
388}
389
390type IndexCandleRaw = (
391    NumberString,
392    NumberString,
393    NumberString,
394    NumberString,
395    NumberString,
396    NumberString,
397);
398
399impl From<IndexCandleRaw> for IndexCandle {
400    fn from(raw: IndexCandleRaw) -> Self {
401        Self {
402            ts: raw.0,
403            open: raw.1,
404            high: raw.2,
405            low: raw.3,
406            close: raw.4,
407            confirm: raw.5,
408        }
409    }
410}
411
412/// Grouped option trades returned by the instrument-family-trades endpoint.
413#[derive(Debug, Clone, Deserialize)]
414#[serde(rename_all = "camelCase")]
415#[non_exhaustive]
416pub struct OptionFamilyTradeGroup {
417    /// 24-hour volume.
418    #[serde(default)]
419    pub vol24h: NumberString,
420    /// Option type (`C` or `P`).
421    #[serde(default)]
422    pub opt_type: String,
423    /// Individual trades within this group.
424    #[serde(default)]
425    pub trade_info: Vec<OptionInstrumentFamilyTrade>,
426}