Skip to main content

datamaxi/
generated.rs

1// Code generated by datamaxi-codegen. DO NOT EDIT.
2
3use crate::api::{Client, Config, Datamaxi, Result};
4use serde::Deserialize;
5use std::collections::HashMap;
6
7// --- Announcements ---
8
9#[derive(Clone)]
10pub struct Announcements {
11    pub client: Client,
12}
13
14impl Datamaxi for Announcements {
15    fn new(api_key: String) -> Announcements {
16        let config = Config {
17            base_url: None,
18            api_key,
19        };
20        Announcements {
21            client: Client::new(config),
22        }
23    }
24    fn new_with_base_url(api_key: String, base_url: String) -> Announcements {
25        let config = Config {
26            base_url: Some(base_url),
27            api_key,
28        };
29        Announcements {
30            client: Client::new(config),
31        }
32    }
33}
34
35impl Announcements {
36    /// Get latest announcements from centralized exchanges
37    pub fn announcements(&self, options: CexAnnouncementsOptions) -> Result<serde_json::Value> {
38        let mut parameters = HashMap::new();
39        if let Some(v) = options.page {
40            parameters.insert("page".to_string(), v.to_string());
41        }
42        if let Some(v) = options.limit {
43            parameters.insert("limit".to_string(), v.to_string());
44        }
45        if let Some(v) = options.sort {
46            parameters.insert("sort".to_string(), v.to_string());
47        }
48        if let Some(v) = options.key {
49            parameters.insert("key".to_string(), v.to_string());
50        }
51        if let Some(v) = options.exchange {
52            parameters.insert("exchange".to_string(), v.to_string());
53        }
54        if let Some(v) = options.category {
55            parameters.insert("category".to_string(), v.to_string());
56        }
57        self.client.get("/cex/announcements", Some(parameters))
58    }
59}
60
61pub struct CexAnnouncementsOptions {
62    pub page: Option<i64>,
63    pub limit: Option<i64>,
64    pub sort: Option<String>,
65    pub key: Option<String>,
66    pub exchange: Option<String>,
67    pub category: Option<String>,
68}
69
70impl CexAnnouncementsOptions {
71    pub fn new() -> Self {
72        CexAnnouncementsOptions {
73            page: None,
74            limit: None,
75            sort: None,
76            key: None,
77            exchange: None,
78            category: None,
79        }
80    }
81
82    pub fn page(mut self, page: i64) -> Self {
83        self.page = Some(page);
84        self
85    }
86
87    pub fn limit(mut self, limit: i64) -> Self {
88        self.limit = Some(limit);
89        self
90    }
91
92    pub fn sort(mut self, sort: impl Into<String>) -> Self {
93        self.sort = Some(sort.into());
94        self
95    }
96
97    pub fn key(mut self, key: impl Into<String>) -> Self {
98        self.key = Some(key.into());
99        self
100    }
101
102    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
103        self.exchange = Some(exchange.into());
104        self
105    }
106
107    pub fn category(mut self, category: impl Into<String>) -> Self {
108        self.category = Some(category.into());
109        self
110    }
111}
112
113// --- CexCandle ---
114
115#[derive(Clone)]
116pub struct CexCandle {
117    pub client: Client,
118}
119
120impl Datamaxi for CexCandle {
121    fn new(api_key: String) -> CexCandle {
122        let config = Config {
123            base_url: None,
124            api_key,
125        };
126        CexCandle {
127            client: Client::new(config),
128        }
129    }
130    fn new_with_base_url(api_key: String, base_url: String) -> CexCandle {
131        let config = Config {
132            base_url: Some(base_url),
133            api_key,
134        };
135        CexCandle {
136            client: Client::new(config),
137        }
138    }
139}
140
141impl CexCandle {
142    /// Get historical candle data for a given `exchange`, `symbol`, `interval` and `market`.
143    pub fn get(
144        &self,
145        exchange: impl Into<String>,
146        market: impl Into<String>,
147        symbol: impl Into<String>,
148        options: CexCandleOptions,
149    ) -> Result<serde_json::Value> {
150        let mut parameters = HashMap::new();
151        parameters.insert("exchange".to_string(), exchange.into());
152        parameters.insert("market".to_string(), market.into());
153        parameters.insert("symbol".to_string(), symbol.into());
154        if let Some(v) = options.currency {
155            parameters.insert("currency".to_string(), v.to_string());
156        }
157        if let Some(v) = options.interval {
158            parameters.insert("interval".to_string(), v.to_string());
159        }
160        if let Some(v) = options.from {
161            parameters.insert("from".to_string(), v.to_string());
162        }
163        if let Some(v) = options.to {
164            parameters.insert("to".to_string(), v.to_string());
165        }
166        self.client.get("/cex/candle", Some(parameters))
167    }
168
169    /// Get supported exchanges accepted by `/api/v1/cex/candle` endpoint.
170    pub fn exchanges(&self, market: impl Into<String>) -> Result<serde_json::Value> {
171        let mut parameters = HashMap::new();
172        parameters.insert("market".to_string(), market.into());
173        self.client.get("/cex/candle/exchanges", Some(parameters))
174    }
175
176    /// Fetch supported intervals accepted by `/api/v1/cex/candle` endpoint.
177    pub fn intervals(&self) -> Result<serde_json::Value> {
178        self.client.get("/cex/candle/intervals", None)
179    }
180
181    /// Fetch supported symbols accepted by `/api/v1/cex/candle` endpoint.
182    pub fn symbols(&self, options: CexCandleSymbolsOptions) -> Result<serde_json::Value> {
183        let mut parameters = HashMap::new();
184        if let Some(v) = options.exchange {
185            parameters.insert("exchange".to_string(), v.to_string());
186        }
187        if let Some(v) = options.market {
188            parameters.insert("market".to_string(), v.to_string());
189        }
190        self.client.get("/cex/candle/symbols", Some(parameters))
191    }
192}
193
194pub struct CexCandleOptions {
195    pub currency: Option<String>,
196    pub interval: Option<String>,
197    pub from: Option<String>,
198    pub to: Option<String>,
199}
200
201impl CexCandleOptions {
202    pub fn new() -> Self {
203        CexCandleOptions {
204            currency: None,
205            interval: None,
206            from: None,
207            to: None,
208        }
209    }
210
211    pub fn currency(mut self, currency: impl Into<String>) -> Self {
212        self.currency = Some(currency.into());
213        self
214    }
215
216    pub fn interval(mut self, interval: impl Into<String>) -> Self {
217        self.interval = Some(interval.into());
218        self
219    }
220
221    pub fn from(mut self, from: impl Into<String>) -> Self {
222        self.from = Some(from.into());
223        self
224    }
225
226    pub fn to(mut self, to: impl Into<String>) -> Self {
227        self.to = Some(to.into());
228        self
229    }
230}
231
232pub struct CexCandleSymbolsOptions {
233    pub exchange: Option<String>,
234    pub market: Option<String>,
235}
236
237impl CexCandleSymbolsOptions {
238    pub fn new() -> Self {
239        CexCandleSymbolsOptions {
240            exchange: None,
241            market: None,
242        }
243    }
244
245    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
246        self.exchange = Some(exchange.into());
247        self
248    }
249
250    pub fn market(mut self, market: impl Into<String>) -> Self {
251        self.market = Some(market.into());
252        self
253    }
254}
255
256// --- CexSymbol ---
257
258#[derive(Clone)]
259pub struct CexSymbol {
260    pub client: Client,
261}
262
263impl Datamaxi for CexSymbol {
264    fn new(api_key: String) -> CexSymbol {
265        let config = Config {
266            base_url: None,
267            api_key,
268        };
269        CexSymbol {
270            client: Client::new(config),
271        }
272    }
273    fn new_with_base_url(api_key: String, base_url: String) -> CexSymbol {
274        let config = Config {
275            base_url: Some(base_url),
276            api_key,
277        };
278        CexSymbol {
279            client: Client::new(config),
280        }
281    }
282}
283
284impl CexSymbol {
285    /// Return currently-active caution/warning/danger flagged symbols. Bithumb provides an expiry (end_at); other exchanges are open-ended until the next collector poll clears them.
286    pub fn cautions(&self, options: CexSymbolCautionsOptions) -> Result<serde_json::Value> {
287        let mut parameters = HashMap::new();
288        if let Some(v) = options.exchange {
289            parameters.insert("exchange".to_string(), v.to_string());
290        }
291        if let Some(v) = options.market {
292            parameters.insert("market".to_string(), v.to_string());
293        }
294        if let Some(v) = options.min_level {
295            parameters.insert("min_level".to_string(), v.to_string());
296        }
297        if let Some(v) = options.active_only {
298            parameters.insert("active_only".to_string(), v.to_string());
299        }
300        if let Some(v) = options.limit {
301            parameters.insert("limit".to_string(), v.to_string());
302        }
303        if let Some(v) = options.page {
304            parameters.insert("page".to_string(), v.to_string());
305        }
306        self.client.get("/cex/symbol/cautions", Some(parameters))
307    }
308
309    /// Return symbols with a known delisting_at timestamp or trading_status in {delisting, delisted}. Filter by time window to get upcoming delistings.
310    pub fn delistings(&self, options: CexSymbolDelistingsOptions) -> Result<serde_json::Value> {
311        let mut parameters = HashMap::new();
312        if let Some(v) = options.exchange {
313            parameters.insert("exchange".to_string(), v.to_string());
314        }
315        if let Some(v) = options.market {
316            parameters.insert("market".to_string(), v.to_string());
317        }
318        if let Some(v) = options.from_ms {
319            parameters.insert("from_ms".to_string(), v.to_string());
320        }
321        if let Some(v) = options.to_ms {
322            parameters.insert("to_ms".to_string(), v.to_string());
323        }
324        if let Some(v) = options.include_past {
325            parameters.insert("include_past".to_string(), v.to_string());
326        }
327        if let Some(v) = options.limit {
328            parameters.insert("limit".to_string(), v.to_string());
329        }
330        if let Some(v) = options.page {
331            parameters.insert("page".to_string(), v.to_string());
332        }
333        self.client.get("/cex/symbol/delistings", Some(parameters))
334    }
335
336    /// Sums long/short liquidation volume across all events in a rolling window for every exchange × quote pairing of the base asset. Window max 30d; default 24h.
337    pub fn liquidation(
338        &self,
339        base: impl Into<String>,
340        options: CexSymbolLiquidationOptions,
341    ) -> Result<serde_json::Value> {
342        let mut parameters = HashMap::new();
343        parameters.insert("base".to_string(), base.into());
344        if let Some(v) = options.window {
345            parameters.insert("window".to_string(), v.to_string());
346        }
347        self.client.get("/cex/symbol/liquidation", Some(parameters))
348    }
349
350    /// Fetch per-symbol trading status, caution flags, tags and timing metadata collected by tfsymbolmeta.
351    pub fn metadata(&self, options: CexSymbolMetadataOptions) -> Result<serde_json::Value> {
352        let mut parameters = HashMap::new();
353        if let Some(v) = options.exchange {
354            parameters.insert("exchange".to_string(), v.to_string());
355        }
356        if let Some(v) = options.market {
357            parameters.insert("market".to_string(), v.to_string());
358        }
359        if let Some(v) = options.base {
360            parameters.insert("base".to_string(), v.to_string());
361        }
362        if let Some(v) = options.quote {
363            parameters.insert("quote".to_string(), v.to_string());
364        }
365        if let Some(v) = options.status {
366            parameters.insert("status".to_string(), v.to_string());
367        }
368        if let Some(v) = options.limit {
369            parameters.insert("limit".to_string(), v.to_string());
370        }
371        if let Some(v) = options.page {
372            parameters.insert("page".to_string(), v.to_string());
373        }
374        self.client.get("/cex/symbol/metadata", Some(parameters))
375    }
376
377    /// Latest Open Interest snapshot across every futures venue carrying the given base. Sorted by USD value descending, NULLs last.
378    pub fn oi(
379        &self,
380        base: impl Into<String>,
381        options: CexSymbolOiOptions,
382    ) -> Result<serde_json::Value> {
383        let mut parameters = HashMap::new();
384        parameters.insert("base".to_string(), base.into());
385        if let Some(v) = options.exchange {
386            parameters.insert("exchange".to_string(), v.to_string());
387        }
388        self.client.get("/cex/symbol/oi", Some(parameters))
389    }
390
391    /// Enriched snapshot combining the latest OI (USD) with 1h/4h/24h change percentages and OI/24h volume ratio. Backed by the tfopeninterest taskflow's Redis HASH.
392    pub fn oi_stats(
393        &self,
394        base: impl Into<String>,
395        options: CexSymbolOiStatsOptions,
396    ) -> Result<serde_json::Value> {
397        let mut parameters = HashMap::new();
398        parameters.insert("base".to_string(), base.into());
399        if let Some(v) = options.exchange {
400            parameters.insert("exchange".to_string(), v.to_string());
401        }
402        if let Some(v) = options.currency {
403            parameters.insert("currency".to_string(), v.to_string());
404        }
405        self.client.get("/cex/symbol/oi-stats", Some(parameters))
406    }
407
408    /// Fetch (exchange, market, base, quote, tag) rows from cex_symbol_tag. Use to find every symbol flagged with a given tag (e.g. all meme coins across exchanges).
409    pub fn tags(&self, options: CexSymbolTagsOptions) -> Result<serde_json::Value> {
410        let mut parameters = HashMap::new();
411        if let Some(v) = options.tag {
412            parameters.insert("tag".to_string(), v.to_string());
413        }
414        if let Some(v) = options.exchange {
415            parameters.insert("exchange".to_string(), v.to_string());
416        }
417        if let Some(v) = options.market {
418            parameters.insert("market".to_string(), v.to_string());
419        }
420        if let Some(v) = options.base {
421            parameters.insert("base".to_string(), v.to_string());
422        }
423        if let Some(v) = options.source {
424            parameters.insert("source".to_string(), v.to_string());
425        }
426        if let Some(v) = options.min_confidence {
427            parameters.insert("min_confidence".to_string(), v.to_string());
428        }
429        if let Some(v) = options.limit {
430            parameters.insert("limit".to_string(), v.to_string());
431        }
432        if let Some(v) = options.page {
433            parameters.insert("page".to_string(), v.to_string());
434        }
435        self.client.get("/cex/symbol/tags", Some(parameters))
436    }
437
438    /// Latest 24h trading volume across every (exchange, market, quote) a token lists on. Backed by cache.latest_volume.
439    pub fn volume(
440        &self,
441        base: impl Into<String>,
442        options: CexSymbolVolumeOptions,
443    ) -> Result<serde_json::Value> {
444        let mut parameters = HashMap::new();
445        parameters.insert("base".to_string(), base.into());
446        if let Some(v) = options.market {
447            parameters.insert("market".to_string(), v.to_string());
448        }
449        self.client.get("/cex/symbol/volume", Some(parameters))
450    }
451}
452
453pub struct CexSymbolCautionsOptions {
454    pub exchange: Option<String>,
455    pub market: Option<String>,
456    pub min_level: Option<String>,
457    pub active_only: Option<bool>,
458    pub limit: Option<i64>,
459    pub page: Option<i64>,
460}
461
462impl CexSymbolCautionsOptions {
463    pub fn new() -> Self {
464        CexSymbolCautionsOptions {
465            exchange: None,
466            market: None,
467            min_level: None,
468            active_only: None,
469            limit: None,
470            page: None,
471        }
472    }
473
474    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
475        self.exchange = Some(exchange.into());
476        self
477    }
478
479    pub fn market(mut self, market: impl Into<String>) -> Self {
480        self.market = Some(market.into());
481        self
482    }
483
484    pub fn min_level(mut self, min_level: impl Into<String>) -> Self {
485        self.min_level = Some(min_level.into());
486        self
487    }
488
489    pub fn active_only(mut self, active_only: bool) -> Self {
490        self.active_only = Some(active_only);
491        self
492    }
493
494    pub fn limit(mut self, limit: i64) -> Self {
495        self.limit = Some(limit);
496        self
497    }
498
499    pub fn page(mut self, page: i64) -> Self {
500        self.page = Some(page);
501        self
502    }
503}
504
505pub struct CexSymbolDelistingsOptions {
506    pub exchange: Option<String>,
507    pub market: Option<String>,
508    pub from_ms: Option<i64>,
509    pub to_ms: Option<i64>,
510    pub include_past: Option<bool>,
511    pub limit: Option<i64>,
512    pub page: Option<i64>,
513}
514
515impl CexSymbolDelistingsOptions {
516    pub fn new() -> Self {
517        CexSymbolDelistingsOptions {
518            exchange: None,
519            market: None,
520            from_ms: None,
521            to_ms: None,
522            include_past: None,
523            limit: None,
524            page: None,
525        }
526    }
527
528    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
529        self.exchange = Some(exchange.into());
530        self
531    }
532
533    pub fn market(mut self, market: impl Into<String>) -> Self {
534        self.market = Some(market.into());
535        self
536    }
537
538    pub fn from_ms(mut self, from_ms: i64) -> Self {
539        self.from_ms = Some(from_ms);
540        self
541    }
542
543    pub fn to_ms(mut self, to_ms: i64) -> Self {
544        self.to_ms = Some(to_ms);
545        self
546    }
547
548    pub fn include_past(mut self, include_past: bool) -> Self {
549        self.include_past = Some(include_past);
550        self
551    }
552
553    pub fn limit(mut self, limit: i64) -> Self {
554        self.limit = Some(limit);
555        self
556    }
557
558    pub fn page(mut self, page: i64) -> Self {
559        self.page = Some(page);
560        self
561    }
562}
563
564pub struct CexSymbolLiquidationOptions {
565    pub window: Option<String>,
566}
567
568impl CexSymbolLiquidationOptions {
569    pub fn new() -> Self {
570        CexSymbolLiquidationOptions { window: None }
571    }
572
573    pub fn window(mut self, window: impl Into<String>) -> Self {
574        self.window = Some(window.into());
575        self
576    }
577}
578
579pub struct CexSymbolMetadataOptions {
580    pub exchange: Option<String>,
581    pub market: Option<String>,
582    pub base: Option<String>,
583    pub quote: Option<String>,
584    pub status: Option<String>,
585    pub limit: Option<i64>,
586    pub page: Option<i64>,
587}
588
589impl CexSymbolMetadataOptions {
590    pub fn new() -> Self {
591        CexSymbolMetadataOptions {
592            exchange: None,
593            market: None,
594            base: None,
595            quote: None,
596            status: None,
597            limit: None,
598            page: None,
599        }
600    }
601
602    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
603        self.exchange = Some(exchange.into());
604        self
605    }
606
607    pub fn market(mut self, market: impl Into<String>) -> Self {
608        self.market = Some(market.into());
609        self
610    }
611
612    pub fn base(mut self, base: impl Into<String>) -> Self {
613        self.base = Some(base.into());
614        self
615    }
616
617    pub fn quote(mut self, quote: impl Into<String>) -> Self {
618        self.quote = Some(quote.into());
619        self
620    }
621
622    pub fn status(mut self, status: impl Into<String>) -> Self {
623        self.status = Some(status.into());
624        self
625    }
626
627    pub fn limit(mut self, limit: i64) -> Self {
628        self.limit = Some(limit);
629        self
630    }
631
632    pub fn page(mut self, page: i64) -> Self {
633        self.page = Some(page);
634        self
635    }
636}
637
638pub struct CexSymbolOiOptions {
639    pub exchange: Option<String>,
640}
641
642impl CexSymbolOiOptions {
643    pub fn new() -> Self {
644        CexSymbolOiOptions { exchange: None }
645    }
646
647    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
648        self.exchange = Some(exchange.into());
649        self
650    }
651}
652
653pub struct CexSymbolOiStatsOptions {
654    pub exchange: Option<String>,
655    pub currency: Option<String>,
656}
657
658impl CexSymbolOiStatsOptions {
659    pub fn new() -> Self {
660        CexSymbolOiStatsOptions {
661            exchange: None,
662            currency: None,
663        }
664    }
665
666    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
667        self.exchange = Some(exchange.into());
668        self
669    }
670
671    pub fn currency(mut self, currency: impl Into<String>) -> Self {
672        self.currency = Some(currency.into());
673        self
674    }
675}
676
677pub struct CexSymbolTagsOptions {
678    pub tag: Option<String>,
679    pub exchange: Option<String>,
680    pub market: Option<String>,
681    pub base: Option<String>,
682    pub source: Option<String>,
683    pub min_confidence: Option<i64>,
684    pub limit: Option<i64>,
685    pub page: Option<i64>,
686}
687
688impl CexSymbolTagsOptions {
689    pub fn new() -> Self {
690        CexSymbolTagsOptions {
691            tag: None,
692            exchange: None,
693            market: None,
694            base: None,
695            source: None,
696            min_confidence: None,
697            limit: None,
698            page: None,
699        }
700    }
701
702    pub fn tag(mut self, tag: impl Into<String>) -> Self {
703        self.tag = Some(tag.into());
704        self
705    }
706
707    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
708        self.exchange = Some(exchange.into());
709        self
710    }
711
712    pub fn market(mut self, market: impl Into<String>) -> Self {
713        self.market = Some(market.into());
714        self
715    }
716
717    pub fn base(mut self, base: impl Into<String>) -> Self {
718        self.base = Some(base.into());
719        self
720    }
721
722    pub fn source(mut self, source: impl Into<String>) -> Self {
723        self.source = Some(source.into());
724        self
725    }
726
727    pub fn min_confidence(mut self, min_confidence: i64) -> Self {
728        self.min_confidence = Some(min_confidence);
729        self
730    }
731
732    pub fn limit(mut self, limit: i64) -> Self {
733        self.limit = Some(limit);
734        self
735    }
736
737    pub fn page(mut self, page: i64) -> Self {
738        self.page = Some(page);
739        self
740    }
741}
742
743pub struct CexSymbolVolumeOptions {
744    pub market: Option<String>,
745}
746
747impl CexSymbolVolumeOptions {
748    pub fn new() -> Self {
749        CexSymbolVolumeOptions { market: None }
750    }
751
752    pub fn market(mut self, market: impl Into<String>) -> Self {
753        self.market = Some(market.into());
754        self
755    }
756}
757
758// --- Dex ---
759
760#[derive(Clone)]
761pub struct Dex {
762    pub client: Client,
763}
764
765impl Datamaxi for Dex {
766    fn new(api_key: String) -> Dex {
767        let config = Config {
768            base_url: None,
769            api_key,
770        };
771        Dex {
772            client: Client::new(config),
773        }
774    }
775    fn new_with_base_url(api_key: String, base_url: String) -> Dex {
776        let config = Config {
777            base_url: Some(base_url),
778            api_key,
779        };
780        Dex {
781            client: Client::new(config),
782        }
783    }
784}
785
786impl Dex {
787    /// Fetch historical candle data for a given `chain`, `exchange`, `pool` and `interval`.
788    pub fn candle(
789        &self,
790        chain: impl Into<String>,
791        exchange: impl Into<String>,
792        pool: impl Into<String>,
793        options: DexCandleOptions,
794    ) -> Result<serde_json::Value> {
795        let mut parameters = HashMap::new();
796        parameters.insert("chain".to_string(), chain.into());
797        parameters.insert("exchange".to_string(), exchange.into());
798        parameters.insert("pool".to_string(), pool.into());
799        if let Some(v) = options.interval {
800            parameters.insert("interval".to_string(), v.to_string());
801        }
802        if let Some(v) = options.from {
803            parameters.insert("from".to_string(), v.to_string());
804        }
805        if let Some(v) = options.to {
806            parameters.insert("to".to_string(), v.to_string());
807        }
808        if let Some(v) = options.page {
809            parameters.insert("page".to_string(), v.to_string());
810        }
811        if let Some(v) = options.limit {
812            parameters.insert("limit".to_string(), v.to_string());
813        }
814        if let Some(v) = options.sort {
815            parameters.insert("sort".to_string(), v.to_string());
816        }
817        self.client.get("/dex/candle", Some(parameters))
818    }
819
820    /// Get supported chains accepted by `/api/v1/dex/trade`, `/api/v1/dex/candle` and `/api/v1/dex/liquidity` endpoints.
821    pub fn chains(&self) -> Result<serde_json::Value> {
822        self.client.get("/dex/chains", None)
823    }
824
825    /// Get supported exchanges accepted by `/api/v1/dex/trade`, `/api/v1/dex/candle` and `/api/v1/dex/liquidity` endpoints.
826    pub fn exchanges(&self) -> Result<serde_json::Value> {
827        self.client.get("/dex/exchanges", None)
828    }
829
830    /// Get supported intervals accepted by `/api/v1/dex/candle` endpoint.
831    pub fn intervals(&self) -> Result<serde_json::Value> {
832        self.client.get("/dex/intervals", None)
833    }
834
835    /// Get supported pools accepted by `/api/v1/dex/trade`, `/api/v1/dex/candle` and `/api/v1/dex/liquidity` endpoints.
836    pub fn pools(&self, options: DexPoolsOptions) -> Result<serde_json::Value> {
837        let mut parameters = HashMap::new();
838        if let Some(v) = options.exchange {
839            parameters.insert("exchange".to_string(), v.to_string());
840        }
841        if let Some(v) = options.chain {
842            parameters.insert("chain".to_string(), v.to_string());
843        }
844        self.client.get("/dex/pools", Some(parameters))
845    }
846
847    /// Get historical DEX trade data for a given `exchange` and `symbol`.
848    pub fn trade(
849        &self,
850        chain: impl Into<String>,
851        exchange: impl Into<String>,
852        pool: impl Into<String>,
853        options: DexTradeOptions,
854    ) -> Result<serde_json::Value> {
855        let mut parameters = HashMap::new();
856        parameters.insert("chain".to_string(), chain.into());
857        parameters.insert("exchange".to_string(), exchange.into());
858        parameters.insert("pool".to_string(), pool.into());
859        if let Some(v) = options.from {
860            parameters.insert("from".to_string(), v.to_string());
861        }
862        if let Some(v) = options.to {
863            parameters.insert("to".to_string(), v.to_string());
864        }
865        if let Some(v) = options.page {
866            parameters.insert("page".to_string(), v.to_string());
867        }
868        if let Some(v) = options.limit {
869            parameters.insert("limit".to_string(), v.to_string());
870        }
871        if let Some(v) = options.sort {
872            parameters.insert("sort".to_string(), v.to_string());
873        }
874        self.client.get("/dex/trade", Some(parameters))
875    }
876}
877
878pub struct DexCandleOptions {
879    pub interval: Option<String>,
880    pub from: Option<String>,
881    pub to: Option<String>,
882    pub page: Option<i64>,
883    pub limit: Option<i64>,
884    pub sort: Option<String>,
885}
886
887impl DexCandleOptions {
888    pub fn new() -> Self {
889        DexCandleOptions {
890            interval: None,
891            from: None,
892            to: None,
893            page: None,
894            limit: None,
895            sort: None,
896        }
897    }
898
899    pub fn interval(mut self, interval: impl Into<String>) -> Self {
900        self.interval = Some(interval.into());
901        self
902    }
903
904    pub fn from(mut self, from: impl Into<String>) -> Self {
905        self.from = Some(from.into());
906        self
907    }
908
909    pub fn to(mut self, to: impl Into<String>) -> Self {
910        self.to = Some(to.into());
911        self
912    }
913
914    pub fn page(mut self, page: i64) -> Self {
915        self.page = Some(page);
916        self
917    }
918
919    pub fn limit(mut self, limit: i64) -> Self {
920        self.limit = Some(limit);
921        self
922    }
923
924    pub fn sort(mut self, sort: impl Into<String>) -> Self {
925        self.sort = Some(sort.into());
926        self
927    }
928}
929
930pub struct DexPoolsOptions {
931    pub exchange: Option<String>,
932    pub chain: Option<String>,
933}
934
935impl DexPoolsOptions {
936    pub fn new() -> Self {
937        DexPoolsOptions {
938            exchange: None,
939            chain: None,
940        }
941    }
942
943    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
944        self.exchange = Some(exchange.into());
945        self
946    }
947
948    pub fn chain(mut self, chain: impl Into<String>) -> Self {
949        self.chain = Some(chain.into());
950        self
951    }
952}
953
954pub struct DexTradeOptions {
955    pub from: Option<String>,
956    pub to: Option<String>,
957    pub page: Option<i64>,
958    pub limit: Option<i64>,
959    pub sort: Option<String>,
960}
961
962impl DexTradeOptions {
963    pub fn new() -> Self {
964        DexTradeOptions {
965            from: None,
966            to: None,
967            page: None,
968            limit: None,
969            sort: None,
970        }
971    }
972
973    pub fn from(mut self, from: impl Into<String>) -> Self {
974        self.from = Some(from.into());
975        self
976    }
977
978    pub fn to(mut self, to: impl Into<String>) -> Self {
979        self.to = Some(to.into());
980        self
981    }
982
983    pub fn page(mut self, page: i64) -> Self {
984        self.page = Some(page);
985        self
986    }
987
988    pub fn limit(mut self, limit: i64) -> Self {
989        self.limit = Some(limit);
990        self
991    }
992
993    pub fn sort(mut self, sort: impl Into<String>) -> Self {
994        self.sort = Some(sort.into());
995        self
996    }
997}
998
999// --- Forex ---
1000
1001#[derive(Clone)]
1002pub struct Forex {
1003    pub client: Client,
1004}
1005
1006impl Datamaxi for Forex {
1007    fn new(api_key: String) -> Forex {
1008        let config = Config {
1009            base_url: None,
1010            api_key,
1011        };
1012        Forex {
1013            client: Client::new(config),
1014        }
1015    }
1016    fn new_with_base_url(api_key: String, base_url: String) -> Forex {
1017        let config = Config {
1018            base_url: Some(base_url),
1019            api_key,
1020        };
1021        Forex {
1022            client: Client::new(config),
1023        }
1024    }
1025}
1026
1027impl Forex {
1028    /// Get the latest forex rate for given symbol.
1029    pub fn get(&self, options: ForexOptions) -> Result<serde_json::Value> {
1030        let mut parameters = HashMap::new();
1031        if let Some(v) = options.symbol {
1032            parameters.insert("symbol".to_string(), v.to_string());
1033        }
1034        self.client.get("/forex", Some(parameters))
1035    }
1036
1037    /// Get supported forex symbols.
1038    pub fn symbols(&self) -> Result<serde_json::Value> {
1039        self.client.get("/forex/symbols", None)
1040    }
1041}
1042
1043pub struct ForexOptions {
1044    pub symbol: Option<String>,
1045}
1046
1047impl ForexOptions {
1048    pub fn new() -> Self {
1049        ForexOptions { symbol: None }
1050    }
1051
1052    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
1053        self.symbol = Some(symbol.into());
1054        self
1055    }
1056}
1057
1058// --- FundingRate ---
1059
1060#[derive(Clone)]
1061pub struct FundingRate {
1062    pub client: Client,
1063}
1064
1065impl Datamaxi for FundingRate {
1066    fn new(api_key: String) -> FundingRate {
1067        let config = Config {
1068            base_url: None,
1069            api_key,
1070        };
1071        FundingRate {
1072            client: Client::new(config),
1073        }
1074    }
1075    fn new_with_base_url(api_key: String, base_url: String) -> FundingRate {
1076        let config = Config {
1077            base_url: Some(base_url),
1078            api_key,
1079        };
1080        FundingRate {
1081            client: Client::new(config),
1082        }
1083    }
1084}
1085
1086impl FundingRate {
1087    /// Get supported exchanges accepted by `/api/v1/funding-rate` endpoint.
1088    pub fn exchanges(&self) -> Result<serde_json::Value> {
1089        self.client.get("/funding-rate/exchanges", None)
1090    }
1091
1092    /// Get historical funding rate data for a given `exchange` and `symbol`.
1093    pub fn history(
1094        &self,
1095        exchange: impl Into<String>,
1096        symbol: impl Into<String>,
1097        options: FundingRateHistoryOptions,
1098    ) -> Result<serde_json::Value> {
1099        let mut parameters = HashMap::new();
1100        parameters.insert("exchange".to_string(), exchange.into());
1101        parameters.insert("symbol".to_string(), symbol.into());
1102        if let Some(v) = options.page {
1103            parameters.insert("page".to_string(), v.to_string());
1104        }
1105        if let Some(v) = options.limit {
1106            parameters.insert("limit".to_string(), v.to_string());
1107        }
1108        if let Some(v) = options.from {
1109            parameters.insert("from".to_string(), v.to_string());
1110        }
1111        if let Some(v) = options.to {
1112            parameters.insert("to".to_string(), v.to_string());
1113        }
1114        if let Some(v) = options.sort {
1115            parameters.insert("sort".to_string(), v.to_string());
1116        }
1117        self.client.get("/funding-rate/history", Some(parameters))
1118    }
1119
1120    /// Fetch the latest funding rate data for a given `exchange` and `symbol`.
1121    pub fn latest(
1122        &self,
1123        exchange: impl Into<String>,
1124        symbol: impl Into<String>,
1125    ) -> Result<serde_json::Value> {
1126        let mut parameters = HashMap::new();
1127        parameters.insert("exchange".to_string(), exchange.into());
1128        parameters.insert("symbol".to_string(), symbol.into());
1129        self.client.get("/funding-rate/latest", Some(parameters))
1130    }
1131
1132    /// Fetch supported symbols accepted by `/api/v1/funding-rate` endpoint.
1133    pub fn symbols(&self, options: FundingRateSymbolsOptions) -> Result<serde_json::Value> {
1134        let mut parameters = HashMap::new();
1135        if let Some(v) = options.exchange {
1136            parameters.insert("exchange".to_string(), v.to_string());
1137        }
1138        self.client.get("/funding-rate/symbols", Some(parameters))
1139    }
1140}
1141
1142pub struct FundingRateHistoryOptions {
1143    pub page: Option<String>,
1144    pub limit: Option<String>,
1145    pub from: Option<String>,
1146    pub to: Option<String>,
1147    pub sort: Option<String>,
1148}
1149
1150impl FundingRateHistoryOptions {
1151    pub fn new() -> Self {
1152        FundingRateHistoryOptions {
1153            page: None,
1154            limit: None,
1155            from: None,
1156            to: None,
1157            sort: None,
1158        }
1159    }
1160
1161    pub fn page(mut self, page: impl Into<String>) -> Self {
1162        self.page = Some(page.into());
1163        self
1164    }
1165
1166    pub fn limit(mut self, limit: impl Into<String>) -> Self {
1167        self.limit = Some(limit.into());
1168        self
1169    }
1170
1171    pub fn from(mut self, from: impl Into<String>) -> Self {
1172        self.from = Some(from.into());
1173        self
1174    }
1175
1176    pub fn to(mut self, to: impl Into<String>) -> Self {
1177        self.to = Some(to.into());
1178        self
1179    }
1180
1181    pub fn sort(mut self, sort: impl Into<String>) -> Self {
1182        self.sort = Some(sort.into());
1183        self
1184    }
1185}
1186
1187pub struct FundingRateSymbolsOptions {
1188    pub exchange: Option<String>,
1189}
1190
1191impl FundingRateSymbolsOptions {
1192    pub fn new() -> Self {
1193        FundingRateSymbolsOptions { exchange: None }
1194    }
1195
1196    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1197        self.exchange = Some(exchange.into());
1198        self
1199    }
1200}
1201
1202// --- IndexPrice ---
1203
1204#[derive(Clone)]
1205pub struct IndexPrice {
1206    pub client: Client,
1207}
1208
1209impl Datamaxi for IndexPrice {
1210    fn new(api_key: String) -> IndexPrice {
1211        let config = Config {
1212            base_url: None,
1213            api_key,
1214        };
1215        IndexPrice {
1216            client: Client::new(config),
1217        }
1218    }
1219    fn new_with_base_url(api_key: String, base_url: String) -> IndexPrice {
1220        let config = Config {
1221            base_url: Some(base_url),
1222            api_key,
1223        };
1224        IndexPrice {
1225            client: Client::new(config),
1226        }
1227    }
1228}
1229
1230impl IndexPrice {
1231    /// Get index price
1232    pub fn get(
1233        &self,
1234        asset: impl Into<String>,
1235        options: IndexPriceOptions,
1236    ) -> Result<serde_json::Value> {
1237        let mut parameters = HashMap::new();
1238        parameters.insert("asset".to_string(), asset.into());
1239        if let Some(v) = options.from {
1240            parameters.insert("from".to_string(), v.to_string());
1241        }
1242        if let Some(v) = options.to {
1243            parameters.insert("to".to_string(), v.to_string());
1244        }
1245        if let Some(v) = options.interval {
1246            parameters.insert("interval".to_string(), v.to_string());
1247        }
1248        self.client.get("/index-price", Some(parameters))
1249    }
1250}
1251
1252pub struct IndexPriceOptions {
1253    pub from: Option<String>,
1254    pub to: Option<String>,
1255    pub interval: Option<String>,
1256}
1257
1258impl IndexPriceOptions {
1259    pub fn new() -> Self {
1260        IndexPriceOptions {
1261            from: None,
1262            to: None,
1263            interval: None,
1264        }
1265    }
1266
1267    pub fn from(mut self, from: impl Into<String>) -> Self {
1268        self.from = Some(from.into());
1269        self
1270    }
1271
1272    pub fn to(mut self, to: impl Into<String>) -> Self {
1273        self.to = Some(to.into());
1274        self
1275    }
1276
1277    pub fn interval(mut self, interval: impl Into<String>) -> Self {
1278        self.interval = Some(interval.into());
1279        self
1280    }
1281}
1282
1283// --- Liquidation ---
1284
1285#[derive(Clone)]
1286pub struct Liquidation {
1287    pub client: Client,
1288}
1289
1290impl Datamaxi for Liquidation {
1291    fn new(api_key: String) -> Liquidation {
1292        let config = Config {
1293            base_url: None,
1294            api_key,
1295        };
1296        Liquidation {
1297            client: Client::new(config),
1298        }
1299    }
1300    fn new_with_base_url(api_key: String, base_url: String) -> Liquidation {
1301        let config = Config {
1302            base_url: Some(base_url),
1303            api_key,
1304        };
1305        Liquidation {
1306            client: Client::new(config),
1307        }
1308    }
1309}
1310
1311impl Liquidation {
1312    /// Fetch recent liquidation events for a futures symbol on a given exchange, newest first.
1313    pub fn get(
1314        &self,
1315        exchange: impl Into<String>,
1316        symbol: impl Into<String>,
1317        options: LiquidationOptions,
1318    ) -> Result<serde_json::Value> {
1319        let mut parameters = HashMap::new();
1320        parameters.insert("exchange".to_string(), exchange.into());
1321        parameters.insert("symbol".to_string(), symbol.into());
1322        if let Some(v) = options.limit {
1323            parameters.insert("limit".to_string(), v.to_string());
1324        }
1325        self.client.get("/liquidation", Some(parameters))
1326    }
1327
1328    /// Fetch most recent liquidation events across all futures symbols, newest first. Use together with the `/ws/v1/liquidation/feed` firehose for a live feed view.
1329    pub fn feed(&self, options: LiquidationFeedOptions) -> Result<serde_json::Value> {
1330        let mut parameters = HashMap::new();
1331        if let Some(v) = options.exchange {
1332            parameters.insert("exchange".to_string(), v.to_string());
1333        }
1334        if let Some(v) = options.base {
1335            parameters.insert("base".to_string(), v.to_string());
1336        }
1337        if let Some(v) = options.minVolumeUsd {
1338            parameters.insert("minVolumeUsd".to_string(), v.to_string());
1339        }
1340        if let Some(v) = options.limit {
1341            parameters.insert("limit".to_string(), v.to_string());
1342        }
1343        self.client.get("/liquidation/feed", Some(parameters))
1344    }
1345
1346    /// Aggregated long/short liquidation USD by (token, exchange) over a rolling window. Result is cached for ~10s. Sub-1h windows are not supported; use the WS feed for finer granularity.
1347    pub fn heatmap(&self, options: LiquidationHeatmapOptions) -> Result<serde_json::Value> {
1348        let mut parameters = HashMap::new();
1349        if let Some(v) = options.window {
1350            parameters.insert("window".to_string(), v.to_string());
1351        }
1352        if let Some(v) = options.topN {
1353            parameters.insert("topN".to_string(), v.to_string());
1354        }
1355        self.client.get("/liquidation/heatmap", Some(parameters))
1356    }
1357
1358    /// Coinglass-style liquidation map for one perpetual pair. Returns a price-grid breakdown of where leveraged positions would be liquidated, split by leverage tier (10x / 25x / 50x / 100x) and side (long below current price, short above). Built from current OI + last-24h candle entries + a fixed leverage-cohort prior. Read the `assumptions` field in the response for the modelling disclaimer. Cached server-side (~5s) so back-to-back polls are cheap.
1359    pub fn map(
1360        &self,
1361        base: impl Into<String>,
1362        options: LiquidationMapOptions,
1363    ) -> Result<serde_json::Value> {
1364        let mut parameters = HashMap::new();
1365        parameters.insert("base".to_string(), base.into());
1366        if let Some(v) = options.exchange {
1367            parameters.insert("exchange".to_string(), v.to_string());
1368        }
1369        if let Some(v) = options.quote {
1370            parameters.insert("quote".to_string(), v.to_string());
1371        }
1372        self.client.get("/liquidation/map", Some(parameters))
1373    }
1374
1375    /// Aggregate liquidation stats (total, long/short split, count, venue count, biggest single event) over a 1h/4h/24h window. Backs the liquidation page KPI strip for windows the live feed buffer can't cover.
1376    pub fn stats(&self, options: LiquidationStatsOptions) -> Result<serde_json::Value> {
1377        let mut parameters = HashMap::new();
1378        if let Some(v) = options.window {
1379            parameters.insert("window".to_string(), v.to_string());
1380        }
1381        if let Some(v) = options.exchange {
1382            parameters.insert("exchange".to_string(), v.to_string());
1383        }
1384        if let Some(v) = options.minVolumeUsd {
1385            parameters.insert("minVolumeUsd".to_string(), v.to_string());
1386        }
1387        self.client.get("/liquidation/stats", Some(parameters))
1388    }
1389
1390    /// Bucketed long / short liquidation USD over time for a single (base, quote) pair, joined with the futures-candle close as a reference price line. Long/short USD comes from `cex.liquidation` (Side='sell' = long position liquidated, 'buy' = short). Price comes from `candle.futures_1m` on the requested exchange — or Binance as the reference when none is specified. Cached ~30s server-side.
1391    pub fn symbol_history(
1392        &self,
1393        symbol: impl Into<String>,
1394        options: LiquidationSymbolHistoryOptions,
1395    ) -> Result<serde_json::Value> {
1396        let mut parameters = HashMap::new();
1397        parameters.insert("symbol".to_string(), symbol.into());
1398        if let Some(v) = options.quote {
1399            parameters.insert("quote".to_string(), v.to_string());
1400        }
1401        if let Some(v) = options.exchange {
1402            parameters.insert("exchange".to_string(), v.to_string());
1403        }
1404        if let Some(v) = options.interval {
1405            parameters.insert("interval".to_string(), v.to_string());
1406        }
1407        if let Some(v) = options.window {
1408            parameters.insert("window".to_string(), v.to_string());
1409        }
1410        self.client
1411            .get("/liquidation/symbol-history", Some(parameters))
1412    }
1413}
1414
1415pub struct LiquidationOptions {
1416    pub limit: Option<i64>,
1417}
1418
1419impl LiquidationOptions {
1420    pub fn new() -> Self {
1421        LiquidationOptions { limit: None }
1422    }
1423
1424    pub fn limit(mut self, limit: i64) -> Self {
1425        self.limit = Some(limit);
1426        self
1427    }
1428}
1429
1430pub struct LiquidationFeedOptions {
1431    pub exchange: Option<String>,
1432    pub base: Option<String>,
1433    pub minVolumeUsd: Option<f64>,
1434    pub limit: Option<i64>,
1435}
1436
1437impl LiquidationFeedOptions {
1438    pub fn new() -> Self {
1439        LiquidationFeedOptions {
1440            exchange: None,
1441            base: None,
1442            minVolumeUsd: None,
1443            limit: None,
1444        }
1445    }
1446
1447    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1448        self.exchange = Some(exchange.into());
1449        self
1450    }
1451
1452    pub fn base(mut self, base: impl Into<String>) -> Self {
1453        self.base = Some(base.into());
1454        self
1455    }
1456
1457    pub fn minVolumeUsd(mut self, minVolumeUsd: f64) -> Self {
1458        self.minVolumeUsd = Some(minVolumeUsd);
1459        self
1460    }
1461
1462    pub fn limit(mut self, limit: i64) -> Self {
1463        self.limit = Some(limit);
1464        self
1465    }
1466}
1467
1468pub struct LiquidationHeatmapOptions {
1469    pub window: Option<String>,
1470    pub topN: Option<i64>,
1471}
1472
1473impl LiquidationHeatmapOptions {
1474    pub fn new() -> Self {
1475        LiquidationHeatmapOptions {
1476            window: None,
1477            topN: None,
1478        }
1479    }
1480
1481    pub fn window(mut self, window: impl Into<String>) -> Self {
1482        self.window = Some(window.into());
1483        self
1484    }
1485
1486    pub fn topN(mut self, topN: i64) -> Self {
1487        self.topN = Some(topN);
1488        self
1489    }
1490}
1491
1492pub struct LiquidationMapOptions {
1493    pub exchange: Option<String>,
1494    pub quote: Option<String>,
1495}
1496
1497impl LiquidationMapOptions {
1498    pub fn new() -> Self {
1499        LiquidationMapOptions {
1500            exchange: None,
1501            quote: None,
1502        }
1503    }
1504
1505    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1506        self.exchange = Some(exchange.into());
1507        self
1508    }
1509
1510    pub fn quote(mut self, quote: impl Into<String>) -> Self {
1511        self.quote = Some(quote.into());
1512        self
1513    }
1514}
1515
1516pub struct LiquidationStatsOptions {
1517    pub window: Option<String>,
1518    pub exchange: Option<String>,
1519    pub minVolumeUsd: Option<f64>,
1520}
1521
1522impl LiquidationStatsOptions {
1523    pub fn new() -> Self {
1524        LiquidationStatsOptions {
1525            window: None,
1526            exchange: None,
1527            minVolumeUsd: None,
1528        }
1529    }
1530
1531    pub fn window(mut self, window: impl Into<String>) -> Self {
1532        self.window = Some(window.into());
1533        self
1534    }
1535
1536    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1537        self.exchange = Some(exchange.into());
1538        self
1539    }
1540
1541    pub fn minVolumeUsd(mut self, minVolumeUsd: f64) -> Self {
1542        self.minVolumeUsd = Some(minVolumeUsd);
1543        self
1544    }
1545}
1546
1547pub struct LiquidationSymbolHistoryOptions {
1548    pub quote: Option<String>,
1549    pub exchange: Option<String>,
1550    pub interval: Option<String>,
1551    pub window: Option<String>,
1552}
1553
1554impl LiquidationSymbolHistoryOptions {
1555    pub fn new() -> Self {
1556        LiquidationSymbolHistoryOptions {
1557            quote: None,
1558            exchange: None,
1559            interval: None,
1560            window: None,
1561        }
1562    }
1563
1564    pub fn quote(mut self, quote: impl Into<String>) -> Self {
1565        self.quote = Some(quote.into());
1566        self
1567    }
1568
1569    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1570        self.exchange = Some(exchange.into());
1571        self
1572    }
1573
1574    pub fn interval(mut self, interval: impl Into<String>) -> Self {
1575        self.interval = Some(interval.into());
1576        self
1577    }
1578
1579    pub fn window(mut self, window: impl Into<String>) -> Self {
1580        self.window = Some(window.into());
1581        self
1582    }
1583}
1584
1585// --- Listing ---
1586
1587#[derive(Clone)]
1588pub struct Listing {
1589    pub client: Client,
1590}
1591
1592impl Datamaxi for Listing {
1593    fn new(api_key: String) -> Listing {
1594        let config = Config {
1595            base_url: None,
1596            api_key,
1597        };
1598        Listing {
1599            client: Client::new(config),
1600        }
1601    }
1602    fn new_with_base_url(api_key: String, base_url: String) -> Listing {
1603        let config = Config {
1604            base_url: Some(base_url),
1605            api_key,
1606        };
1607        Listing {
1608            client: Client::new(config),
1609        }
1610    }
1611}
1612
1613impl Listing {
1614    /// Get historical token listings for Upbit and Bithumb for KRW market
1615    pub fn historical(&self, options: ListingsHistoricalOptions) -> Result<serde_json::Value> {
1616        let mut parameters = HashMap::new();
1617        if let Some(v) = options.refresh {
1618            parameters.insert("refresh".to_string(), v.to_string());
1619        }
1620        self.client.get("/listings/historical", Some(parameters))
1621    }
1622}
1623
1624pub struct ListingsHistoricalOptions {
1625    pub refresh: Option<bool>,
1626}
1627
1628impl ListingsHistoricalOptions {
1629    pub fn new() -> Self {
1630        ListingsHistoricalOptions { refresh: None }
1631    }
1632
1633    pub fn refresh(mut self, refresh: bool) -> Self {
1634        self.refresh = Some(refresh);
1635        self
1636    }
1637}
1638
1639// --- MarginBorrow ---
1640
1641#[derive(Clone)]
1642pub struct MarginBorrow {
1643    pub client: Client,
1644}
1645
1646impl Datamaxi for MarginBorrow {
1647    fn new(api_key: String) -> MarginBorrow {
1648        let config = Config {
1649            base_url: None,
1650            api_key,
1651        };
1652        MarginBorrow {
1653            client: Client::new(config),
1654        }
1655    }
1656    fn new_with_base_url(api_key: String, base_url: String) -> MarginBorrow {
1657        let config = Config {
1658            base_url: Some(base_url),
1659            api_key,
1660        };
1661        MarginBorrow {
1662            client: Client::new(config),
1663        }
1664    }
1665}
1666
1667impl MarginBorrow {
1668    /// Get the margin borrow data.
1669    pub fn get(&self, asset: impl Into<String>) -> Result<serde_json::Value> {
1670        let mut parameters = HashMap::new();
1671        parameters.insert("asset".to_string(), asset.into());
1672        self.client.get("/margin-borrow", Some(parameters))
1673    }
1674}
1675
1676// --- NaverTrend ---
1677
1678#[derive(Clone)]
1679pub struct NaverTrend {
1680    pub client: Client,
1681}
1682
1683impl Datamaxi for NaverTrend {
1684    fn new(api_key: String) -> NaverTrend {
1685        let config = Config {
1686            base_url: None,
1687            api_key,
1688        };
1689        NaverTrend {
1690            client: Client::new(config),
1691        }
1692    }
1693    fn new_with_base_url(api_key: String, base_url: String) -> NaverTrend {
1694        let config = Config {
1695            base_url: Some(base_url),
1696            api_key,
1697        };
1698        NaverTrend {
1699            client: Client::new(config),
1700        }
1701    }
1702}
1703
1704impl NaverTrend {
1705    /// Get Naver trend data with a daily frequency for a project that is associated with a given [symbol](./symbols). The values in response are normalized into a range from 0 to 100, where 0 corresponds to a minimum interest, and 100 corresponds to a maximum interest of users in Naver search engine.
1706    pub fn get(&self, symbol: impl Into<String>) -> Result<serde_json::Value> {
1707        let mut parameters = HashMap::new();
1708        parameters.insert("symbol".to_string(), symbol.into());
1709        self.client.get("/naver-trend", Some(parameters))
1710    }
1711
1712    /// Get crypto symbols that are accepted by [Naver trend endpoint](./trend).
1713    pub fn symbols(&self) -> Result<serde_json::Value> {
1714        self.client.get("/naver-trend/symbols", None)
1715    }
1716}
1717
1718// --- OpenInterest ---
1719
1720#[derive(Clone)]
1721pub struct OpenInterest {
1722    pub client: Client,
1723}
1724
1725impl Datamaxi for OpenInterest {
1726    fn new(api_key: String) -> OpenInterest {
1727        let config = Config {
1728            base_url: None,
1729            api_key,
1730        };
1731        OpenInterest {
1732            client: Client::new(config),
1733        }
1734    }
1735    fn new_with_base_url(api_key: String, base_url: String) -> OpenInterest {
1736        let config = Config {
1737            base_url: Some(base_url),
1738            api_key,
1739        };
1740        OpenInterest {
1741            client: Client::new(config),
1742        }
1743    }
1744}
1745
1746impl OpenInterest {
1747    /// Fetch the most recent Open Interest snapshot for a futures symbol on a given exchange.
1748    pub fn get(
1749        &self,
1750        exchange: impl Into<String>,
1751        symbol: impl Into<String>,
1752    ) -> Result<serde_json::Value> {
1753        let mut parameters = HashMap::new();
1754        parameters.insert("exchange".to_string(), exchange.into());
1755        parameters.insert("symbol".to_string(), symbol.into());
1756        self.client.get("/open-interest", Some(parameters))
1757    }
1758
1759    /// Historical Open Interest time series for a single token, broken down per exchange and aggregated to a fixed bucket (avg within bucket). The default lookback depends on the requested interval — 7 days for 1h, 30 days for 4h, 1 year for 1d — so callers don't have to hand-tune `from`/`to` for typical queries. The response also includes token metadata (icon, symbol, name) so a single call paints the whole header strip.
1760    pub fn history_aggregated(
1761        &self,
1762        token_id: impl Into<String>,
1763        options: OpenInterestHistoryAggregatedOptions,
1764    ) -> Result<serde_json::Value> {
1765        let mut parameters = HashMap::new();
1766        parameters.insert("token_id".to_string(), token_id.into());
1767        if let Some(v) = options.interval {
1768            parameters.insert("interval".to_string(), v.to_string());
1769        }
1770        if let Some(v) = options.from {
1771            parameters.insert("from".to_string(), v.to_string());
1772        }
1773        if let Some(v) = options.to {
1774            parameters.insert("to".to_string(), v.to_string());
1775        }
1776        self.client
1777            .get("/open-interest/history-aggregated", Some(parameters))
1778    }
1779
1780    /// Fetch latest Open Interest snapshots across exchanges/symbols. Optionally filter by `exchange`. Results are sorted by `openInterestUsd` descending (null values last).
1781    pub fn list(&self, options: OpenInterestListOptions) -> Result<serde_json::Value> {
1782        let mut parameters = HashMap::new();
1783        if let Some(v) = options.exchange {
1784            parameters.insert("exchange".to_string(), v.to_string());
1785        }
1786        self.client.get("/open-interest/list", Some(parameters))
1787    }
1788
1789    /// Paginated token × exchange Open Interest matrix. For each base asset we list the per-exchange notional OI in USD (when a venue carries the token) and `null` when it doesn't trade there. The matrix is sortable by any exchange column and searchable by base symbol — same shape the DataMaxi+ dashboard uses on `/open-interest`. Cached snapshot rebuilds every few seconds, so back-to-back requests are cheap.
1790    pub fn overview(&self, options: OpenInterestOverviewOptions) -> Result<serde_json::Value> {
1791        let mut parameters = HashMap::new();
1792        if let Some(v) = options.page {
1793            parameters.insert("page".to_string(), v.to_string());
1794        }
1795        if let Some(v) = options.limit {
1796            parameters.insert("limit".to_string(), v.to_string());
1797        }
1798        if let Some(v) = options.key {
1799            parameters.insert("key".to_string(), v.to_string());
1800        }
1801        if let Some(v) = options.sort {
1802            parameters.insert("sort".to_string(), v.to_string());
1803        }
1804        if let Some(v) = options.query {
1805            parameters.insert("query".to_string(), v.to_string());
1806        }
1807        self.client.get("/open-interest/overview", Some(parameters))
1808    }
1809
1810    /// Top-line aggregates over the current Open Interest snapshot — total OI USD, top tokens by OI, top exchanges by OI, and the count of venues currently reporting any base. Powers the OI page's KPI strip and breakdown card without forcing the caller to fetch the full token list.
1811    pub fn summary(&self, options: OpenInterestSummaryOptions) -> Result<serde_json::Value> {
1812        let mut parameters = HashMap::new();
1813        if let Some(v) = options.topN {
1814            parameters.insert("topN".to_string(), v.to_string());
1815        }
1816        self.client.get("/open-interest/summary", Some(parameters))
1817    }
1818}
1819
1820pub struct OpenInterestHistoryAggregatedOptions {
1821    pub interval: Option<String>,
1822    pub from: Option<i64>,
1823    pub to: Option<i64>,
1824}
1825
1826impl OpenInterestHistoryAggregatedOptions {
1827    pub fn new() -> Self {
1828        OpenInterestHistoryAggregatedOptions {
1829            interval: None,
1830            from: None,
1831            to: None,
1832        }
1833    }
1834
1835    pub fn interval(mut self, interval: impl Into<String>) -> Self {
1836        self.interval = Some(interval.into());
1837        self
1838    }
1839
1840    pub fn from(mut self, from: i64) -> Self {
1841        self.from = Some(from);
1842        self
1843    }
1844
1845    pub fn to(mut self, to: i64) -> Self {
1846        self.to = Some(to);
1847        self
1848    }
1849}
1850
1851pub struct OpenInterestListOptions {
1852    pub exchange: Option<String>,
1853}
1854
1855impl OpenInterestListOptions {
1856    pub fn new() -> Self {
1857        OpenInterestListOptions { exchange: None }
1858    }
1859
1860    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
1861        self.exchange = Some(exchange.into());
1862        self
1863    }
1864}
1865
1866pub struct OpenInterestOverviewOptions {
1867    pub page: Option<i64>,
1868    pub limit: Option<i64>,
1869    pub key: Option<String>,
1870    pub sort: Option<String>,
1871    pub query: Option<String>,
1872}
1873
1874impl OpenInterestOverviewOptions {
1875    pub fn new() -> Self {
1876        OpenInterestOverviewOptions {
1877            page: None,
1878            limit: None,
1879            key: None,
1880            sort: None,
1881            query: None,
1882        }
1883    }
1884
1885    pub fn page(mut self, page: i64) -> Self {
1886        self.page = Some(page);
1887        self
1888    }
1889
1890    pub fn limit(mut self, limit: i64) -> Self {
1891        self.limit = Some(limit);
1892        self
1893    }
1894
1895    pub fn key(mut self, key: impl Into<String>) -> Self {
1896        self.key = Some(key.into());
1897        self
1898    }
1899
1900    pub fn sort(mut self, sort: impl Into<String>) -> Self {
1901        self.sort = Some(sort.into());
1902        self
1903    }
1904
1905    pub fn query(mut self, query: impl Into<String>) -> Self {
1906        self.query = Some(query.into());
1907        self
1908    }
1909}
1910
1911pub struct OpenInterestSummaryOptions {
1912    pub topN: Option<i64>,
1913}
1914
1915impl OpenInterestSummaryOptions {
1916    pub fn new() -> Self {
1917        OpenInterestSummaryOptions { topN: None }
1918    }
1919
1920    pub fn topN(mut self, topN: i64) -> Self {
1921        self.topN = Some(topN);
1922        self
1923    }
1924}
1925
1926// --- Premium ---
1927
1928#[derive(Clone)]
1929pub struct Premium {
1930    pub client: Client,
1931}
1932
1933impl Datamaxi for Premium {
1934    fn new(api_key: String) -> Premium {
1935        let config = Config {
1936            base_url: None,
1937            api_key,
1938        };
1939        Premium {
1940            client: Client::new(config),
1941        }
1942    }
1943    fn new_with_base_url(api_key: String, base_url: String) -> Premium {
1944        let config = Config {
1945            base_url: Some(base_url),
1946            api_key,
1947        };
1948        Premium {
1949            client: Client::new(config),
1950        }
1951    }
1952}
1953
1954impl Premium {
1955    /// Returns the sorted list of categorical token tags currently indexed for the premium table filter. Updated on the aggregator's tagstate reload cadence.
1956    pub fn tags(&self) -> Result<serde_json::Value> {
1957        self.client.get("/front/premium/tags", None)
1958    }
1959
1960    /// Get real-time premium (price difference) data across exchanges.
1961    pub fn get(&self, options: PremiumOptions) -> Result<serde_json::Value> {
1962        let mut parameters = HashMap::new();
1963        if let Some(v) = options.source_exchange {
1964            parameters.insert("source_exchange".to_string(), v.to_string());
1965        }
1966        if let Some(v) = options.target_exchange {
1967            parameters.insert("target_exchange".to_string(), v.to_string());
1968        }
1969        if let Some(v) = options.asset {
1970            parameters.insert("asset".to_string(), v.to_string());
1971        }
1972        if let Some(v) = options.source_quote {
1973            parameters.insert("source_quote".to_string(), v.to_string());
1974        }
1975        if let Some(v) = options.target_quote {
1976            parameters.insert("target_quote".to_string(), v.to_string());
1977        }
1978        if let Some(v) = options.source_market {
1979            parameters.insert("source_market".to_string(), v.to_string());
1980        }
1981        if let Some(v) = options.target_market {
1982            parameters.insert("target_market".to_string(), v.to_string());
1983        }
1984        if let Some(v) = options.premium_type {
1985            parameters.insert("premium_type".to_string(), v.to_string());
1986        }
1987        if let Some(v) = options.currency {
1988            parameters.insert("currency".to_string(), v.to_string());
1989        }
1990        if let Some(v) = options.conversion_base {
1991            parameters.insert("conversion_base".to_string(), v.to_string());
1992        }
1993        if let Some(v) = options.page {
1994            parameters.insert("page".to_string(), v.to_string());
1995        }
1996        if let Some(v) = options.limit {
1997            parameters.insert("limit".to_string(), v.to_string());
1998        }
1999        if let Some(v) = options.sort {
2000            parameters.insert("sort".to_string(), v.to_string());
2001        }
2002        if let Some(v) = options.key {
2003            parameters.insert("key".to_string(), v.to_string());
2004        }
2005        if let Some(v) = options.query {
2006            parameters.insert("query".to_string(), v.to_string());
2007        }
2008        if let Some(v) = options.only_transferable {
2009            parameters.insert("only_transferable".to_string(), v.to_string());
2010        }
2011        if let Some(v) = options.network {
2012            parameters.insert("network".to_string(), v.to_string());
2013        }
2014        if let Some(v) = options.min_sv {
2015            parameters.insert("min_sv".to_string(), v.to_string());
2016        }
2017        if let Some(v) = options.min_tv {
2018            parameters.insert("min_tv".to_string(), v.to_string());
2019        }
2020        self.client.get("/premium", Some(parameters))
2021    }
2022
2023    /// Get supported source exchanges for premium data.
2024    pub fn exchanges(&self) -> Result<serde_json::Value> {
2025        self.client.get("/premium/exchanges", None)
2026    }
2027}
2028
2029pub struct PremiumOptions {
2030    pub source_exchange: Option<String>,
2031    pub target_exchange: Option<String>,
2032    pub asset: Option<String>,
2033    pub source_quote: Option<String>,
2034    pub target_quote: Option<String>,
2035    pub source_market: Option<String>,
2036    pub target_market: Option<String>,
2037    pub premium_type: Option<String>,
2038    pub currency: Option<String>,
2039    pub conversion_base: Option<String>,
2040    pub page: Option<i64>,
2041    pub limit: Option<i64>,
2042    pub sort: Option<String>,
2043    pub key: Option<String>,
2044    pub query: Option<String>,
2045    pub only_transferable: Option<bool>,
2046    pub network: Option<String>,
2047    pub min_sv: Option<f64>,
2048    pub min_tv: Option<f64>,
2049}
2050
2051impl PremiumOptions {
2052    pub fn new() -> Self {
2053        PremiumOptions {
2054            source_exchange: None,
2055            target_exchange: None,
2056            asset: None,
2057            source_quote: None,
2058            target_quote: None,
2059            source_market: None,
2060            target_market: None,
2061            premium_type: None,
2062            currency: None,
2063            conversion_base: None,
2064            page: None,
2065            limit: None,
2066            sort: None,
2067            key: None,
2068            query: None,
2069            only_transferable: None,
2070            network: None,
2071            min_sv: None,
2072            min_tv: None,
2073        }
2074    }
2075
2076    pub fn source_exchange(mut self, source_exchange: impl Into<String>) -> Self {
2077        self.source_exchange = Some(source_exchange.into());
2078        self
2079    }
2080
2081    pub fn target_exchange(mut self, target_exchange: impl Into<String>) -> Self {
2082        self.target_exchange = Some(target_exchange.into());
2083        self
2084    }
2085
2086    pub fn asset(mut self, asset: impl Into<String>) -> Self {
2087        self.asset = Some(asset.into());
2088        self
2089    }
2090
2091    pub fn source_quote(mut self, source_quote: impl Into<String>) -> Self {
2092        self.source_quote = Some(source_quote.into());
2093        self
2094    }
2095
2096    pub fn target_quote(mut self, target_quote: impl Into<String>) -> Self {
2097        self.target_quote = Some(target_quote.into());
2098        self
2099    }
2100
2101    pub fn source_market(mut self, source_market: impl Into<String>) -> Self {
2102        self.source_market = Some(source_market.into());
2103        self
2104    }
2105
2106    pub fn target_market(mut self, target_market: impl Into<String>) -> Self {
2107        self.target_market = Some(target_market.into());
2108        self
2109    }
2110
2111    pub fn premium_type(mut self, premium_type: impl Into<String>) -> Self {
2112        self.premium_type = Some(premium_type.into());
2113        self
2114    }
2115
2116    pub fn currency(mut self, currency: impl Into<String>) -> Self {
2117        self.currency = Some(currency.into());
2118        self
2119    }
2120
2121    pub fn conversion_base(mut self, conversion_base: impl Into<String>) -> Self {
2122        self.conversion_base = Some(conversion_base.into());
2123        self
2124    }
2125
2126    pub fn page(mut self, page: i64) -> Self {
2127        self.page = Some(page);
2128        self
2129    }
2130
2131    pub fn limit(mut self, limit: i64) -> Self {
2132        self.limit = Some(limit);
2133        self
2134    }
2135
2136    pub fn sort(mut self, sort: impl Into<String>) -> Self {
2137        self.sort = Some(sort.into());
2138        self
2139    }
2140
2141    pub fn key(mut self, key: impl Into<String>) -> Self {
2142        self.key = Some(key.into());
2143        self
2144    }
2145
2146    pub fn query(mut self, query: impl Into<String>) -> Self {
2147        self.query = Some(query.into());
2148        self
2149    }
2150
2151    pub fn only_transferable(mut self, only_transferable: bool) -> Self {
2152        self.only_transferable = Some(only_transferable);
2153        self
2154    }
2155
2156    pub fn network(mut self, network: impl Into<String>) -> Self {
2157        self.network = Some(network.into());
2158        self
2159    }
2160
2161    pub fn min_sv(mut self, min_sv: f64) -> Self {
2162        self.min_sv = Some(min_sv);
2163        self
2164    }
2165
2166    pub fn min_tv(mut self, min_tv: f64) -> Self {
2167        self.min_tv = Some(min_tv);
2168        self
2169    }
2170}
2171
2172// --- Telegram ---
2173
2174#[derive(Clone)]
2175pub struct Telegram {
2176    pub client: Client,
2177}
2178
2179impl Datamaxi for Telegram {
2180    fn new(api_key: String) -> Telegram {
2181        let config = Config {
2182            base_url: None,
2183            api_key,
2184        };
2185        Telegram {
2186            client: Client::new(config),
2187        }
2188    }
2189    fn new_with_base_url(api_key: String, base_url: String) -> Telegram {
2190        let config = Config {
2191            base_url: Some(base_url),
2192            api_key,
2193        };
2194        Telegram {
2195            client: Client::new(config),
2196        }
2197    }
2198}
2199
2200impl Telegram {
2201    /// Get Telegram channels
2202    pub fn channels(&self, options: TelegramChannelsOptions) -> Result<serde_json::Value> {
2203        let mut parameters = HashMap::new();
2204        if let Some(v) = options.page {
2205            parameters.insert("page".to_string(), v.to_string());
2206        }
2207        if let Some(v) = options.limit {
2208            parameters.insert("limit".to_string(), v.to_string());
2209        }
2210        if let Some(v) = options.category {
2211            parameters.insert("category".to_string(), v.to_string());
2212        }
2213        if let Some(v) = options.key {
2214            parameters.insert("key".to_string(), v.to_string());
2215        }
2216        if let Some(v) = options.sort {
2217            parameters.insert("sort".to_string(), v.to_string());
2218        }
2219        self.client.get("/telegram/channels", Some(parameters))
2220    }
2221
2222    /// Get Telegram messages.
2223    pub fn messages(&self, options: TelegramMessagesOptions) -> Result<serde_json::Value> {
2224        let mut parameters = HashMap::new();
2225        if let Some(v) = options.channel {
2226            parameters.insert("channel".to_string(), v.to_string());
2227        }
2228        if let Some(v) = options.page {
2229            parameters.insert("page".to_string(), v.to_string());
2230        }
2231        if let Some(v) = options.limit {
2232            parameters.insert("limit".to_string(), v.to_string());
2233        }
2234        if let Some(v) = options.key {
2235            parameters.insert("key".to_string(), v.to_string());
2236        }
2237        if let Some(v) = options.sort {
2238            parameters.insert("sort".to_string(), v.to_string());
2239        }
2240        if let Some(v) = options.category {
2241            parameters.insert("category".to_string(), v.to_string());
2242        }
2243        if let Some(v) = options.search_query {
2244            parameters.insert("search_query".to_string(), v.to_string());
2245        }
2246        self.client.get("/telegram/messages", Some(parameters))
2247    }
2248}
2249
2250pub struct TelegramChannelsOptions {
2251    pub page: Option<i64>,
2252    pub limit: Option<i64>,
2253    pub category: Option<String>,
2254    pub key: Option<String>,
2255    pub sort: Option<String>,
2256}
2257
2258impl TelegramChannelsOptions {
2259    pub fn new() -> Self {
2260        TelegramChannelsOptions {
2261            page: None,
2262            limit: None,
2263            category: None,
2264            key: None,
2265            sort: None,
2266        }
2267    }
2268
2269    pub fn page(mut self, page: i64) -> Self {
2270        self.page = Some(page);
2271        self
2272    }
2273
2274    pub fn limit(mut self, limit: i64) -> Self {
2275        self.limit = Some(limit);
2276        self
2277    }
2278
2279    pub fn category(mut self, category: impl Into<String>) -> Self {
2280        self.category = Some(category.into());
2281        self
2282    }
2283
2284    pub fn key(mut self, key: impl Into<String>) -> Self {
2285        self.key = Some(key.into());
2286        self
2287    }
2288
2289    pub fn sort(mut self, sort: impl Into<String>) -> Self {
2290        self.sort = Some(sort.into());
2291        self
2292    }
2293}
2294
2295pub struct TelegramMessagesOptions {
2296    pub channel: Option<String>,
2297    pub page: Option<i64>,
2298    pub limit: Option<i64>,
2299    pub key: Option<String>,
2300    pub sort: Option<String>,
2301    pub category: Option<String>,
2302    pub search_query: Option<String>,
2303}
2304
2305impl TelegramMessagesOptions {
2306    pub fn new() -> Self {
2307        TelegramMessagesOptions {
2308            channel: None,
2309            page: None,
2310            limit: None,
2311            key: None,
2312            sort: None,
2313            category: None,
2314            search_query: None,
2315        }
2316    }
2317
2318    pub fn channel(mut self, channel: impl Into<String>) -> Self {
2319        self.channel = Some(channel.into());
2320        self
2321    }
2322
2323    pub fn page(mut self, page: i64) -> Self {
2324        self.page = Some(page);
2325        self
2326    }
2327
2328    pub fn limit(mut self, limit: i64) -> Self {
2329        self.limit = Some(limit);
2330        self
2331    }
2332
2333    pub fn key(mut self, key: impl Into<String>) -> Self {
2334        self.key = Some(key.into());
2335        self
2336    }
2337
2338    pub fn sort(mut self, sort: impl Into<String>) -> Self {
2339        self.sort = Some(sort.into());
2340        self
2341    }
2342
2343    pub fn category(mut self, category: impl Into<String>) -> Self {
2344        self.category = Some(category.into());
2345        self
2346    }
2347
2348    pub fn search_query(mut self, search_query: impl Into<String>) -> Self {
2349        self.search_query = Some(search_query.into());
2350        self
2351    }
2352}
2353
2354// --- Ticker ---
2355
2356#[derive(Clone)]
2357pub struct Ticker {
2358    pub client: Client,
2359}
2360
2361impl Datamaxi for Ticker {
2362    fn new(api_key: String) -> Ticker {
2363        let config = Config {
2364            base_url: None,
2365            api_key,
2366        };
2367        Ticker {
2368            client: Client::new(config),
2369        }
2370    }
2371    fn new_with_base_url(api_key: String, base_url: String) -> Ticker {
2372        let config = Config {
2373            base_url: Some(base_url),
2374            api_key,
2375        };
2376        Ticker {
2377            client: Client::new(config),
2378        }
2379    }
2380}
2381
2382impl Ticker {
2383    /// Fetch the latest ticker for symbol from given exchange.
2384    pub fn get(
2385        &self,
2386        exchange: impl Into<String>,
2387        symbol: impl Into<String>,
2388        options: TickerOptions,
2389    ) -> Result<serde_json::Value> {
2390        let mut parameters = HashMap::new();
2391        parameters.insert("exchange".to_string(), exchange.into());
2392        parameters.insert("symbol".to_string(), symbol.into());
2393        if let Some(v) = options.market {
2394            parameters.insert("market".to_string(), v.to_string());
2395        }
2396        if let Some(v) = options.currency {
2397            parameters.insert("currency".to_string(), v.to_string());
2398        }
2399        if let Some(v) = options.conversion_base {
2400            parameters.insert("conversion_base".to_string(), v.to_string());
2401        }
2402        self.client.get("/ticker", Some(parameters))
2403    }
2404
2405    /// Get supported exchanges accepted by `/api/v1/ticker` endpoint.
2406    pub fn exchanges(&self, options: TickerExchangesOptions) -> Result<serde_json::Value> {
2407        let mut parameters = HashMap::new();
2408        if let Some(v) = options.market {
2409            parameters.insert("market".to_string(), v.to_string());
2410        }
2411        self.client.get("/ticker/exchanges", Some(parameters))
2412    }
2413
2414    /// Get supported symbols accepted by `/api/v1/ticker` endpoint.
2415    pub fn symbols(
2416        &self,
2417        exchange: impl Into<String>,
2418        options: TickerSymbolsOptions,
2419    ) -> Result<serde_json::Value> {
2420        let mut parameters = HashMap::new();
2421        parameters.insert("exchange".to_string(), exchange.into());
2422        if let Some(v) = options.market {
2423            parameters.insert("market".to_string(), v.to_string());
2424        }
2425        self.client.get("/ticker/symbols", Some(parameters))
2426    }
2427}
2428
2429pub struct TickerOptions {
2430    pub market: Option<String>,
2431    pub currency: Option<String>,
2432    pub conversion_base: Option<String>,
2433}
2434
2435impl TickerOptions {
2436    pub fn new() -> Self {
2437        TickerOptions {
2438            market: None,
2439            currency: None,
2440            conversion_base: None,
2441        }
2442    }
2443
2444    pub fn market(mut self, market: impl Into<String>) -> Self {
2445        self.market = Some(market.into());
2446        self
2447    }
2448
2449    pub fn currency(mut self, currency: impl Into<String>) -> Self {
2450        self.currency = Some(currency.into());
2451        self
2452    }
2453
2454    pub fn conversion_base(mut self, conversion_base: impl Into<String>) -> Self {
2455        self.conversion_base = Some(conversion_base.into());
2456        self
2457    }
2458}
2459
2460pub struct TickerExchangesOptions {
2461    pub market: Option<String>,
2462}
2463
2464impl TickerExchangesOptions {
2465    pub fn new() -> Self {
2466        TickerExchangesOptions { market: None }
2467    }
2468
2469    pub fn market(mut self, market: impl Into<String>) -> Self {
2470        self.market = Some(market.into());
2471        self
2472    }
2473}
2474
2475pub struct TickerSymbolsOptions {
2476    pub market: Option<String>,
2477}
2478
2479impl TickerSymbolsOptions {
2480    pub fn new() -> Self {
2481        TickerSymbolsOptions { market: None }
2482    }
2483
2484    pub fn market(mut self, market: impl Into<String>) -> Self {
2485        self.market = Some(market.into());
2486        self
2487    }
2488}
2489
2490// --- Token ---
2491
2492#[derive(Clone)]
2493pub struct Token {
2494    pub client: Client,
2495}
2496
2497impl Datamaxi for Token {
2498    fn new(api_key: String) -> Token {
2499        let config = Config {
2500            base_url: None,
2501            api_key,
2502        };
2503        Token {
2504            client: Client::new(config),
2505        }
2506    }
2507    fn new_with_base_url(api_key: String, base_url: String) -> Token {
2508        let config = Config {
2509            base_url: Some(base_url),
2510            api_key,
2511        };
2512        Token {
2513            client: Client::new(config),
2514        }
2515    }
2516}
2517
2518impl Token {
2519    /// Fetch latest token updates
2520    pub fn updates(&self, options: CexTokenUpdatesOptions) -> Result<serde_json::Value> {
2521        let mut parameters = HashMap::new();
2522        if let Some(v) = options.page {
2523            parameters.insert("page".to_string(), v.to_string());
2524        }
2525        if let Some(v) = options.limit {
2526            parameters.insert("limit".to_string(), v.to_string());
2527        }
2528        if let Some(v) = options.r#type {
2529            parameters.insert("type".to_string(), v.to_string());
2530        }
2531        self.client.get("/cex/token/updates", Some(parameters))
2532    }
2533}
2534
2535pub struct CexTokenUpdatesOptions {
2536    pub page: Option<String>,
2537    pub limit: Option<String>,
2538    pub r#type: Option<String>,
2539}
2540
2541impl CexTokenUpdatesOptions {
2542    pub fn new() -> Self {
2543        CexTokenUpdatesOptions {
2544            page: None,
2545            limit: None,
2546            r#type: None,
2547        }
2548    }
2549
2550    pub fn page(mut self, page: impl Into<String>) -> Self {
2551        self.page = Some(page.into());
2552        self
2553    }
2554
2555    pub fn limit(mut self, limit: impl Into<String>) -> Self {
2556        self.limit = Some(limit.into());
2557        self
2558    }
2559
2560    pub fn r#type(mut self, r#type: impl Into<String>) -> Self {
2561        self.r#type = Some(r#type.into());
2562        self
2563    }
2564}
2565
2566// --- TradingFees ---
2567
2568#[derive(Clone)]
2569pub struct TradingFees {
2570    pub client: Client,
2571}
2572
2573impl Datamaxi for TradingFees {
2574    fn new(api_key: String) -> TradingFees {
2575        let config = Config {
2576            base_url: None,
2577            api_key,
2578        };
2579        TradingFees {
2580            client: Client::new(config),
2581        }
2582    }
2583    fn new_with_base_url(api_key: String, base_url: String) -> TradingFees {
2584        let config = Config {
2585            base_url: Some(base_url),
2586            api_key,
2587        };
2588        TradingFees {
2589            client: Client::new(config),
2590        }
2591    }
2592}
2593
2594impl TradingFees {
2595    /// Get trading fees.
2596    pub fn fees(&self, options: CexFeesOptions) -> Result<serde_json::Value> {
2597        let mut parameters = HashMap::new();
2598        if let Some(v) = options.exchange {
2599            parameters.insert("exchange".to_string(), v.to_string());
2600        }
2601        if let Some(v) = options.symbol {
2602            parameters.insert("symbol".to_string(), v.to_string());
2603        }
2604        self.client.get("/cex/fees", Some(parameters))
2605    }
2606
2607    /// Get supported exchanges accepted by `/api/v1/trading-fees` endpoint.
2608    pub fn exchanges(&self) -> Result<serde_json::Value> {
2609        self.client.get("/cex/fees/exchanges", None)
2610    }
2611
2612    /// Get supported symbols accepted by `/api/v1/trading-fees` endpoint.
2613    pub fn symbols(&self, exchange: impl Into<String>) -> Result<serde_json::Value> {
2614        let mut parameters = HashMap::new();
2615        parameters.insert("exchange".to_string(), exchange.into());
2616        self.client.get("/cex/fees/symbols", Some(parameters))
2617    }
2618}
2619
2620pub struct CexFeesOptions {
2621    pub exchange: Option<String>,
2622    pub symbol: Option<String>,
2623}
2624
2625impl CexFeesOptions {
2626    pub fn new() -> Self {
2627        CexFeesOptions {
2628            exchange: None,
2629            symbol: None,
2630        }
2631    }
2632
2633    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
2634        self.exchange = Some(exchange.into());
2635        self
2636    }
2637
2638    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
2639        self.symbol = Some(symbol.into());
2640        self
2641    }
2642}
2643
2644// --- WalletStatus ---
2645
2646#[derive(Clone)]
2647pub struct WalletStatus {
2648    pub client: Client,
2649}
2650
2651impl Datamaxi for WalletStatus {
2652    fn new(api_key: String) -> WalletStatus {
2653        let config = Config {
2654            base_url: None,
2655            api_key,
2656        };
2657        WalletStatus {
2658            client: Client::new(config),
2659        }
2660    }
2661    fn new_with_base_url(api_key: String, base_url: String) -> WalletStatus {
2662        let config = Config {
2663            base_url: Some(base_url),
2664            api_key,
2665        };
2666        WalletStatus {
2667            client: Client::new(config),
2668        }
2669    }
2670}
2671
2672impl WalletStatus {
2673    /// Get the latest wallet status for asset from given exchange.
2674    pub fn get(
2675        &self,
2676        asset: impl Into<String>,
2677        options: WalletStatusOptions,
2678    ) -> Result<serde_json::Value> {
2679        let mut parameters = HashMap::new();
2680        parameters.insert("asset".to_string(), asset.into());
2681        if let Some(v) = options.exchange {
2682            parameters.insert("exchange".to_string(), v.to_string());
2683        }
2684        self.client.get("/wallet-status", Some(parameters))
2685    }
2686
2687    /// Get assets accepted by `/api/v1/wallet-status` endpoint.
2688    pub fn assets(&self, exchange: impl Into<String>) -> Result<serde_json::Value> {
2689        let mut parameters = HashMap::new();
2690        parameters.insert("exchange".to_string(), exchange.into());
2691        self.client.get("/wallet-status/assets", Some(parameters))
2692    }
2693
2694    /// Get exchanges accepted by `/api/v1/wallet-status` endpoint.
2695    pub fn exchanges(&self) -> Result<serde_json::Value> {
2696        self.client.get("/wallet-status/exchanges", None)
2697    }
2698}
2699
2700pub struct WalletStatusOptions {
2701    pub exchange: Option<String>,
2702}
2703
2704impl WalletStatusOptions {
2705    pub fn new() -> Self {
2706        WalletStatusOptions { exchange: None }
2707    }
2708
2709    pub fn exchange(mut self, exchange: impl Into<String>) -> Self {
2710        self.exchange = Some(exchange.into());
2711        self
2712    }
2713}