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