nautilus_kraken/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//! Core constants shared across the Kraken adapter components.
17
18use std::{num::NonZeroU32, sync::LazyLock};
19
20use nautilus_model::identifiers::{ClientId, Venue};
21use nautilus_network::ratelimiter::quota::Quota;
22use ustr::Ustr;
23
24/// Venue identifier string.
25pub const KRAKEN: &str = "KRAKEN";
26
27/// Static venue instance.
28pub static KRAKEN_VENUE: LazyLock<Venue> = LazyLock::new(|| Venue::new(Ustr::from(KRAKEN)));
29
30/// Static client ID instance.
31pub static KRAKEN_CLIENT_ID: LazyLock<ClientId> =
32 LazyLock::new(|| ClientId::new(Ustr::from(KRAKEN)));
33
34// API Partner integration identifier
35pub const NAUTILUS_KRAKEN_BROKER_ID: &str = "AA98 N84G GOPN GL6Y";
36
37// WebSocket-specific constants
38pub const KRAKEN_PONG: &str = "pong";
39pub const KRAKEN_WS_TOPIC_DELIMITER: char = '.';
40
41// Spot API URLs (v2)
42pub const KRAKEN_SPOT_HTTP_URL: &str = "https://api.kraken.com";
43pub const KRAKEN_SPOT_WS_PUBLIC_URL: &str = "wss://ws.kraken.com/v2";
44pub const KRAKEN_SPOT_WS_PRIVATE_URL: &str = "wss://ws-auth.kraken.com/v2";
45pub const KRAKEN_SPOT_WS_L3_URL: &str = "wss://ws-l3.kraken.com/v2";
46
47// Futures API URLs
48pub const KRAKEN_FUTURES_HTTP_URL: &str = "https://futures.kraken.com";
49pub const KRAKEN_FUTURES_WS_URL: &str = "wss://futures.kraken.com/ws/v1";
50
51// Demo URLs
52pub const KRAKEN_FUTURES_DEMO_HTTP_URL: &str = "https://demo-futures.kraken.com";
53pub const KRAKEN_FUTURES_DEMO_WS_URL: &str = "wss://demo-futures.kraken.com/ws/v1";
54
55// Spot order flags (oflags parameter values)
56pub const KRAKEN_OFLAG_POST_ONLY: &str = "post";
57pub const KRAKEN_OFLAG_QUOTE_QUANTITY: &str = "viqc";
58
59/// Kraken Futures WebSocket request rate limit: 100 requests per 1 second.
60///
61/// Set to 90/sec (10% margin below the documented 100/sec hard cap).
62///
63/// <https://docs.kraken.com/api/docs/guides/futures-rate-limits/#websocket-limits>
64pub static KRAKEN_FUTURES_WS_SUBSCRIPTION_QUOTA: LazyLock<Quota> = LazyLock::new(|| {
65 Quota::per_second(NonZeroU32::new(90).expect("non-zero")).expect("valid constant")
66});
67
68/// Kraken Spot WebSocket request rate limit (conservative).
69///
70/// The Spot WS message rate limit is dynamic and varies depending on system load.
71/// No fixed number is documented — the server returns `{"Error": "Exceeded msg rate"}`
72/// when exceeded. This conservative quota should avoid hitting the limit under normal use.
73///
74/// <https://docs.kraken.com/api/docs/guides/spot-ratelimits>
75pub static KRAKEN_SPOT_WS_SUBSCRIPTION_QUOTA: LazyLock<Quota> = LazyLock::new(|| {
76 Quota::per_second(NonZeroU32::new(20).expect("non-zero"))
77 .expect("valid constant")
78 .allow_burst(NonZeroU32::new(10).expect("non-zero"))
79});
80
81/// Kraken Spot WebSocket order rate limit (conservative).
82///
83/// Shares the same dynamic connection-level message budget as subscriptions.
84/// The matching engine enforces additional per-pair rate limits with decay
85/// (thresholds: 60 Starter / 125 Intermediate / 180 Pro).
86///
87/// <https://docs.kraken.com/api/docs/guides/spot-ratelimits>
88pub static KRAKEN_SPOT_WS_ORDER_QUOTA: LazyLock<Quota> = LazyLock::new(|| {
89 Quota::per_second(NonZeroU32::new(10).expect("non-zero"))
90 .expect("valid constant")
91 .allow_burst(NonZeroU32::new(10).expect("non-zero"))
92});
93
94/// Pre-interned rate limit key for WebSocket subscription operations.
95pub static KRAKEN_RATE_LIMIT_KEY_SUBSCRIPTION: LazyLock<[Ustr; 1]> =
96 LazyLock::new(|| [Ustr::from("subscription")]);
97
98/// Pre-interned rate limit key for WebSocket order operations.
99pub static KRAKEN_RATE_LIMIT_KEY_ORDER: LazyLock<[Ustr; 1]> =
100 LazyLock::new(|| [Ustr::from("order")]);
101
102// Post-only rejection reason strings
103pub const KRAKEN_FUTURES_POST_ONLY_REJECT: &str = "post_order_failed_because_it_would_filled";
104pub const KRAKEN_SPOT_POST_ONLY_REJECT: &str = "Post only order";
105pub const KRAKEN_SPOT_POST_ONLY_ERROR: &str = "EOrder:Post only order";