Skip to main content

quant_indicators/
series.rs

1//! Time series representation for indicator output.
2
3use chrono::{DateTime, Utc};
4use rust_decimal::Decimal;
5
6/// A time-indexed series of values.
7///
8/// Represents the output of an indicator computation.
9/// Each value is paired with its timestamp.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Series {
12    values: Vec<(DateTime<Utc>, Decimal)>,
13}
14
15impl Series {
16    /// Create a new series from timestamped values.
17    #[must_use]
18    pub fn new(values: Vec<(DateTime<Utc>, Decimal)>) -> Self {
19        Self { values }
20    }
21
22    /// Create an empty series.
23    #[must_use]
24    pub fn empty() -> Self {
25        Self { values: Vec::new() }
26    }
27
28    /// Get the number of values in the series.
29    #[must_use]
30    pub fn len(&self) -> usize {
31        self.values.len()
32    }
33
34    /// Check if the series is empty.
35    #[must_use]
36    pub fn is_empty(&self) -> bool {
37        self.values.is_empty()
38    }
39
40    /// Get the underlying values.
41    #[must_use]
42    pub fn values(&self) -> &[(DateTime<Utc>, Decimal)] {
43        &self.values
44    }
45
46    /// Get just the decimal values without timestamps.
47    #[must_use]
48    pub fn decimal_values(&self) -> Vec<Decimal> {
49        self.values.iter().map(|(_, v)| *v).collect()
50    }
51
52    /// Get the value at a specific index.
53    #[must_use]
54    pub fn get(&self, index: usize) -> Option<(DateTime<Utc>, Decimal)> {
55        self.values.get(index).copied()
56    }
57
58    /// Get the last value in the series.
59    #[must_use]
60    pub fn last(&self) -> Option<(DateTime<Utc>, Decimal)> {
61        self.values.last().copied()
62    }
63
64    /// Get the first value in the series.
65    #[must_use]
66    pub fn first(&self) -> Option<(DateTime<Utc>, Decimal)> {
67        self.values.first().copied()
68    }
69}
70
71impl IntoIterator for Series {
72    type Item = (DateTime<Utc>, Decimal);
73    type IntoIter = std::vec::IntoIter<Self::Item>;
74
75    fn into_iter(self) -> Self::IntoIter {
76        self.values.into_iter()
77    }
78}
79
80impl<'a> IntoIterator for &'a Series {
81    type Item = &'a (DateTime<Utc>, Decimal);
82    type IntoIter = std::slice::Iter<'a, (DateTime<Utc>, Decimal)>;
83
84    fn into_iter(self) -> Self::IntoIter {
85        self.values.iter()
86    }
87}
88
89#[cfg(test)]
90#[path = "series_tests.rs"]
91mod tests;