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}