Skip to main content

tradingview/source/
tradingview.rs

1//! TradingView data source adapter.
2//!
3//! Bridges the existing TradingView WebSocket client infrastructure to the
4//! generic [`DataSource`] trait and [`MarketEvent`] pipeline.
5//!
6//! # Migration path
7//!
8//! The existing code in `live/` (WebSocket, handler, command runner) can be
9//! incrementally adapted to implement this trait. The key change is replacing
10//! the `Handler` trait's type-specific methods (`handle_quote_data`,
11//! `handle_series_data`) with event normalization functions that produce
12//! `MarketEvent` variants.
13
14use async_trait::async_trait;
15use tokio_util::sync::CancellationToken;
16
17use super::DataSource;
18use crate::Result;
19use crate::events::MarketEvent;
20
21/// TradingView WebSocket data source.
22///
23/// Wraps the existing `WebSocketClient` to produce normalized events.
24/// This is a forward-compatible design; full implementation requires
25/// adapting the existing handler code to emit `MarketEvent` batches.
26pub struct TradingViewSource {
27    name: String,
28}
29
30impl TradingViewSource {
31    /// Create a new TradingView data source.
32    ///
33    /// In the full implementation, this would accept configuration
34    /// (auth_token, server, subscriptions) and initialize the
35    /// `WebSocketClient` + `CommandRunner`.
36    pub fn new() -> Self {
37        Self {
38            name: "tradingview".to_string(),
39        }
40    }
41}
42
43impl Default for TradingViewSource {
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49#[async_trait]
50impl DataSource for TradingViewSource {
51    async fn run(
52        &self,
53        _sink: tokio::sync::mpsc::Sender<Vec<MarketEvent>>,
54        _cancel: CancellationToken,
55    ) -> Result<()> {
56        // In the full implementation, this would:
57        // 1. Create a WebSocketClient with the configured server/auth
58        // 2. Create a CommandRunner
59        // 3. Set up quote/chart sessions for the requested subscriptions
60        // 4. Read messages from the WebSocket in a loop
61        // 5. Normalize each raw message into MarketEvent variants
62        // 6. Send batches through the sink channel
63        // 7. Handle reconnection and error recovery
64        // 8. Respect the CancellationToken for graceful shutdown
65
66        // Placeholder: yield nothing
67        let _ = self.name;
68        Ok(())
69    }
70
71    fn name(&self) -> &str {
72        &self.name
73    }
74}