Skip to main content

binance_sdk/spot/websocket_streams/
mod.rs

1/*
2 * Spot WebSocket Market Streams
3 *
4 * Access market data, manage accounts, and trade on Binance Spot.
5 *
6 * The version of the OpenAPI document: 1.0.0
7 *
8 *
9 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10 * https://openapi-generator.tech
11 * Do not edit the class manually.
12 */
13
14#![allow(unused_imports)]
15use serde_json::Value;
16use std::sync::{Arc, atomic::Ordering};
17use tokio::spawn;
18
19use crate::common::config::ConfigurationWebsocketStreams;
20use crate::common::websocket::{
21    Subscription, WebsocketBase, WebsocketStream, WebsocketStreams as WebsocketStreamsBase,
22    create_stream_handler,
23};
24use crate::models::{StreamId, WebsocketEvent, WebsocketMode};
25
26mod apis;
27mod handle;
28mod models;
29
30pub use apis::*;
31pub use handle::*;
32pub use models::*;
33
34const HAS_TIME_UNIT: bool = true;
35
36pub struct WebsocketStreams {
37    websocket_streams_base: Arc<WebsocketStreamsBase>,
38    api_client: ApiClient,
39}
40
41impl WebsocketStreams {
42    pub(crate) async fn connect(
43        config: ConfigurationWebsocketStreams,
44        streams: Vec<String>,
45        mode: Option<WebsocketMode>,
46    ) -> anyhow::Result<Self> {
47        let mut cfg = config;
48        if let Some(m) = mode {
49            cfg.mode = m;
50        }
51
52        if !HAS_TIME_UNIT {
53            cfg.time_unit = None;
54        }
55
56        let websocket_streams_base = WebsocketStreamsBase::new(cfg, vec![], vec![]);
57
58        websocket_streams_base.clone().connect(streams).await?;
59
60        Ok(Self {
61            websocket_streams_base: websocket_streams_base.clone(),
62            api_client: ApiClient::new(websocket_streams_base.clone()),
63        })
64    }
65
66    /// Subscribes to WebSocket events with a provided callback function.
67    ///
68    /// # Arguments
69    ///
70    /// * `callback` - A mutable function that takes a `WebsocketEvent` and is `Send` and `'static`.
71    ///
72    /// # Returns
73    ///
74    /// A `Subscription` that can be used to manage the event subscription.
75    ///
76    /// # Examples
77    ///
78    ///
79    /// let subscription = `websocket_streams.subscribe_on_ws_events(|event`| {
80    ///     // Handle WebSocket event
81    /// });
82    ///
83    pub fn subscribe_on_ws_events<F>(&self, callback: F) -> Subscription
84    where
85        F: FnMut(WebsocketEvent) + Send + 'static,
86    {
87        let base = Arc::clone(&self.websocket_streams_base);
88        base.common.events.subscribe(callback)
89    }
90
91    /// Unsubscribes from WebSocket events for a given `Subscription`.
92    ///
93    /// # Arguments
94    ///
95    /// * `subscription` - The `Subscription` to unsubscribe from WebSocket events.
96    ///
97    /// # Examples
98    ///
99    ///
100    /// let subscription = `websocket_streams.subscribe_on_ws_events(|event`| {
101    ///     // Handle WebSocket event
102    /// });
103    /// `websocket_streams.unsubscribe_from_ws_events(subscription)`;
104    ///
105    pub fn unsubscribe_from_ws_events(&self, subscription: Subscription) {
106        subscription.unsubscribe();
107    }
108
109    /// Disconnects the WebSocket connection.
110    ///
111    /// # Returns
112    ///
113    /// A `Result` indicating whether the disconnection was successful.
114    /// Returns an error if the disconnection fails.
115    ///
116    /// # Errors
117    ///
118    /// Returns an [`anyhow::Error`] if the connection fails.
119    ///
120    /// # Examples
121    ///
122    ///
123    /// let `websocket_streams` = `WebSocketStreams::new`(...);
124    /// `websocket_streams.disconnect().await`?;
125    ///
126    pub async fn disconnect(&self) -> anyhow::Result<()> {
127        self.websocket_streams_base
128            .disconnect()
129            .await
130            .map_err(anyhow::Error::msg)
131    }
132
133    /// Checks if the WebSocket connection is currently active.
134    ///
135    /// # Returns
136    ///
137    /// A `bool` indicating whether the WebSocket connection is established and connected.
138    ///
139    /// # Examples
140    ///
141    ///
142    /// let `is_active` = `websocket_streams.is_connected().await`;
143    /// if `is_active` {
144    ///     // WebSocket connection is active
145    /// }
146    ///
147    pub async fn is_connected(&self) -> bool {
148        self.websocket_streams_base.is_connected().await
149    }
150
151    /// Sends a ping to the WebSocket server to maintain the connection.
152    ///
153    /// # Examples
154    ///
155    ///
156    /// `websocket_streams.ping_server().await`;
157    ///
158    ///
159    /// This method sends a ping request to the WebSocket server to keep the connection alive
160    /// and check the server's responsiveness.
161    pub async fn ping_server(&self) {
162        self.websocket_streams_base.ping_server().await;
163    }
164
165    /// Subscribes to specified WebSocket streams.
166    ///
167    /// # Arguments
168    ///
169    /// * `streams` - A vector of stream names to subscribe to
170    /// * `id` - An optional identifier for the subscription request
171    ///
172    /// # Examples
173    ///
174    ///
175    /// `websocket_streams.subscribe(vec`!["`btcusdt@trade".to_string()`], None).await;
176    ///
177    ///
178    /// This method initiates an asynchronous subscription to the specified WebSocket streams.
179    /// The subscription is performed in a separate task using `spawn`.
180    pub fn subscribe(&self, streams: Vec<String>, id: Option<String>) {
181        let base = Arc::clone(&self.websocket_streams_base);
182        spawn(async move { base.subscribe(streams, id.map(StreamId::from), None).await });
183    }
184
185    /// Unsubscribes from specified WebSocket streams.
186    ///
187    /// # Arguments
188    ///
189    /// * `streams` - A vector of stream names to unsubscribe from
190    /// * `id` - An optional identifier for the unsubscription request
191    ///
192    /// # Examples
193    ///
194    ///
195    /// `websocket_streams.unsubscribe(vec`!["`btcusdt@trade".to_string()`], None).await;
196    ///
197    ///
198    /// This method initiates an asynchronous unsubscription from the specified WebSocket streams.
199    /// The unsubscription is performed in a separate task using `spawn`.
200    pub fn unsubscribe(&self, streams: Vec<String>, id: Option<String>) {
201        let base = Arc::clone(&self.websocket_streams_base);
202        spawn(async move {
203            base.unsubscribe(streams, id.map(StreamId::from), None)
204                .await;
205        });
206    }
207
208    /// Checks if the current WebSocket stream is subscribed to a specific stream.
209    ///
210    /// # Arguments
211    ///
212    /// * `stream` - The name of the stream to check for subscription
213    ///
214    /// # Returns
215    ///
216    /// A boolean indicating whether the stream is currently subscribed
217    ///
218    /// # Examples
219    ///
220    ///
221    /// let `is_subscribed` = `websocket_streams.is_subscribed("btcusdt@trade").await`;
222    ///
223    ///
224    /// This method checks the subscription status of a specific WebSocket stream.
225    pub async fn is_subscribed(&self, stream: &str) -> bool {
226        self.websocket_streams_base.is_subscribed(stream).await
227    }
228
229    /// User Data Stream
230    ///
231    /// Establishes a WebSocket stream for user-specific data events.
232    ///
233    /// # Arguments
234    ///
235    /// - `listen_key`: A unique key for identifying the user's data stream
236    /// - `id`: An optional identifier for the stream request
237    ///
238    /// # Returns
239    ///
240    /// [`Arc<WebsocketStream<UserDataStreamEventsResponse>>`] on success.
241    ///
242    /// # Errors
243    ///
244    /// Returns an [`anyhow::Error`] if the stream creation fails or if parsing the response encounters issues.
245    ///
246    /// # Examples
247    ///
248    ///
249    /// let `user_stream` = `websocket_streams.user_data(listen_key`, None).await?;
250    ///
251    pub async fn user_data(
252        &self,
253        listen_key: String,
254        id: Option<String>,
255    ) -> anyhow::Result<Arc<WebsocketStream<UserDataStreamEventsResponse>>> {
256        Ok(create_stream_handler::<UserDataStreamEventsResponse>(
257            WebsocketBase::WebsocketStreams(self.websocket_streams_base.clone()),
258            listen_key,
259            id.map(StreamId::from),
260            None,
261        )
262        .await)
263    }
264
265    /// Aggregate Trade Streams
266    ///
267    /// The Aggregate Trade Streams push trade information that is aggregated
268    /// for a single taker order.
269    ///
270    /// Update Speed: Real-time
271    ///
272    /// # Arguments
273    ///
274    /// - `params`: [`AggTradeParams`]
275    ///   The parameters for this operation.
276    ///
277    /// # Returns
278    ///
279    /// [`Arc<WebsocketStream<models::AggTradeResponse>>`] on success.
280    ///
281    /// # Errors
282    ///
283    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
284    ///
285    ///
286    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#agg-trade).
287    ///
288    pub async fn agg_trade(
289        &self,
290        params: AggTradeParams,
291    ) -> anyhow::Result<Arc<WebsocketStream<models::AggTradeResponse>>> {
292        self.api_client.agg_trade(params).await
293    }
294
295    /// All Market Rolling Window Statistics Streams
296    ///
297    /// Rolling window ticker statistics for all market symbols, computed over
298    /// multiple windows.
299    ///
300    /// Note that only tickers that have changed will be present in the array.
301    ///
302    /// Update Speed: 1000ms
303    ///
304    /// # Arguments
305    ///
306    /// - `params`: [`AllMarketRollingWindowTickerParams`]
307    ///   The parameters for this operation.
308    ///
309    /// # Returns
310    ///
311    /// [`Arc<WebsocketStream<Vec<models::AllMarketRollingWindowTickerResponseInner>>>`] on success.
312    ///
313    /// # Errors
314    ///
315    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
316    ///
317    ///
318    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#all-market-rolling-window-ticker).
319    ///
320    pub async fn all_market_rolling_window_ticker(
321        &self,
322        params: AllMarketRollingWindowTickerParams,
323    ) -> anyhow::Result<Arc<WebsocketStream<Vec<models::AllMarketRollingWindowTickerResponseInner>>>>
324    {
325        self.api_client
326            .all_market_rolling_window_ticker(params)
327            .await
328    }
329
330    /// All Market Mini Tickers Stream
331    ///
332    /// 24hr rolling window mini-ticker statistics for all symbols that changed
333    /// in an array. These are NOT the statistics of the UTC day, but a 24hr
334    /// rolling window for the previous 24hrs. Note that only tickers that have
335    /// changed will be present in the array.
336    ///
337    /// Update Speed: 1000ms
338    ///
339    /// # Arguments
340    ///
341    /// - `params`: [`AllMiniTickerParams`]
342    ///   The parameters for this operation.
343    ///
344    /// # Returns
345    ///
346    /// [`Arc<WebsocketStream<Vec<models::AllMiniTickerResponseInner>>>`] on success.
347    ///
348    /// # Errors
349    ///
350    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
351    ///
352    ///
353    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#all-mini-ticker).
354    ///
355    pub async fn all_mini_ticker(
356        &self,
357        params: AllMiniTickerParams,
358    ) -> anyhow::Result<Arc<WebsocketStream<Vec<models::AllMiniTickerResponseInner>>>> {
359        self.api_client.all_mini_ticker(params).await
360    }
361
362    /// Average Price
363    ///
364    /// Average price streams push changes in the average price over a fixed time interval.
365    ///
366    /// Update Speed: 1000ms
367    ///
368    /// # Arguments
369    ///
370    /// - `params`: [`AvgPriceParams`]
371    ///   The parameters for this operation.
372    ///
373    /// # Returns
374    ///
375    /// [`Arc<WebsocketStream<models::AvgPriceResponse>>`] on success.
376    ///
377    /// # Errors
378    ///
379    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
380    ///
381    ///
382    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#avg-price).
383    ///
384    pub async fn avg_price(
385        &self,
386        params: AvgPriceParams,
387    ) -> anyhow::Result<Arc<WebsocketStream<models::AvgPriceResponse>>> {
388        self.api_client.avg_price(params).await
389    }
390
391    /// Block Trade Streams
392    ///
393    /// Block Trade Streams push block trade information in real-time.
394    ///
395    /// Update Speed: Real-time
396    ///
397    /// # Arguments
398    ///
399    /// - `params`: [`BlockTradeParams`]
400    ///   The parameters for this operation.
401    ///
402    /// # Returns
403    ///
404    /// [`Arc<WebsocketStream<models::BlockTradeResponse>>`] on success.
405    ///
406    /// # Errors
407    ///
408    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
409    ///
410    ///
411    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#block-trade).
412    ///
413    pub async fn block_trade(
414        &self,
415        params: BlockTradeParams,
416    ) -> anyhow::Result<Arc<WebsocketStream<models::BlockTradeResponse>>> {
417        self.api_client.block_trade(params).await
418    }
419
420    /// Individual Symbol Book Ticker Streams
421    ///
422    /// Pushes any update to the best bid or ask's price or quantity in
423    /// real-time for a specified symbol.
424    ///
425    /// Multiple `<symbol>@bookTicker` streams can be subscribed to over one
426    /// connection.
427    ///
428    /// Update Speed: Real-time
429    ///
430    /// # Arguments
431    ///
432    /// - `params`: [`BookTickerParams`]
433    ///   The parameters for this operation.
434    ///
435    /// # Returns
436    ///
437    /// [`Arc<WebsocketStream<models::BookTickerResponse>>`] on success.
438    ///
439    /// # Errors
440    ///
441    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
442    ///
443    ///
444    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#book-ticker).
445    ///
446    pub async fn book_ticker(
447        &self,
448        params: BookTickerParams,
449    ) -> anyhow::Result<Arc<WebsocketStream<models::BookTickerResponse>>> {
450        self.api_client.book_ticker(params).await
451    }
452
453    /// Diff. Depth Stream
454    ///
455    /// Order book price and quantity depth updates used to locally manage an order book.
456    ///
457    /// Update Speed: 1000ms or 100ms
458    ///
459    /// # Arguments
460    ///
461    /// - `params`: [`DiffBookDepthParams`]
462    ///   The parameters for this operation.
463    ///
464    /// # Returns
465    ///
466    /// [`Arc<WebsocketStream<models::DiffBookDepthResponse>>`] on success.
467    ///
468    /// # Errors
469    ///
470    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
471    ///
472    ///
473    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#diff-book-depth).
474    ///
475    pub async fn diff_book_depth(
476        &self,
477        params: DiffBookDepthParams,
478    ) -> anyhow::Result<Arc<WebsocketStream<models::DiffBookDepthResponse>>> {
479        self.api_client.diff_book_depth(params).await
480    }
481
482    /// Kline/Candlestick Streams for UTC
483    ///
484    /// The Kline/Candlestick Stream push updates to the current
485    /// klines/candlestick every second in `UTC+0` timezone
486    ///
487    /// Update Speed: 1000ms for `1s`, 2000ms for the other intervals
488    ///
489    /// # Arguments
490    ///
491    /// - `params`: [`KlineParams`]
492    ///   The parameters for this operation.
493    ///
494    /// # Returns
495    ///
496    /// [`Arc<WebsocketStream<models::KlineResponse>>`] on success.
497    ///
498    /// # Errors
499    ///
500    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
501    ///
502    ///
503    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#kline).
504    ///
505    pub async fn kline(
506        &self,
507        params: KlineParams,
508    ) -> anyhow::Result<Arc<WebsocketStream<models::KlineResponse>>> {
509        self.api_client.kline(params).await
510    }
511
512    /// Kline/Candlestick Streams with timezone offset
513    ///
514    /// The Kline/Candlestick Stream push updates to the current
515    /// klines/candlestick every second in `UTC+8` timezone
516    ///
517    /// **Kline/Candlestick chart intervals:**
518    ///
519    /// Supported intervals: See Kline/Candlestick chart intervals
520    ///
521    /// **UTC+8 timezone offset:**
522    /// - Kline intervals open and close in the UTC+8 timezone. For example the 1d klines will open at the beginning of the UTC+8 day, and close at the end of the UTC+8 day.
523    /// - Note that E (event time), t (start time) and T (close time) in the payload are Unix timestamps, which are always interpreted in UTC.
524    ///
525    /// Update Speed: 1000ms for `1s`, 2000ms for the other intervals
526    ///
527    /// # Arguments
528    ///
529    /// - `params`: [`KlineOffsetParams`]
530    ///   The parameters for this operation.
531    ///
532    /// # Returns
533    ///
534    /// [`Arc<WebsocketStream<models::KlineOffsetResponse>>`] on success.
535    ///
536    /// # Errors
537    ///
538    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
539    ///
540    ///
541    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#kline-offset).
542    ///
543    pub async fn kline_offset(
544        &self,
545        params: KlineOffsetParams,
546    ) -> anyhow::Result<Arc<WebsocketStream<models::KlineOffsetResponse>>> {
547        self.api_client.kline_offset(params).await
548    }
549
550    /// Individual Symbol Mini Ticker Stream
551    ///
552    /// 24hr rolling window mini-ticker statistics. These are NOT the statistics
553    /// of the UTC day, but a 24hr rolling window for the previous 24hrs.
554    ///
555    /// Update Speed: 1000ms
556    ///
557    /// # Arguments
558    ///
559    /// - `params`: [`MiniTickerParams`]
560    ///   The parameters for this operation.
561    ///
562    /// # Returns
563    ///
564    /// [`Arc<WebsocketStream<models::MiniTickerResponse>>`] on success.
565    ///
566    /// # Errors
567    ///
568    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
569    ///
570    ///
571    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#mini-ticker).
572    ///
573    pub async fn mini_ticker(
574        &self,
575        params: MiniTickerParams,
576    ) -> anyhow::Result<Arc<WebsocketStream<models::MiniTickerResponse>>> {
577        self.api_client.mini_ticker(params).await
578    }
579
580    /// WebSocket Partial Book Depth Streams
581    ///
582    /// Top **\<levels\>** bids and asks, pushed every second.
583    ///
584    /// Update Speed: 1000ms or 100ms
585    ///
586    /// # Arguments
587    ///
588    /// - `params`: [`PartialBookDepthParams`]
589    ///   The parameters for this operation.
590    ///
591    /// # Returns
592    ///
593    /// [`Arc<WebsocketStream<models::PartialBookDepthResponse>>`] on success.
594    ///
595    /// # Errors
596    ///
597    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
598    ///
599    ///
600    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#partial-book-depth).
601    ///
602    pub async fn partial_book_depth(
603        &self,
604        params: PartialBookDepthParams,
605    ) -> anyhow::Result<Arc<WebsocketStream<models::PartialBookDepthResponse>>> {
606        self.api_client.partial_book_depth(params).await
607    }
608
609    /// Reference Price Streams
610    ///
611    /// Reference price stream for a symbol.
612    ///
613    /// Update Speed: 1000ms
614    ///
615    /// # Arguments
616    ///
617    /// - `params`: [`ReferencePriceParams`]
618    ///   The parameters for this operation.
619    ///
620    /// # Returns
621    ///
622    /// [`Arc<WebsocketStream<models::ReferencePriceResponse>>`] on success.
623    ///
624    /// # Errors
625    ///
626    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
627    ///
628    ///
629    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#reference-price).
630    ///
631    pub async fn reference_price(
632        &self,
633        params: ReferencePriceParams,
634    ) -> anyhow::Result<Arc<WebsocketStream<models::ReferencePriceResponse>>> {
635        self.api_client.reference_price(params).await
636    }
637
638    /// Individual Symbol Rolling Window Statistics Streams
639    ///
640    /// Rolling window ticker statistics for a single symbol, computed over
641    /// multiple windows.
642    ///
643    /// **Note:** This stream is different from the `<symbol>@ticker` stream. The open time `"O"` always starts on a minute, while the closing time `"C"` is the current time
644    /// of the update. As such, the effective window might be up to 59999ms wider than `<window_size>`.
645    ///
646    /// Update Speed: 1000ms
647    ///
648    /// # Arguments
649    ///
650    /// - `params`: [`RollingWindowTickerParams`]
651    ///   The parameters for this operation.
652    ///
653    /// # Returns
654    ///
655    /// [`Arc<WebsocketStream<models::RollingWindowTickerResponse>>`] on success.
656    ///
657    /// # Errors
658    ///
659    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
660    ///
661    ///
662    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#rolling-window-ticker).
663    ///
664    pub async fn rolling_window_ticker(
665        &self,
666        params: RollingWindowTickerParams,
667    ) -> anyhow::Result<Arc<WebsocketStream<models::RollingWindowTickerResponse>>> {
668        self.api_client.rolling_window_ticker(params).await
669    }
670
671    /// Individual Symbol Ticker Streams
672    ///
673    /// 24hr rolling window ticker statistics for a single symbol. These are NOT
674    /// the statistics of the UTC day, but a 24hr rolling window for the
675    /// previous 24hrs.
676    ///
677    /// Update Speed: 1000ms
678    ///
679    /// # Arguments
680    ///
681    /// - `params`: [`TickerParams`]
682    ///   The parameters for this operation.
683    ///
684    /// # Returns
685    ///
686    /// [`Arc<WebsocketStream<models::TickerResponse>>`] on success.
687    ///
688    /// # Errors
689    ///
690    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
691    ///
692    ///
693    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#ticker).
694    ///
695    pub async fn ticker(
696        &self,
697        params: TickerParams,
698    ) -> anyhow::Result<Arc<WebsocketStream<models::TickerResponse>>> {
699        self.api_client.ticker(params).await
700    }
701
702    /// Trade Streams
703    ///
704    /// The Trade Streams push raw trade information; each trade has a unique
705    /// buyer and seller.
706    ///
707    /// Update Speed: Real-time
708    ///
709    /// # Arguments
710    ///
711    /// - `params`: [`TradeParams`]
712    ///   The parameters for this operation.
713    ///
714    /// # Returns
715    ///
716    /// [`Arc<WebsocketStream<models::TradeResponse>>`] on success.
717    ///
718    /// # Errors
719    ///
720    /// Returns an [`anyhow::Error`] if the stream request fails, if parameters are invalid, or if parsing the response fails.
721    ///
722    ///
723    /// For full API details, see the [Binance API Documentation](https://developers.binance.com/en/docs/catalog/core-trading-spot-trading/api/ws-streams/~#trade).
724    ///
725    pub async fn trade(
726        &self,
727        params: TradeParams,
728    ) -> anyhow::Result<Arc<WebsocketStream<models::TradeResponse>>> {
729        self.api_client.trade(params).await
730    }
731}