cefi_rs_bybit/rest/
market.rs

1use std::collections::HashMap;
2
3use crate::{errors::BybitResult, http::BybitHttp, types::GetTickersResponse};
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7#[serde(rename_all = "camelCase")]
8pub struct ServerTimeResponse {
9    pub time_second: String,
10    pub time_nano: String,
11}
12
13#[derive(Serialize, Deserialize, Debug, Clone)]
14#[serde(rename_all = "camelCase")]
15pub struct InstrumentsInfoResponse {
16    pub category: String,
17    pub list: Vec<InstrumentInfo>,
18    pub next_page_cursor: String,
19}
20
21#[derive(Serialize, Deserialize, Debug, Clone)]
22#[serde(rename_all = "camelCase")]
23pub struct InstrumentInfo {
24    pub symbol: String,
25    pub contract_type: String,
26    pub status: String,
27    pub base_coin: String,
28    pub quote_coin: String,
29    pub launch_time: String,
30    pub delivery_time: String,
31    pub delivery_fee_rate: String,
32    pub price_scale: String,
33    pub leverage_filter: LeverageFilter,
34    pub price_filter: PriceFilter,
35    pub lot_size_filter: LotSizeFilter,
36    pub unified_margin_trade: bool,
37    pub funding_interval: i32,
38    pub settle_coin: String,
39    pub copy_trading: String,
40    pub upper_funding_rate: String,
41    pub lower_funding_rate: String,
42    pub is_pre_listing: bool,
43    pub pre_listing_info: Option<serde_json::Value>,
44    pub risk_parameters: RiskParameters,
45}
46
47#[derive(Serialize, Deserialize, Debug, Clone)]
48#[serde(rename_all = "camelCase")]
49pub struct LeverageFilter {
50    pub min_leverage: String,
51    pub max_leverage: String,
52    pub leverage_step: String,
53}
54
55#[derive(Serialize, Deserialize, Debug, Clone)]
56#[serde(rename_all = "camelCase")]
57pub struct PriceFilter {
58    pub min_price: String,
59    pub max_price: String,
60    pub tick_size: String,
61}
62
63#[derive(Serialize, Deserialize, Debug, Clone)]
64#[serde(rename_all = "camelCase")]
65pub struct LotSizeFilter {
66    pub max_order_qty: String,
67    pub min_order_qty: String,
68    pub qty_step: String,
69    pub post_only_max_order_qty: String,
70    pub max_mkt_order_qty: String,
71    pub min_notional_value: String,
72}
73
74#[derive(Serialize, Deserialize, Debug, Clone)]
75#[serde(rename_all = "camelCase")]
76pub struct RiskParameters {
77    pub price_limit_ratio_x: String,
78    pub price_limit_ratio_y: String,
79}
80
81#[derive(Serialize, Deserialize, Debug, Clone)]
82pub struct OrderbookResponse {
83    #[serde(rename = "s")]
84    pub symbol: String,
85    #[serde(rename = "a")]
86    pub asks: Vec<[String; 2]>,
87    #[serde(rename = "b")]
88    pub bids: Vec<[String; 2]>,
89    #[serde(rename = "ts")]
90    pub timestamp: i64,
91    #[serde(rename = "u")]
92    pub update_id: i64,
93    pub seq: i64,
94    #[serde(rename = "cts")]
95    pub cross_seq: i64,
96}
97
98impl BybitHttp {
99    pub async fn get_server_time(&self) -> BybitResult<ServerTimeResponse> {
100        self.send_get_request::<ServerTimeResponse>("v5/market/time", HashMap::new(), false)
101            .await
102    }
103
104    pub async fn get_instruments_info(
105        &self,
106        category: String,
107    ) -> BybitResult<InstrumentsInfoResponse> {
108        self.send_get_request::<InstrumentsInfoResponse>(
109            "v5/market/instruments-info",
110            HashMap::from([("category", category.as_str())]),
111            false,
112        )
113        .await
114    }
115
116    pub async fn get_orderbook(
117        &self,
118        category: String,
119        symbol: String,
120        limit: i32,
121    ) -> BybitResult<OrderbookResponse> {
122        self.send_get_request::<OrderbookResponse>(
123            "v5/market/orderbook",
124            HashMap::from([
125                ("category", category.as_str()),
126                ("symbol", symbol.as_str()),
127                ("limit", limit.to_string().as_str()),
128            ]),
129            false,
130        )
131        .await
132    }
133
134    pub async fn get_tickers(&self) -> BybitResult<GetTickersResponse> {
135        self.send_get_request::<GetTickersResponse>(
136            "v5/market/tickers",
137            HashMap::from([("category", "linear")]),
138            false,
139        )
140        .await
141    }
142}
143
144#[cfg(test)]
145mod tests {
146    use super::*;
147
148    #[tokio::test]
149    async fn test_get_server_time() {
150        let client = BybitHttp::new("".to_string(), "".to_string());
151        let res = client.get_server_time().await;
152        println!("{:?}", res);
153    }
154
155    #[tokio::test]
156    async fn test_get_instruments_info() {
157        let client = BybitHttp::new("".to_string(), "".to_string());
158        let res = client.get_instruments_info("linear".to_string()).await;
159        println!("{:?}", res);
160    }
161
162    #[tokio::test]
163    async fn test_get_orderbook() {
164        let client = BybitHttp::new("".to_string(), "".to_string());
165        let res = client
166            .get_orderbook("linear".to_string(), "BTCUSDT".to_string(), 5)
167            .await;
168        println!("{:?}", res);
169    }
170
171    #[tokio::test]
172    async fn test_get_tickers() {
173        let client = BybitHttp::new("".to_string(), "".to_string());
174        let res = client.get_tickers().await;
175        println!("{:?}", res);
176    }
177}