Skip to main content

finance_query_core/websocket/
mod.rs

1//! WebSocket support types for real-time data streaming.
2//!
3//! This module provides framework-agnostic data structures for WebSocket
4//! subscriptions. These types can be used with any WebSocket framework.
5
6use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8
9use crate::models::movers::MarketMover;
10use crate::models::sectors::MarketSector;
11use crate::models::{News, Quote, SimpleQuote};
12
13/// Real-time quote update for streaming stock quotes.
14///
15/// This type supports streaming a single quote or multiple quotes at once.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct QuotesUpdate {
18    /// List of updated quotes
19    pub quotes: Vec<SimpleQuote>,
20    /// Timestamp of the update
21    pub timestamp: DateTime<Utc>,
22}
23
24impl QuotesUpdate {
25    /// Create a new QuotesUpdate with a single quote.
26    pub fn single(quote: SimpleQuote) -> Self {
27        Self {
28            quotes: vec![quote],
29            timestamp: Utc::now(),
30        }
31    }
32
33    /// Create a new QuotesUpdate with multiple quotes.
34    pub fn multiple(quotes: Vec<SimpleQuote>) -> Self {
35        Self {
36            quotes,
37            timestamp: Utc::now(),
38        }
39    }
40
41    /// Create a new QuotesUpdate with multiple quotes (alias for multiple).
42    pub fn new(quotes: Vec<SimpleQuote>) -> Self {
43        Self::multiple(quotes)
44    }
45
46    /// Create a new QuotesUpdate with a specific timestamp.
47    pub fn with_timestamp(quotes: Vec<SimpleQuote>, timestamp: DateTime<Utc>) -> Self {
48        Self { quotes, timestamp }
49    }
50
51    /// Check if this update contains a specific symbol.
52    pub fn contains_symbol(&self, symbol: &str) -> bool {
53        self.quotes.iter().any(|q| q.symbol == symbol)
54    }
55
56    /// Get a quote by symbol if present.
57    pub fn get_quote(&self, symbol: &str) -> Option<&SimpleQuote> {
58        self.quotes.iter().find(|q| q.symbol == symbol)
59    }
60
61    /// Returns true if this update contains no quotes.
62    pub fn is_empty(&self) -> bool {
63        self.quotes.is_empty()
64    }
65
66    /// Returns the number of quotes in this update.
67    pub fn len(&self) -> usize {
68        self.quotes.len()
69    }
70}
71
72/// Profile update containing quote, similar stocks, sector performance, and news.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct ProfileUpdate {
75    /// Current quote data for the symbol
76    pub quote: Option<Quote>,
77    /// Similar stocks to the symbol
78    pub similar: Option<Vec<SimpleQuote>>,
79    /// Sector performance data
80    pub sector_performance: Option<MarketSector>,
81    /// Recent news for the symbol
82    pub news: Option<Vec<News>>,
83}
84
85/// Market movers update containing actives, gainers, and losers.
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct MoversUpdate {
88    /// Most active stocks
89    pub actives: Vec<MarketMover>,
90    /// Top gaining stocks
91    pub gainers: Vec<MarketMover>,
92    /// Top losing stocks
93    pub losers: Vec<MarketMover>,
94    /// Timestamp of the update
95    pub timestamp: DateTime<Utc>,
96}
97
98impl MoversUpdate {
99    /// Create a new MoversUpdate with current timestamp.
100    pub fn new(
101        actives: Vec<MarketMover>,
102        gainers: Vec<MarketMover>,
103        losers: Vec<MarketMover>,
104    ) -> Self {
105        Self {
106            actives,
107            gainers,
108            losers,
109            timestamp: Utc::now(),
110        }
111    }
112
113    /// Create a new MoversUpdate with a specific timestamp.
114    pub fn with_timestamp(
115        actives: Vec<MarketMover>,
116        gainers: Vec<MarketMover>,
117        losers: Vec<MarketMover>,
118        timestamp: DateTime<Utc>,
119    ) -> Self {
120        Self {
121            actives,
122            gainers,
123            losers,
124            timestamp,
125        }
126    }
127}
128
129/// Market hours status update.
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct MarketHours {
132    /// Current market status (e.g., "open", "closed", "pre-market", "after-hours")
133    pub status: String,
134    /// Optional reason for the status (e.g., holiday name)
135    pub reason: Option<String>,
136    /// Timestamp of the status update
137    pub timestamp: DateTime<Utc>,
138}
139
140/// Moving average update for real-time indicator streaming.
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct MovingAverageUpdate {
143    /// Stock symbol
144    pub symbol: String,
145    /// Indicator type (e.g., "SMA", "EMA")
146    pub indicator_type: String,
147    /// Period for the moving average
148    pub period: i32,
149    /// Calculated value
150    pub value: f64,
151    /// Timestamp of the calculation
152    pub timestamp: DateTime<Utc>,
153}