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}