ta_statistics/traits/paired_statistics.rs
1/// Paired statistics trait for calculating statistics on pairs of values
2///
3/// This trait provides a foundation for calculating various statistics on pairs of values,
4/// such as covariance, correlation, and beta. It is used as a base trait for more specific
5/// statistical calculations that examine relationships between two variables.
6pub trait PairedStatistics<T> {
7 /// Updates the paired statistical calculations with a new value pair in the time series
8 ///
9 /// Incorporates a new data point pair into the rolling window, maintaining the specified
10 /// window size by removing the oldest pair when necessary. This core method provides
11 /// the foundation for all paired statistical measures that examine relationships
12 /// between two variables.
13 ///
14 /// # Arguments
15 ///
16 /// * `value` - A tuple containing the paired values (x, y) to incorporate into calculations
17 ///
18 /// # Returns
19 ///
20 /// * `&mut Self` - The updated statistics object for method chaining
21 fn next(&mut self, value: (T, T)) -> &mut Self
22 where
23 Self: Sized;
24
25 /// Returns the covariance of the paired values in the rolling window
26 ///
27 /// Covariance measures how two variables change together, indicating the direction
28 /// of their linear relationship. This fundamental measure of association provides:
29 ///
30 /// - Directional relationship analysis between paired time series
31 /// - Foundation for correlation, beta, and regression calculations
32 /// - Raw measurement of how variables move in tandem
33 /// - Basis for portfolio diversification and risk assessments
34 ///
35 /// # Returns
36 ///
37 /// * `Option<T>` - The covariance of the values in the window, or `None` if the window is not full
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// use ta_statistics::{Statistics, PairedStatistics};
43 /// use assert_approx_eq::assert_approx_eq;
44 ///
45 /// let mut stats = Statistics::new(3);
46 /// let mut results = vec![];
47 /// let inputs = [(2.0, 1.0), (4.0, 3.0), (6.0, 2.0), (8.0, 5.0), (10.0, 7.0)];
48 /// inputs.iter().for_each(|i| {
49 /// stats.next(*i).cov().map(|v| results.push(v));
50 /// });
51 ///
52 /// let expected: [f64; 3] = [0.6667, 1.3333, 3.3333];
53 /// for (i, e) in expected.iter().enumerate() {
54 /// assert_approx_eq!(e, results[i], 0.1);
55 /// }
56 ///
57 /// stats.reset().set_ddof(true);
58 /// results = vec![];
59 /// inputs.iter().for_each(|i| {
60 /// stats.next(*i).cov().map(|v| results.push(v));
61 /// });
62 ///
63 /// let expected: [f64; 3] = [1.0, 2.0, 5.0];
64 /// for (i, e) in expected.iter().enumerate() {
65 /// assert_approx_eq!(e, results[i], 0.1);
66 /// }
67 /// ```
68 fn cov(&self) -> Option<T>;
69
70 /// Returns the correlation coefficient (Pearson's r) of paired values in the rolling window
71 ///
72 /// Correlation normalizes covariance by the product of standard deviations, producing
73 /// a standardized measure of linear relationship strength between -1 and 1:
74 ///
75 /// - Quantifies the strength and direction of relationships between variables
76 /// - Enables cross-pair comparison on a standardized scale
77 /// - Provides the foundation for statistical arbitrage models
78 /// - Identifies regime changes in intermarket relationships
79 ///
80 /// # Returns
81 ///
82 /// * `Option<T>` - The correlation coefficient in the window, or `None` if the window is not full
83 ///
84 /// # Examples
85 ///
86 /// ```
87 /// use ta_statistics::{Statistics, PairedStatistics};
88 /// use assert_approx_eq::assert_approx_eq;
89 ///
90 /// let mut stats = Statistics::new(3);
91 /// let mut results = vec![];
92 /// let inputs = [
93 /// (0.496714, 0.115991),
94 /// (-0.138264, -0.329650),
95 /// (0.647689, 0.574363),
96 /// (1.523030, 0.109481),
97 /// (-0.234153, -1.026366),
98 /// (-0.234137, -0.445040),
99 /// (1.579213, 0.599033),
100 /// (0.767435, 0.694328),
101 /// (-0.469474, -0.782644),
102 /// (0.542560, -0.326360)
103 /// ];
104 ///
105 /// inputs.iter().for_each(|i| {
106 /// stats.next(*i).corr().map(|v| results.push(v));
107 /// });
108 /// let expected: [f64; 8] = [0.939464, 0.458316, 0.691218, 0.859137, 0.935658, 0.858379, 0.895148, 0.842302,];
109 /// for (i, e) in expected.iter().enumerate() {
110 /// assert_approx_eq!(e, results[i], 0.1);
111 /// }
112 ///
113 /// ```
114 fn corr(&self) -> Option<T>;
115
116 /// Returns the beta coefficient of the paired values in the rolling window
117 ///
118 /// Beta measures the relative volatility between two time series, indicating
119 /// the sensitivity of one variable to changes in another:
120 ///
121 /// - Quantifies systematic risk exposure between related instruments
122 /// - Determines optimal hedge ratios for risk management
123 /// - Provides relative sensitivity analysis for pair relationships
124 /// - Serves as a key input for factor modeling and attribution analysis
125 ///
126 /// # Returns
127 ///
128 /// * `Option<T>` - The beta coefficient in the window, or `None` if the window is not full
129 ///
130 /// # Examples
131 ///
132 /// ```
133 /// use ta_statistics::{Statistics, PairedStatistics};
134 /// use assert_approx_eq::assert_approx_eq;
135 ///
136 /// let mut stats = Statistics::new(3);
137 /// let mut results = vec![];
138 /// let inputs = [
139 /// (0.015, 0.010),
140 /// (0.025, 0.015),
141 /// (-0.010, -0.005),
142 /// (0.030, 0.020),
143 /// (0.005, 0.010),
144 /// (-0.015, -0.010),
145 /// (0.020, 0.015),
146 /// ];
147 ///
148 /// inputs.iter().for_each(|i| {
149 /// stats.next(*i).beta().map(|v| results.push(v));
150 /// });
151 ///
152 /// let expected: [f64; 5] = [1.731, 1.643, 1.553, 1.429, 1.286];
153 /// for (i, e) in expected.iter().enumerate() {
154 /// assert_approx_eq!(e, results[i], 0.1);
155 /// }
156 /// ```
157 fn beta(&self) -> Option<T>;
158}