Skip to main content

nautilus_binance/common/
consts.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 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//! Binance venue constants and API endpoints.
17
18use std::{num::NonZeroU32, sync::LazyLock};
19
20use nautilus_model::identifiers::{ClientId, Venue};
21use nautilus_network::ratelimiter::quota::Quota;
22use ustr::Ustr;
23
24use super::enums::{BinanceRateLimitInterval, BinanceRateLimitType};
25
26/// The Binance venue identifier string.
27pub const BINANCE: &str = "BINANCE";
28
29/// Static venue instance for Binance.
30pub static BINANCE_VENUE: LazyLock<Venue> = LazyLock::new(|| Venue::new(Ustr::from(BINANCE)));
31
32/// Static client ID instance for Binance.
33pub static BINANCE_CLIENT_ID: LazyLock<ClientId> =
34    LazyLock::new(|| ClientId::new(Ustr::from(BINANCE)));
35
36/// Binance Link and Trade broker ID for Spot.
37///
38/// <https://developers.binance.com/docs/binance_link/link-and-trade>
39pub const BINANCE_NAUTILUS_SPOT_BROKER_ID: &str = "TD67BGP9";
40
41/// Binance Link and Trade broker ID for Futures.
42///
43/// <https://developers.binance.com/docs/binance_link/link-and-trade>
44pub const BINANCE_NAUTILUS_FUTURES_BROKER_ID: &str = "aHRE4BCj";
45
46/// Binance Spot API base URL (live exchange).
47pub const BINANCE_SPOT_HTTP_URL: &str = "https://api.binance.com";
48
49/// Binance USD-M Futures API base URL (live exchange).
50pub const BINANCE_FUTURES_USD_HTTP_URL: &str = "https://fapi.binance.com";
51
52/// Binance COIN-M Futures API base URL (live exchange).
53pub const BINANCE_FUTURES_COIN_HTTP_URL: &str = "https://dapi.binance.com";
54
55/// Binance European Options API base URL (live exchange).
56pub const BINANCE_OPTIONS_HTTP_URL: &str = "https://eapi.binance.com";
57
58/// Binance European Options API base URL (testnet/demo).
59pub const BINANCE_OPTIONS_TESTNET_HTTP_URL: &str = "https://testnet.binancefuture.com";
60
61/// Binance Spot API base URL (testnet).
62pub const BINANCE_SPOT_TESTNET_HTTP_URL: &str = "https://testnet.binance.vision";
63
64/// Binance USD-M Futures API base URL (testnet).
65pub const BINANCE_FUTURES_USD_TESTNET_HTTP_URL: &str = "https://demo-fapi.binance.com";
66
67/// Binance COIN-M Futures API base URL (testnet).
68pub const BINANCE_FUTURES_COIN_TESTNET_HTTP_URL: &str = "https://testnet.binancefuture.com";
69
70/// Binance Spot API base URL (demo).
71pub const BINANCE_SPOT_DEMO_HTTP_URL: &str = "https://demo-api.binance.com";
72
73/// Binance USD-M Futures API base URL (demo).
74pub const BINANCE_FUTURES_USD_DEMO_HTTP_URL: &str = "https://demo-fapi.binance.com";
75
76/// Binance COIN-M Futures API base URL (demo).
77pub const BINANCE_FUTURES_COIN_DEMO_HTTP_URL: &str = "https://demo-dapi.binance.com";
78
79/// Binance Spot WebSocket base URL (live exchange).
80pub const BINANCE_SPOT_WS_URL: &str = "wss://stream.binance.com:9443/ws";
81
82/// Binance USD-M Futures WebSocket base URL (live exchange).
83pub const BINANCE_FUTURES_USD_WS_URL: &str = "wss://fstream.binance.com/market/ws";
84
85/// Binance USD-M Futures WebSocket public stream URL (live exchange, high-frequency book data).
86pub const BINANCE_FUTURES_USD_WS_PUBLIC_URL: &str = "wss://fstream.binance.com/public/ws";
87
88/// Binance USD-M Futures WebSocket private stream URL (live exchange).
89pub const BINANCE_FUTURES_USD_WS_PRIVATE_URL: &str = "wss://fstream.binance.com/private/ws";
90
91/// Binance COIN-M Futures WebSocket base URL (live exchange).
92pub const BINANCE_FUTURES_COIN_WS_URL: &str = "wss://dstream.binance.com/ws";
93
94/// Binance European Options WebSocket base URL (live exchange).
95pub const BINANCE_OPTIONS_WS_URL: &str = "wss://nbstream.binance.com/eoptions";
96
97/// Binance European Options WebSocket base URL (testnet/demo).
98pub const BINANCE_OPTIONS_TESTNET_WS_URL: &str = "wss://fstream.binancefuture.com/market/ws";
99
100/// Binance European Options WebSocket public stream URL (testnet/demo).
101pub const BINANCE_OPTIONS_TESTNET_WS_PUBLIC_URL: &str = "wss://fstream.binancefuture.com/public/ws";
102
103/// Binance European Options WebSocket private stream URL (testnet/demo).
104pub const BINANCE_OPTIONS_TESTNET_WS_PRIVATE_URL: &str =
105    "wss://fstream.binancefuture.com/private/ws";
106
107/// Binance Spot SBE WebSocket stream URL (live exchange).
108pub const BINANCE_SPOT_SBE_WS_URL: &str = "wss://stream-sbe.binance.com/ws";
109
110/// Binance Spot SBE WebSocket API URL (live exchange).
111pub const BINANCE_SPOT_SBE_WS_API_URL: &str =
112    "wss://ws-api.binance.com:443/ws-api/v3?responseFormat=sbe&sbeSchemaId=3&sbeSchemaVersion=4";
113
114/// Binance USD-M Futures WebSocket Trading API URL (live exchange).
115pub const BINANCE_FUTURES_USD_WS_API_URL: &str = "wss://ws-fapi.binance.com/ws-fapi/v1";
116
117/// Binance USD-M Futures WebSocket Trading API URL (testnet).
118pub const BINANCE_FUTURES_USD_WS_API_TESTNET_URL: &str =
119    "wss://testnet.binancefuture.com/ws-fapi/v1";
120
121/// Binance Spot SBE WebSocket API URL (testnet).
122pub const BINANCE_SPOT_SBE_WS_API_TESTNET_URL: &str = "wss://ws-api.testnet.binance.vision/ws-api/v3?responseFormat=sbe&sbeSchemaId=3&sbeSchemaVersion=4";
123
124/// Binance Spot SBE WebSocket API URL (demo).
125pub const BINANCE_SPOT_SBE_WS_API_DEMO_URL: &str =
126    "wss://demo-ws-api.binance.com/ws-api/v3?responseFormat=sbe&sbeSchemaId=3&sbeSchemaVersion=4";
127
128/// Binance Spot WebSocket base URL (testnet).
129pub const BINANCE_SPOT_TESTNET_WS_URL: &str = "wss://stream.testnet.binance.vision/ws";
130
131/// Binance Spot WebSocket base URL (demo).
132pub const BINANCE_SPOT_DEMO_WS_URL: &str = "wss://demo-stream.binance.com/ws";
133
134/// Binance USD-M Futures WebSocket base URL (demo).
135pub const BINANCE_FUTURES_USD_DEMO_WS_URL: &str = "wss://demo-fstream.binance.com/ws";
136
137/// Binance COIN-M Futures WebSocket base URL (demo).
138pub const BINANCE_FUTURES_COIN_DEMO_WS_URL: &str = "wss://demo-dstream.binance.com/ws";
139
140/// Binance USD-M Futures WebSocket base URL (testnet).
141pub const BINANCE_FUTURES_USD_TESTNET_WS_URL: &str = "wss://fstream.binancefuture.com/ws";
142
143/// Binance COIN-M Futures WebSocket base URL (testnet).
144pub const BINANCE_FUTURES_COIN_TESTNET_WS_URL: &str = "wss://dstream.binancefuture.com/ws";
145
146/// HTTP header name for the Binance API key.
147pub const BINANCE_API_KEY_HEADER: &str = "X-MBX-APIKEY";
148
149/// Binance Spot API version path.
150pub const BINANCE_SPOT_API_PATH: &str = "/api/v3";
151
152/// Binance USD-M Futures API version path.
153pub const BINANCE_FAPI_PATH: &str = "/fapi/v1";
154
155/// Binance COIN-M Futures API version path.
156pub const BINANCE_DAPI_PATH: &str = "/dapi/v1";
157
158/// Binance European Options API version path.
159pub const BINANCE_EAPI_PATH: &str = "/eapi/v1";
160
161/// Describes a static rate limit quota for a product type.
162#[derive(Clone, Copy, Debug)]
163pub struct BinanceRateLimitQuota {
164    /// Rate limit type.
165    pub rate_limit_type: BinanceRateLimitType,
166    /// Time interval unit.
167    pub interval: BinanceRateLimitInterval,
168    /// Number of intervals.
169    pub interval_num: u32,
170    /// Maximum allowed requests for the interval.
171    pub limit: u32,
172}
173
174/// Spot & margin REST limits (default IP weights).
175///
176/// References:
177/// - <https://developers.binance.com/docs/binance-spot-api-docs/limits>
178pub const BINANCE_SPOT_RATE_LIMITS: &[BinanceRateLimitQuota] = &[
179    BinanceRateLimitQuota {
180        rate_limit_type: BinanceRateLimitType::RequestWeight,
181        interval: BinanceRateLimitInterval::Minute,
182        interval_num: 1,
183        limit: 1_200,
184    },
185    BinanceRateLimitQuota {
186        rate_limit_type: BinanceRateLimitType::Orders,
187        interval: BinanceRateLimitInterval::Second,
188        interval_num: 1,
189        limit: 10,
190    },
191    BinanceRateLimitQuota {
192        rate_limit_type: BinanceRateLimitType::Orders,
193        interval: BinanceRateLimitInterval::Day,
194        interval_num: 1,
195        limit: 100_000,
196    },
197];
198
199/// USD-M Futures REST limits (default IP weights).
200///
201/// References:
202/// - <https://developers.binance.com/docs/derivatives/usds-margined-futures/general-info#limits>
203pub const BINANCE_FAPI_RATE_LIMITS: &[BinanceRateLimitQuota] = &[
204    BinanceRateLimitQuota {
205        rate_limit_type: BinanceRateLimitType::RequestWeight,
206        interval: BinanceRateLimitInterval::Minute,
207        interval_num: 1,
208        limit: 2_400,
209    },
210    BinanceRateLimitQuota {
211        rate_limit_type: BinanceRateLimitType::Orders,
212        interval: BinanceRateLimitInterval::Second,
213        interval_num: 1,
214        limit: 50,
215    },
216    BinanceRateLimitQuota {
217        rate_limit_type: BinanceRateLimitType::Orders,
218        interval: BinanceRateLimitInterval::Minute,
219        interval_num: 1,
220        limit: 1_200,
221    },
222];
223
224/// COIN-M Futures REST limits (default IP weights).
225///
226/// References:
227/// - <https://developers.binance.com/docs/derivatives/coin-margined-futures/general-info#limits>
228pub const BINANCE_DAPI_RATE_LIMITS: &[BinanceRateLimitQuota] = &[
229    BinanceRateLimitQuota {
230        rate_limit_type: BinanceRateLimitType::RequestWeight,
231        interval: BinanceRateLimitInterval::Minute,
232        interval_num: 1,
233        limit: 1_200,
234    },
235    BinanceRateLimitQuota {
236        rate_limit_type: BinanceRateLimitType::Orders,
237        interval: BinanceRateLimitInterval::Second,
238        interval_num: 1,
239        limit: 20,
240    },
241    BinanceRateLimitQuota {
242        rate_limit_type: BinanceRateLimitType::Orders,
243        interval: BinanceRateLimitInterval::Minute,
244        interval_num: 1,
245        limit: 1_200,
246    },
247];
248
249/// Options REST limits (default IP weights).
250///
251/// References:
252/// - <https://developers.binance.com/docs/derivatives/european-options/general-info#limits>
253pub const BINANCE_EAPI_RATE_LIMITS: &[BinanceRateLimitQuota] = &[
254    BinanceRateLimitQuota {
255        rate_limit_type: BinanceRateLimitType::RequestWeight,
256        interval: BinanceRateLimitInterval::Minute,
257        interval_num: 1,
258        limit: 3_000,
259    },
260    BinanceRateLimitQuota {
261        rate_limit_type: BinanceRateLimitType::Orders,
262        interval: BinanceRateLimitInterval::Second,
263        interval_num: 1,
264        limit: 5,
265    },
266    BinanceRateLimitQuota {
267        rate_limit_type: BinanceRateLimitType::Orders,
268        interval: BinanceRateLimitInterval::Minute,
269        interval_num: 1,
270        limit: 200,
271    },
272];
273
274/// WebSocket subscription rate limit: 5 messages per second.
275///
276/// Binance limits incoming WebSocket messages (subscribe/unsubscribe) to 5 per second.
277pub static BINANCE_WS_SUBSCRIPTION_QUOTA: LazyLock<Quota> = LazyLock::new(|| {
278    Quota::per_second(NonZeroU32::new(5).expect("non-zero")).expect("valid constant")
279});
280
281/// WebSocket connection rate limit: 1 per second (conservative).
282///
283/// Binance limits connections to 300 per 5 minutes per IP. This conservative quota
284/// of 1 per second helps avoid hitting the connection limit during reconnection storms.
285pub static BINANCE_WS_CONNECTION_QUOTA: LazyLock<Quota> = LazyLock::new(|| {
286    Quota::per_second(NonZeroU32::new(1).expect("non-zero")).expect("valid constant")
287});
288
289/// Pre-interned rate limit key for WebSocket subscription operations.
290pub static BINANCE_RATE_LIMIT_KEY_SUBSCRIPTION: LazyLock<[Ustr; 1]> =
291    LazyLock::new(|| [Ustr::from("subscription")]);
292
293/// Binance error code for GTX (post-only) order rejection.
294///
295/// Returned when a GTX order would immediately match as taker.
296pub const BINANCE_GTX_ORDER_REJECT_CODE: i64 = -5022;
297
298/// Binance error code for new order rejected.
299///
300/// For spot LIMIT_MAKER orders, this code is returned with the message
301/// "Order would immediately match and take." to indicate a post-only rejection.
302pub const BINANCE_NEW_ORDER_REJECTED_CODE: i64 = -2010;
303
304/// Binance error code returned when an order is not found.
305pub const BINANCE_NO_SUCH_ORDER_CODE: i64 = -2013;
306
307/// Binance error code returned when order execution status is unknown.
308pub const BINANCE_UNEXPECTED_RESPONSE_CODE: i64 = -1006;
309
310/// Binance error code returned when order execution status is unknown.
311pub const BINANCE_STATUS_UNKNOWN_CODE: i64 = -1007;
312
313/// Binance USD-M Futures error code for `dualSidePosition` sync rejection between
314/// UM (USDM) and CM (Coin-M) accounts on Portfolio Margin.
315///
316/// Returned when an order or position-mode change is incompatible with the
317/// account-level hedge mode that PM keeps in sync across UM/CM.
318pub const BINANCE_FUTURES_DUAL_SIDE_SYNC_REJECT_CODE: i64 = -4531;
319
320/// Binance Spot LIMIT_MAKER rejection message.
321///
322/// This message is specific to post-only (LIMIT_MAKER) orders that would match immediately.
323pub const BINANCE_SPOT_POST_ONLY_REJECT_MSG: &str = "Order would immediately match and take.";
324
325/// Valid order book depth levels for Binance.
326pub const BINANCE_BOOK_DEPTHS: [u32; 7] = [5, 10, 20, 50, 100, 500, 1000];
327
328#[cfg(test)]
329mod tests {
330    use rstest::rstest;
331
332    use super::*;
333
334    #[rstest]
335    fn test_venue_error_code_values() {
336        assert_eq!(BINANCE_GTX_ORDER_REJECT_CODE, -5022);
337        assert_eq!(BINANCE_NEW_ORDER_REJECTED_CODE, -2010);
338        assert_eq!(BINANCE_NO_SUCH_ORDER_CODE, -2013);
339        assert_eq!(BINANCE_UNEXPECTED_RESPONSE_CODE, -1006);
340        assert_eq!(BINANCE_STATUS_UNKNOWN_CODE, -1007);
341        assert_eq!(BINANCE_FUTURES_DUAL_SIDE_SYNC_REJECT_CODE, -4531);
342    }
343}