nautilus_bybit/common/models.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Shared data transfer objects used across Bybit HTTP and WebSocket payloads.
17
18use serde::{Deserialize, Serialize};
19
20use crate::common::enums::BybitProductType;
21
22/// Generic wrapper that contains a list payload returned by Bybit.
23#[derive(Clone, Debug, Default, Serialize, Deserialize)]
24#[serde(rename_all = "camelCase")]
25pub struct BybitList<T> {
26 /// Collection returned by the endpoint.
27 pub list: Vec<T>,
28}
29
30/// Generic list result that also carries pagination cursor information.
31#[derive(Clone, Debug, Default, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct BybitCursorList<T> {
34 /// Collection returned by the endpoint.
35 pub list: Vec<T>,
36 /// Pagination cursor for the next page, when provided.
37 pub next_page_cursor: Option<String>,
38 /// Optional product category when the API includes it.
39 #[serde(default)]
40 pub category: Option<BybitProductType>,
41}
42
43/// Common leverage filter that describes leverage bounds and step.
44#[derive(Clone, Debug, Serialize, Deserialize)]
45#[serde(rename_all = "camelCase")]
46pub struct LeverageFilter {
47 /// Minimum leverage supported.
48 pub min_leverage: String,
49 /// Maximum leverage supported.
50 pub max_leverage: String,
51 /// Step between successive leverage values.
52 pub leverage_step: String,
53}
54
55/// Price filter for linear/inverse contracts describing min/max and tick.
56#[derive(Clone, Debug, Serialize, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct LinearPriceFilter {
59 /// Minimum allowed order price.
60 pub min_price: String,
61 /// Maximum allowed order price.
62 pub max_price: String,
63 /// Tick size for price increments.
64 pub tick_size: String,
65}
66
67/// Price filter for spot instruments (only tick size is provided).
68#[derive(Clone, Debug, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct SpotPriceFilter {
71 /// Tick size for price increments.
72 pub tick_size: String,
73}
74
75/// Lot size filter for spot instruments.
76#[derive(Clone, Debug, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct SpotLotSizeFilter {
79 /// Base asset precision.
80 pub base_precision: String,
81 /// Quote asset precision.
82 pub quote_precision: String,
83 /// Minimum order quantity.
84 pub min_order_qty: String,
85 /// Maximum order quantity.
86 pub max_order_qty: String,
87 /// Minimum order notional.
88 pub min_order_amt: String,
89 /// Maximum order notional.
90 pub max_order_amt: String,
91}
92
93/// Lot size filter for derivatives instruments.
94#[derive(Clone, Debug, Serialize, Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct LinearLotSizeFilter {
97 /// Maximum order quantity.
98 pub max_order_qty: String,
99 /// Minimum order quantity.
100 pub min_order_qty: String,
101 /// Quantity increment step.
102 pub qty_step: String,
103 /// Maximum order quantity for post-only orders.
104 #[serde(default)]
105 pub post_only_max_order_qty: Option<String>,
106 /// Maximum order quantity for market orders.
107 #[serde(default)]
108 pub max_mkt_order_qty: Option<String>,
109 /// Minimum notional value.
110 #[serde(default)]
111 pub min_notional_value: Option<String>,
112}
113
114/// Lot size filter for option instruments.
115#[derive(Clone, Debug, Serialize, Deserialize)]
116#[serde(rename_all = "camelCase")]
117pub struct OptionLotSizeFilter {
118 /// Maximum order quantity.
119 pub max_order_qty: String,
120 /// Minimum order quantity.
121 pub min_order_qty: String,
122 /// Quantity increment step.
123 pub qty_step: String,
124}
125
126/// Trait for Bybit response types that contain ret_code and ret_msg fields.
127pub trait BybitResponseCheck {
128 /// Returns the response code (0 = success).
129 fn ret_code(&self) -> i64;
130 /// Returns the response message.
131 fn ret_msg(&self) -> &str;
132}
133
134/// Lightweight struct for checking Bybit API errors without deserializing result.
135///
136/// Bybit error responses often have `result: null` which would fail deserialization
137/// into typed response structs. This struct ignores the result field entirely.
138#[derive(Clone, Debug, Deserialize)]
139#[serde(rename_all = "camelCase")]
140pub struct BybitErrorCheck {
141 /// Return code (0 = success).
142 pub ret_code: i64,
143 /// Textual message accompanying the response.
144 pub ret_msg: String,
145}
146
147/// Top-level response envelope returned by Bybit HTTP endpoints.
148#[derive(Clone, Debug, Serialize, Deserialize)]
149#[serde(rename_all = "camelCase")]
150pub struct BybitResponse<T> {
151 /// Return code (0 = success).
152 pub ret_code: i64,
153 /// Textual message accompanying the response.
154 pub ret_msg: String,
155 /// Actual payload returned by the endpoint.
156 pub result: T,
157 /// Additional metadata returned by some endpoints.
158 #[serde(default)]
159 pub ret_ext_info: Option<serde_json::Value>,
160 /// Server time in milliseconds when the response was produced.
161 #[serde(default)]
162 pub time: Option<i64>,
163}
164
165impl<T> BybitResponseCheck for BybitResponse<T> {
166 fn ret_code(&self) -> i64 {
167 self.ret_code
168 }
169
170 fn ret_msg(&self) -> &str {
171 &self.ret_msg
172 }
173}
174
175/// Convenience alias for responses that return a simple list.
176pub type BybitListResponse<T> = BybitResponse<BybitList<T>>;
177
178/// Convenience alias for responses that return a cursor-based list.
179pub type BybitCursorListResponse<T> = BybitResponse<BybitCursorList<T>>;