nautilus_binance/spot/websocket/trading/messages.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 Spot WebSocket API message types.
17//!
18//! This module defines:
19//! - [`BinanceSpotWsTradingCommand`]: Commands sent from the client to the handler.
20//! - [`BinanceSpotWsTradingMessage`]: Output messages emitted by the handler to the client.
21//! - Request/response structures for the Binance Spot WebSocket Trading API.
22
23use nautilus_network::websocket::WebSocketClient;
24use serde::{Deserialize, Serialize};
25
26use super::user_data::{
27 BinanceSpotAccountPositionMsg, BinanceSpotBalanceUpdateMsg, BinanceSpotExecutionReport,
28};
29use crate::spot::http::{
30 models::{BinanceCancelOrderResponse, BinanceNewOrderResponse},
31 query::{CancelOrderParams, CancelReplaceOrderParams, NewOrderParams},
32};
33
34/// Commands sent from the outer client to the inner handler.
35///
36/// The handler runs in a dedicated Tokio task and processes these commands
37/// to perform WebSocket API operations (request/response pattern).
38#[allow(
39 missing_debug_implementations,
40 clippy::large_enum_variant,
41 reason = "Commands are ephemeral and immediately consumed"
42)]
43pub enum BinanceSpotWsTradingCommand {
44 /// Sets the WebSocket client after connection.
45 SetClient(WebSocketClient),
46 /// Disconnects and cleans up.
47 Disconnect,
48 /// Places a new order.
49 PlaceOrder {
50 /// Request ID for correlation.
51 id: String,
52 /// Order parameters.
53 params: NewOrderParams,
54 },
55 /// Cancels an order.
56 CancelOrder {
57 /// Request ID for correlation.
58 id: String,
59 /// Cancel parameters.
60 params: CancelOrderParams,
61 },
62 /// Cancels and replaces an order atomically.
63 CancelReplaceOrder {
64 /// Request ID for correlation.
65 id: String,
66 /// Cancel-replace parameters.
67 params: CancelReplaceOrderParams,
68 },
69 /// Cancels all open orders for a symbol.
70 CancelAllOrders {
71 /// Request ID for correlation.
72 id: String,
73 /// Symbol to cancel all orders for.
74 symbol: String,
75 },
76 /// Authenticates the WebSocket session via `session.logon`.
77 SessionLogon,
78 /// Subscribes to the user data stream via `userDataStream.subscribe`.
79 SubscribeUserData,
80}
81
82/// Normalized output message from the WebSocket API handler.
83///
84/// These messages are emitted by the handler and consumed by the client
85/// for routing to callers or the execution engine.
86#[derive(Debug, Clone)]
87pub enum BinanceSpotWsTradingMessage {
88 /// Connection established.
89 Connected,
90 /// Session authenticated successfully.
91 Authenticated,
92 /// Session authentication was rejected or could not be sent.
93 AuthenticationRejected(String),
94 /// Connection was re-established after disconnect.
95 Reconnected,
96 /// Order accepted by venue.
97 OrderAccepted {
98 /// Request ID for correlation.
99 request_id: String,
100 /// Order response from venue.
101 response: BinanceNewOrderResponse,
102 },
103 /// Order rejected by venue.
104 OrderRejected {
105 /// Request ID for correlation.
106 request_id: String,
107 /// Error code from venue.
108 code: i32,
109 /// Error message from venue.
110 msg: String,
111 },
112 /// Order canceled successfully.
113 OrderCanceled {
114 /// Request ID for correlation.
115 request_id: String,
116 /// Cancel response from venue.
117 response: BinanceCancelOrderResponse,
118 },
119 /// Cancel rejected by venue.
120 CancelRejected {
121 /// Request ID for correlation.
122 request_id: String,
123 /// Error code from venue.
124 code: i32,
125 /// Error message from venue.
126 msg: String,
127 },
128 /// Cancel-replace response (new order after cancel).
129 CancelReplaceAccepted {
130 /// Request ID for correlation.
131 request_id: String,
132 /// Cancel response.
133 cancel_response: BinanceCancelOrderResponse,
134 /// New order response.
135 new_order_response: BinanceNewOrderResponse,
136 },
137 /// Cancel-replace rejected.
138 CancelReplaceRejected {
139 /// Request ID for correlation.
140 request_id: String,
141 /// Error code from venue.
142 code: i32,
143 /// Error message from venue.
144 msg: String,
145 },
146 /// Request failed without a structured venue response.
147 RequestFailed {
148 /// Request ID for correlation.
149 request_id: String,
150 /// Failure reason.
151 msg: String,
152 },
153 /// All orders canceled for a symbol.
154 AllOrdersCanceled {
155 /// Request ID for correlation.
156 request_id: String,
157 /// Canceled order responses.
158 responses: Vec<BinanceCancelOrderResponse>,
159 },
160 /// User data stream subscribed.
161 UserDataSubscribed {
162 /// Subscription ID from Binance.
163 subscription_id: String,
164 },
165 /// User data subscription was rejected or could not be sent.
166 UserDataSubscriptionRejected(String),
167 /// Order execution report from user data stream.
168 ExecutionReport(Box<BinanceSpotExecutionReport>),
169 /// Account position update from user data stream.
170 AccountPosition(BinanceSpotAccountPositionMsg),
171 /// Balance update from user data stream.
172 BalanceUpdate(BinanceSpotBalanceUpdateMsg),
173 /// Server shutdown notice (sent ~10 minutes before disconnection).
174 ServerShutdown {
175 /// Event time in milliseconds.
176 event_time: i64,
177 },
178 /// Error from venue or network.
179 Error(String),
180}
181
182/// Metadata for a pending request.
183///
184/// Stored in the handler to match responses to their originating requests.
185#[derive(Debug, Clone, Copy)]
186pub enum BinanceSpotWsTradingRequestMeta {
187 /// Pending order placement.
188 PlaceOrder,
189 /// Pending order cancellation.
190 CancelOrder,
191 /// Pending cancel-replace.
192 CancelReplaceOrder,
193 /// Pending cancel-all.
194 CancelAllOrders,
195 /// Pending session logon.
196 SessionLogon,
197 /// Pending user data subscription.
198 SubscribeUserData,
199}
200
201/// WebSocket API request wrapper.
202///
203/// Requests are sent as JSON text frames, responses come back as SBE binary.
204#[derive(Debug, Clone, Serialize)]
205pub struct BinanceSpotWsTradingRequest {
206 /// Unique request ID for correlation.
207 pub id: String,
208 /// API method name (e.g., "order.place").
209 pub method: String,
210 /// Request parameters.
211 pub params: serde_json::Value,
212}
213
214impl BinanceSpotWsTradingRequest {
215 /// Creates a new WebSocket API request.
216 #[must_use]
217 pub fn new(
218 id: impl Into<String>,
219 method: impl Into<String>,
220 params: serde_json::Value,
221 ) -> Self {
222 Self {
223 id: id.into(),
224 method: method.into(),
225 params,
226 }
227 }
228}
229
230/// WebSocket API error response (JSON).
231#[derive(Debug, Clone, Deserialize)]
232pub struct BinanceSpotWsTradingResponseError {
233 /// Error code from venue.
234 pub code: i32,
235 /// Error message from venue.
236 pub msg: String,
237 /// Request ID if available.
238 pub id: Option<String>,
239}
240
241/// WebSocket API method names.
242pub mod method {
243 /// Places a new order.
244 pub const ORDER_PLACE: &str = "order.place";
245 /// Cancels an order.
246 pub const ORDER_CANCEL: &str = "order.cancel";
247 /// Cancels and replaces an order.
248 pub const ORDER_CANCEL_REPLACE: &str = "order.cancelReplace";
249 /// Cancels all open orders for a symbol.
250 pub const OPEN_ORDERS_CANCEL_ALL: &str = "openOrders.cancelAll";
251 /// Initiates session logon.
252 pub const SESSION_LOGON: &str = "session.logon";
253 /// Queries session status.
254 pub const SESSION_STATUS: &str = "session.status";
255 /// Initiates session logout.
256 pub const SESSION_LOGOUT: &str = "session.logout";
257}