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