Skip to main content

bybit/models/
orderbook_request.rs

1use crate::prelude::*;
2
3/// Parameters for requesting order book data.
4///
5/// This struct defines the parameters for querying the order book via the `/v5/market/orderbook` endpoint.
6/// The order book shows current bid and ask prices and quantities, critical for liquidity analysis
7/// and order placement in perpetual futures.
8#[derive(Clone, Default)]
9pub struct OrderbookRequest<'a> {
10    /// The trading pair symbol (e.g., "BTCUSDT").
11    ///
12    /// Identifies the perpetual futures contract. Bots must specify a valid symbol to fetch the correct order book.
13    pub symbol: Cow<'a, str>,
14
15    /// The product category (e.g., Linear, Inverse, Spot, Option).
16    ///
17    /// Specifies the instrument type. For perpetual futures, use `Linear` or `Inverse`.
18    /// Bots must set this correctly to avoid errors.
19    pub category: Category,
20
21    /// The maximum number of order book levels to return.
22    ///
23    /// Controls the depth of the order book (number of bid/ask levels). The valid range depends on the category:
24    /// - `spot`: [1, 200], default: 1
25    /// - `linear` & `inverse`: [1, 500], default: 25
26    /// - `option`: [1, 25], default: 1
27    ///
28    /// Bots should balance depth with performance: deeper books provide more liquidity data
29    /// but increase latency and memory usage.
30    pub limit: Option<u64>,
31}
32
33impl<'a> OrderbookRequest<'a> {
34    /// Creates a default Orderbook request.
35    ///
36    /// Returns a request with `symbol` set to `"BTCUSDT"` and `category` set to `Linear`.
37    /// Suitable for testing but should be customized for production.
38    pub fn default() -> OrderbookRequest<'a> {
39        OrderbookRequest::new("BTCUSDT", Category::Linear, None)
40    }
41
42    /// Constructs a new Orderbook request with specified parameters.
43    ///
44    /// Allows customization. Bots should use this to specify the exact symbol and category
45    /// for their perpetual futures strategy.
46    pub fn new(symbol: &'a str, category: Category, limit: Option<u64>) -> OrderbookRequest<'a> {
47        OrderbookRequest {
48            symbol: Cow::Borrowed(symbol),
49            category,
50            limit,
51        }
52    }
53
54    /// Validates the request parameters according to API constraints.
55    ///
56    /// Returns `Ok(())` if the request is valid, or `Err(String)` with an error message.
57    pub fn validate(&self) -> Result<(), String> {
58        // Validate limit range based on category
59        if let Some(limit) = self.limit {
60            let (min, max) = match self.category {
61                Category::Spot => (1, 200),
62                Category::Linear | Category::Inverse => (1, 500),
63                Category::Option => (1, 25),
64            };
65
66            if limit < min || limit > max {
67                return Err(format!(
68                    "Limit for category {} must be between {} and {} inclusive",
69                    self.category.as_str(),
70                    min,
71                    max
72                ));
73            }
74        }
75
76        Ok(())
77    }
78
79    /// Gets the default limit value for the category.
80    ///
81    /// Returns the default limit value based on the category:
82    /// - `spot`: 1
83    /// - `linear` & `inverse`: 25
84    /// - `option`: 1
85    pub fn default_limit(&self) -> u64 {
86        match self.category {
87            Category::Spot => 1,
88            Category::Linear | Category::Inverse => 25,
89            Category::Option => 1,
90        }
91    }
92
93    /// Gets the effective limit value (either the specified limit or the default).
94    ///
95    /// Returns the limit value to use for the API request.
96    pub fn effective_limit(&self) -> u64 {
97        self.limit.unwrap_or_else(|| self.default_limit())
98    }
99
100    /// Creates a request for spot trading pairs.
101    ///
102    /// Convenience method for creating requests for spot markets.
103    pub fn spot(symbol: &'a str, limit: Option<u64>) -> OrderbookRequest<'a> {
104        OrderbookRequest::new(symbol, Category::Spot, limit)
105    }
106
107    /// Creates a request for linear perpetual futures.
108    ///
109    /// Convenience method for creating requests for USDT-margined perpetual futures.
110    pub fn linear(symbol: &'a str, limit: Option<u64>) -> OrderbookRequest<'a> {
111        OrderbookRequest::new(symbol, Category::Linear, limit)
112    }
113
114    /// Creates a request for inverse perpetual futures.
115    ///
116    /// Convenience method for creating requests for coin-margined perpetual futures.
117    pub fn inverse(symbol: &'a str, limit: Option<u64>) -> OrderbookRequest<'a> {
118        OrderbookRequest::new(symbol, Category::Inverse, limit)
119    }
120
121    /// Creates a request for options contracts.
122    ///
123    /// Convenience method for creating requests for options markets.
124    pub fn option(symbol: &'a str, limit: Option<u64>) -> OrderbookRequest<'a> {
125        OrderbookRequest::new(symbol, Category::Option, limit)
126    }
127}