crypto_rest_client/exchanges/
okx.rs

1use super::utils::http_get;
2use crate::error::Result;
3use crypto_market_type::MarketType;
4use serde_json::Value;
5use std::collections::{BTreeMap, HashMap};
6
7const BASE_URL: &str = "https://www.okx.com";
8
9/// The REST client for OKEx.
10///
11/// OKEx has Spot, Future, Swap and Option markets.
12///
13/// * API doc: <https://www.okx.com/docs-v5/en/>
14/// * Trading at:
15///     * Spot <https://www.okx.com/trade-spot>
16///     * Future <https://www.okx.com/trade-futures>
17///     * Swap <https://www.okx.com/trade-swap>
18///     * Option <https://www.okx.com/trade-option>
19pub struct OkxRestClient {
20    _api_key: Option<String>,
21    _api_secret: Option<String>,
22}
23
24impl OkxRestClient {
25    pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
26        OkxRestClient { _api_key: api_key, _api_secret: api_secret }
27    }
28
29    /// Get most recent trades.
30    ///
31    /// 500 trades are returned.
32    ///
33    /// For example: <https://www.okx.com/api/v5/market/trades?instId=BTC-USDT&limit=500>
34    pub fn fetch_trades(symbol: &str) -> Result<String> {
35        gen_api!(format!("/api/v5/market/trades?instId={symbol}&limit=500"))
36    }
37
38    /// Get the latest Level2 snapshot of orderbook.
39    ///
40    /// Top 400 bids and asks are returned.
41    ///
42    /// For example:
43    /// * <https://www.okx.com/api/v5/market/books?instId=BTC-USDT&sz=400>,
44    /// * <https://www.okx.com/api/v5/market/books?instId=BTC-USDT-SWAP&sz=400>
45    ///
46    /// Rate limit: 20 requests per 2 seconds
47    pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
48        gen_api!(format!("/api/v5/market/books?instId={symbol}&sz=400",))
49    }
50
51    /// Get option underlying.
52    pub fn fetch_option_underlying() -> Result<Vec<String>> {
53        let txt = http_get(
54            "https://www.okx.com/api/v5/public/underlying?instType=OPTION",
55            &BTreeMap::new(),
56        )?;
57        let json_obj = serde_json::from_str::<HashMap<String, Value>>(&txt).unwrap();
58        let data = json_obj.get("data").unwrap().as_array().unwrap()[0].as_array().unwrap();
59        let underlying_indexes =
60            data.iter().map(|x| x.as_str().unwrap().to_string()).collect::<Vec<String>>();
61        Ok(underlying_indexes)
62    }
63
64    /// Get open interest.
65    ///
66    /// inst_type: SWAP, FUTURES, OPTION
67    ///
68    /// For example:
69    /// - <https://www.okx.com/api/v5/public/open-interest?instType=SWAP>
70    /// - <https://www.okx.com/api/v5/public/open-interest?instType=SWAP&instId=BTC-USD-SWAP>
71    pub fn fetch_open_interest(market_type: MarketType, symbol: Option<&str>) -> Result<String> {
72        let inst_type = match market_type {
73            MarketType::LinearFuture => "FUTURES",
74            MarketType::InverseFuture => "FUTURES",
75            MarketType::LinearSwap => "SWAP",
76            MarketType::InverseSwap => "SWAP",
77            MarketType::EuropeanOption => "OPTION",
78            _ => panic!("okx {market_type} doesn't have open interest"),
79        };
80        if let Some(inst_id) = symbol {
81            gen_api!(format!("/api/v5/public/open-interest?instType={inst_type}&instId={inst_id}",))
82        } else {
83            gen_api!(format!("/api/v5/public/open-interest?instType={inst_type}"))
84        }
85    }
86}