@ebowwa/quant-rust 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +161 -0
  2. package/bun-ffi.d.ts +54 -0
  3. package/dist/index.js +576 -0
  4. package/dist/src/index.d.ts +324 -0
  5. package/dist/src/index.d.ts.map +1 -0
  6. package/dist/types/index.d.ts +403 -0
  7. package/dist/types/index.d.ts.map +1 -0
  8. package/native/README.md +62 -0
  9. package/native/darwin-arm64/libquant_rust.dylib +0 -0
  10. package/package.json +70 -0
  11. package/scripts/postinstall.cjs +85 -0
  12. package/src/ffi.rs +496 -0
  13. package/src/index.ts +1073 -0
  14. package/src/indicators/ma.rs +222 -0
  15. package/src/indicators/mod.rs +18 -0
  16. package/src/indicators/momentum.rs +353 -0
  17. package/src/indicators/sr.rs +195 -0
  18. package/src/indicators/trend.rs +351 -0
  19. package/src/indicators/volatility.rs +270 -0
  20. package/src/indicators/volume.rs +213 -0
  21. package/src/lib.rs +130 -0
  22. package/src/patterns/breakout.rs +431 -0
  23. package/src/patterns/chart.rs +772 -0
  24. package/src/patterns/mod.rs +394 -0
  25. package/src/patterns/sr.rs +423 -0
  26. package/src/prediction/amm.rs +338 -0
  27. package/src/prediction/arbitrage.rs +230 -0
  28. package/src/prediction/calibration.rs +317 -0
  29. package/src/prediction/kelly.rs +232 -0
  30. package/src/prediction/lmsr.rs +194 -0
  31. package/src/prediction/mod.rs +59 -0
  32. package/src/prediction/odds.rs +229 -0
  33. package/src/prediction/pnl.rs +254 -0
  34. package/src/prediction/risk.rs +228 -0
  35. package/src/risk/beta.rs +257 -0
  36. package/src/risk/drawdown.rs +256 -0
  37. package/src/risk/leverage.rs +201 -0
  38. package/src/risk/mod.rs +388 -0
  39. package/src/risk/portfolio.rs +287 -0
  40. package/src/risk/ratios.rs +290 -0
  41. package/src/risk/sizing.rs +194 -0
  42. package/src/risk/var.rs +222 -0
  43. package/src/stats/cdf.rs +257 -0
  44. package/src/stats/correlation.rs +225 -0
  45. package/src/stats/distribution.rs +194 -0
  46. package/src/stats/hypothesis.rs +177 -0
  47. package/src/stats/matrix.rs +346 -0
  48. package/src/stats/mod.rs +257 -0
  49. package/src/stats/regression.rs +239 -0
  50. package/src/stats/rolling.rs +193 -0
  51. package/src/stats/timeseries.rs +263 -0
  52. package/src/types.rs +224 -0
  53. package/src/utils/mod.rs +215 -0
  54. package/src/utils/normalize.rs +192 -0
  55. package/src/utils/price.rs +167 -0
  56. package/src/utils/quantiles.rs +177 -0
  57. package/src/utils/returns.rs +158 -0
  58. package/src/utils/rolling.rs +97 -0
  59. package/src/utils/stats.rs +154 -0
  60. package/types/index.ts +513 -0
@@ -0,0 +1,270 @@
1
+ //! Volatility Indicators
2
+ //!
3
+ //! Indicators that measure the rate and magnitude of price changes.
4
+
5
+ use crate::utils::{mean, rolling};
6
+
7
+ /// Average True Range (ATR) result
8
+ #[derive(Debug, Clone, PartialEq)]
9
+ pub struct ATRResult {
10
+ /// ATR values (smoothed TR)
11
+ pub atr: Vec<f64>,
12
+ /// True Range values
13
+ pub tr: Vec<f64>,
14
+ }
15
+
16
+ /// Bollinger Bands result
17
+ #[derive(Debug, Clone, PartialEq)]
18
+ pub struct BollingerBandsResult {
19
+ /// Upper band (middle + std_dev * multiplier)
20
+ pub upper: Vec<f64>,
21
+ /// Middle band (SMA)
22
+ pub middle: Vec<f64>,
23
+ /// Lower band (middle - std_dev * multiplier)
24
+ pub lower: Vec<f64>,
25
+ /// Bandwidth ((upper - lower) / middle * 100)
26
+ pub bandwidth: Vec<f64>,
27
+ /// %B (position within bands: (price - lower) / (upper - lower))
28
+ pub percent_b: Vec<f64>,
29
+ }
30
+
31
+ /// Keltner Channels result
32
+ #[derive(Debug, Clone, PartialEq)]
33
+ pub struct KeltnerChannelsResult {
34
+ /// Upper channel
35
+ pub upper: Vec<f64>,
36
+ /// Middle channel (EMA)
37
+ pub middle: Vec<f64>,
38
+ /// Lower channel
39
+ pub lower: Vec<f64>,
40
+ }
41
+
42
+ /// Average True Range (ATR)
43
+ ///
44
+ /// Measures market volatility by decomposing the entire range
45
+ /// of an asset price for a period.
46
+ ///
47
+ /// True Range = max(H-L, |H-PrevC|, |L-PrevC|)
48
+ /// ATR = EMA of True Range
49
+ ///
50
+ /// # Arguments
51
+ /// * `high` - High prices
52
+ /// * `low` - Low prices
53
+ /// * `close` - Close prices
54
+ /// * `period` - ATR period (default: 14)
55
+ ///
56
+ /// # Returns
57
+ /// An ATRResult containing ATR and True Range values.
58
+ pub fn atr(high: &[f64], low: &[f64], close: &[f64], period: usize) -> ATRResult {
59
+ if high.len() < 2 || period == 0 {
60
+ return ATRResult {
61
+ atr: Vec::new(),
62
+ tr: Vec::new(),
63
+ };
64
+ }
65
+
66
+ // Calculate True Range
67
+ let mut tr: Vec<f64> = vec![high[0] - low[0]]; // First TR is just H-L
68
+
69
+ for i in 1..high.len() {
70
+ let hl = high[i] - low[i];
71
+ let hpc = (high[i] - close[i - 1]).abs();
72
+ let lpc = (low[i] - close[i - 1]).abs();
73
+ tr.push(hl.max(hpc).max(lpc));
74
+ }
75
+
76
+ // Calculate ATR using EMA
77
+ let atr_values = super::ema(&tr, period);
78
+
79
+ ATRResult { atr: atr_values, tr }
80
+ }
81
+
82
+ /// Bollinger Bands
83
+ ///
84
+ /// A volatility indicator consisting of a middle band (SMA)
85
+ /// and two outer bands (standard deviations away).
86
+ ///
87
+ /// # Arguments
88
+ /// * `data` - Price data slice
89
+ /// * `period` - SMA period (default: 20)
90
+ /// * `std_dev_mult` - Standard deviation multiplier (default: 2.0)
91
+ ///
92
+ /// # Returns
93
+ /// A BollingerBandsResult containing upper, middle, lower bands, bandwidth, and %B.
94
+ pub fn bollinger_bands(data: &[f64], period: usize, std_dev_mult: f64) -> BollingerBandsResult {
95
+ if data.len() < period || period == 0 {
96
+ return BollingerBandsResult {
97
+ upper: Vec::new(),
98
+ middle: Vec::new(),
99
+ lower: Vec::new(),
100
+ bandwidth: Vec::new(),
101
+ percent_b: Vec::new(),
102
+ };
103
+ }
104
+
105
+ let middle = super::sma(data, period);
106
+
107
+ // Calculate rolling standard deviation
108
+ let std_devs: Vec<f64> = rolling(data, period, |slice| {
109
+ let avg = mean(slice);
110
+ let variance: f64 = slice.iter().map(|v| (v - avg).powi(2)).sum::<f64>()
111
+ / (slice.len() - 1) as f64;
112
+ variance.sqrt()
113
+ });
114
+
115
+ let mut upper: Vec<f64> = Vec::new();
116
+ let mut lower: Vec<f64> = Vec::new();
117
+ let mut bandwidth: Vec<f64> = Vec::new();
118
+ let mut percent_b: Vec<f64> = Vec::new();
119
+
120
+ for i in 0..middle.len() {
121
+ let mid = middle[i];
122
+ let sd = std_devs[i];
123
+ let up = mid + std_dev_mult * sd;
124
+ let low = mid - std_dev_mult * sd;
125
+
126
+ upper.push(up);
127
+ lower.push(low);
128
+ bandwidth.push(if mid > 0.0 { ((up - low) / mid) * 100.0 } else { 0.0 });
129
+
130
+ // Percent B: where is price relative to bands
131
+ let price_index = data.len() - middle.len() + i;
132
+ if (up - low).abs() > 1e-10 {
133
+ percent_b.push((data[price_index] - low) / (up - low));
134
+ } else {
135
+ percent_b.push(0.5);
136
+ }
137
+ }
138
+
139
+ BollingerBandsResult {
140
+ upper,
141
+ middle,
142
+ lower,
143
+ bandwidth,
144
+ percent_b,
145
+ }
146
+ }
147
+
148
+ /// Keltner Channels
149
+ ///
150
+ /// A volatility-based envelope using ATR above and below an EMA.
151
+ ///
152
+ /// # Arguments
153
+ /// * `high` - High prices
154
+ /// * `low` - Low prices
155
+ /// * `close` - Close prices
156
+ /// * `ema_period` - EMA period (default: 20)
157
+ /// * `atr_period` - ATR period (default: 10)
158
+ /// * `mult` - ATR multiplier (default: 2.0)
159
+ ///
160
+ /// # Returns
161
+ /// A KeltnerChannelsResult containing upper, middle, and lower channels.
162
+ pub fn keltner_channels(
163
+ high: &[f64],
164
+ low: &[f64],
165
+ close: &[f64],
166
+ ema_period: usize,
167
+ atr_period: usize,
168
+ mult: f64,
169
+ ) -> KeltnerChannelsResult {
170
+ if close.len() < ema_period.max(atr_period) || ema_period == 0 || atr_period == 0 {
171
+ return KeltnerChannelsResult {
172
+ upper: Vec::new(),
173
+ middle: Vec::new(),
174
+ lower: Vec::new(),
175
+ };
176
+ }
177
+
178
+ let middle = super::ema(close, ema_period);
179
+ let atr_result = atr(high, low, close, atr_period);
180
+ let atr_values = atr_result.atr;
181
+
182
+ // Align ATR with EMA
183
+ let atr_offset = close.len() - atr_values.len();
184
+ let ema_offset = close.len() - middle.len();
185
+
186
+ let upper: Vec<f64> = middle
187
+ .iter()
188
+ .enumerate()
189
+ .filter_map(|(i, &mid)| {
190
+ let atr_idx = i + (ema_offset - atr_offset);
191
+ if atr_idx < atr_values.len() {
192
+ Some(mid + mult * atr_values[atr_idx])
193
+ } else {
194
+ None
195
+ }
196
+ })
197
+ .collect();
198
+
199
+ let lower: Vec<f64> = middle
200
+ .iter()
201
+ .enumerate()
202
+ .filter_map(|(i, &mid)| {
203
+ let atr_idx = i + (ema_offset - atr_offset);
204
+ if atr_idx < atr_values.len() {
205
+ Some(mid - mult * atr_values[atr_idx])
206
+ } else {
207
+ None
208
+ }
209
+ })
210
+ .collect();
211
+
212
+ // Ensure all three arrays have the same length
213
+ let min_len = upper.len().min(lower.len());
214
+
215
+ KeltnerChannelsResult {
216
+ upper: upper[..min_len].to_vec(),
217
+ middle: middle[..min_len].to_vec(),
218
+ lower: lower[..min_len].to_vec(),
219
+ }
220
+ }
221
+
222
+ #[cfg(test)]
223
+ mod tests {
224
+ use super::*;
225
+
226
+ #[test]
227
+ fn test_atr() {
228
+ let high = vec![10.0, 12.0, 14.0, 16.0, 18.0];
229
+ let low = vec![8.0, 10.0, 11.0, 13.0, 15.0];
230
+ let close = vec![9.0, 11.0, 13.0, 15.0, 17.0];
231
+
232
+ let result = atr(&high, &low, &close, 3);
233
+ assert!(!result.tr.is_empty());
234
+ assert!(!result.atr.is_empty());
235
+
236
+ // First TR should be high[0] - low[0]
237
+ assert!((result.tr[0] - 2.0).abs() < 1e-10);
238
+ }
239
+
240
+ #[test]
241
+ fn test_bollinger_bands() {
242
+ let prices: Vec<f64> = (1..=30).map(|x| x as f64).collect();
243
+ let result = bollinger_bands(&prices, 20, 2.0);
244
+
245
+ assert!(!result.upper.is_empty());
246
+ assert!(!result.middle.is_empty());
247
+ assert!(!result.lower.is_empty());
248
+
249
+ // Upper should be above middle, lower should be below
250
+ for i in 0..result.middle.len() {
251
+ assert!(result.upper[i] > result.middle[i]);
252
+ assert!(result.lower[i] < result.middle[i]);
253
+ }
254
+ }
255
+
256
+ #[test]
257
+ fn test_keltner_channels() {
258
+ let high = vec![10.0, 12.0, 15.0, 14.0, 16.0, 18.0, 17.0, 19.0, 21.0, 20.0,
259
+ 22.0, 24.0, 23.0, 25.0, 27.0, 26.0, 28.0, 30.0, 29.0, 31.0];
260
+ let low = vec![8.0, 9.0, 11.0, 10.0, 12.0, 14.0, 13.0, 15.0, 17.0, 16.0,
261
+ 18.0, 20.0, 19.0, 21.0, 23.0, 22.0, 24.0, 26.0, 25.0, 27.0];
262
+ let close = vec![9.0, 11.0, 14.0, 12.0, 15.0, 17.0, 15.0, 18.0, 20.0, 18.0,
263
+ 21.0, 23.0, 21.0, 24.0, 26.0, 24.0, 27.0, 29.0, 27.0, 30.0];
264
+
265
+ let result = keltner_channels(&high, &low, &close, 10, 10, 2.0);
266
+ assert!(!result.upper.is_empty());
267
+ assert!(!result.middle.is_empty());
268
+ assert!(!result.lower.is_empty());
269
+ }
270
+ }
@@ -0,0 +1,213 @@
1
+ //! Volume Indicators
2
+ //!
3
+ //! Indicators based on trading volume analysis.
4
+
5
+ use crate::utils::{max, min};
6
+
7
+ /// On-Balance Volume (OBV)
8
+ ///
9
+ /// A cumulative indicator that adds volume on up days and subtracts
10
+ /// volume on down days, used to detect divergences with price.
11
+ ///
12
+ /// # Arguments
13
+ /// * `close` - Close prices
14
+ /// * `volume` - Volume data
15
+ ///
16
+ /// # Returns
17
+ /// A vector of OBV values.
18
+ pub fn obv(close: &[f64], volume: &[f64]) -> Vec<f64> {
19
+ if close.len() < 2 || volume.len() < 2 {
20
+ return Vec::new();
21
+ }
22
+
23
+ let mut result: Vec<f64> = vec![0.0];
24
+
25
+ for i in 1..close.len().min(volume.len()) {
26
+ if close[i] > close[i - 1] {
27
+ result.push(result[i - 1] + volume[i]);
28
+ } else if close[i] < close[i - 1] {
29
+ result.push(result[i - 1] - volume[i]);
30
+ } else {
31
+ result.push(result[i - 1]);
32
+ }
33
+ }
34
+
35
+ result
36
+ }
37
+
38
+ /// Money Flow Index (MFI)
39
+ ///
40
+ /// A momentum indicator using price and volume to identify
41
+ /// overbought/oversold conditions. Also known as Volume RSI.
42
+ ///
43
+ /// # Arguments
44
+ /// * `high` - High prices
45
+ /// * `low` - Low prices
46
+ /// * `close` - Close prices
47
+ /// * `volume` - Volume data
48
+ /// * `period` - MFI period (default: 14)
49
+ ///
50
+ /// # Returns
51
+ /// A vector of MFI values (0-100).
52
+ pub fn mfi(
53
+ high: &[f64],
54
+ low: &[f64],
55
+ close: &[f64],
56
+ volume: &[f64],
57
+ period: usize,
58
+ ) -> Vec<f64> {
59
+ if close.len() < period + 1 || period == 0 {
60
+ return Vec::new();
61
+ }
62
+
63
+ // Calculate typical prices and money flows
64
+ let typical_prices: Vec<f64> = close
65
+ .iter()
66
+ .enumerate()
67
+ .map(|(i, &c)| (high[i] + low[i] + c) / 3.0)
68
+ .collect();
69
+
70
+ let money_flows: Vec<f64> = typical_prices
71
+ .iter()
72
+ .enumerate()
73
+ .map(|(i, &tp)| tp * volume[i])
74
+ .collect();
75
+
76
+ let mut result: Vec<f64> = Vec::new();
77
+
78
+ for i in period..close.len() {
79
+ let mut positive_flow = 0.0;
80
+ let mut negative_flow = 0.0;
81
+
82
+ for j in (i + 1 - period)..=i {
83
+ if typical_prices[j] > typical_prices[j - 1] {
84
+ positive_flow += money_flows[j];
85
+ } else {
86
+ negative_flow += money_flows[j];
87
+ }
88
+ }
89
+
90
+ if negative_flow == 0.0 {
91
+ result.push(100.0);
92
+ } else {
93
+ let mf_ratio = positive_flow / negative_flow;
94
+ result.push(100.0 - 100.0 / (1.0 + mf_ratio));
95
+ }
96
+ }
97
+
98
+ result
99
+ }
100
+
101
+ /// Volume Profile
102
+ ///
103
+ /// Analyzes trading activity at specific price levels to identify
104
+ /// areas of high volume (support/resistance zones).
105
+ ///
106
+ /// # Arguments
107
+ /// * `high` - High prices
108
+ /// * `low` - Low prices
109
+ /// * `close` - Close prices
110
+ /// * `volume` - Volume data
111
+ /// * `levels` - Number of price levels to analyze
112
+ ///
113
+ /// # Returns
114
+ /// A vector of (price_level, volume) tuples.
115
+ pub fn volume_profile(
116
+ high: &[f64],
117
+ low: &[f64],
118
+ close: &[f64],
119
+ volume: &[f64],
120
+ levels: usize,
121
+ ) -> Vec<(f64, f64)> {
122
+ if high.is_empty() || low.is_empty() || levels == 0 {
123
+ return Vec::new();
124
+ }
125
+
126
+ let max_high = max(high);
127
+ let min_low = min(low);
128
+
129
+ if max_high.is_nan() || min_low.is_nan() {
130
+ return Vec::new();
131
+ }
132
+
133
+ let price_range = max_high - min_low;
134
+ let level_size = price_range / levels as f64;
135
+
136
+ // Initialize price levels with zero volume
137
+ let mut profile: Vec<(f64, f64)> = (0..=levels)
138
+ .map(|i| (min_low + i as f64 * level_size, 0.0))
139
+ .collect();
140
+
141
+ // Distribute volume across price levels
142
+ for i in 0..close.len().min(high.len()).min(low.len()).min(volume.len()) {
143
+ let h = high[i];
144
+ let l = low[i];
145
+ let v = volume[i];
146
+ let range = h - l;
147
+
148
+ if range > 0.0 {
149
+ // Distribute volume proportionally across levels within the candle's range
150
+ for (level, vol) in profile.iter_mut() {
151
+ if *level >= l && *level <= h {
152
+ *vol += v / levels as f64;
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ profile
159
+ }
160
+
161
+ #[cfg(test)]
162
+ mod tests {
163
+ use super::*;
164
+
165
+ #[test]
166
+ fn test_obv() {
167
+ let close = vec![10.0, 11.0, 10.5, 12.0, 11.5];
168
+ let volume = vec![100.0, 150.0, 120.0, 200.0, 180.0];
169
+
170
+ let result = obv(&close, &volume);
171
+
172
+ assert_eq!(result.len(), 5);
173
+ assert_eq!(result[0], 0.0); // Starting point
174
+ assert_eq!(result[1], 150.0); // Up day: +150
175
+ assert_eq!(result[2], 30.0); // Down day: 150 - 120
176
+ assert_eq!(result[3], 230.0); // Up day: 30 + 200
177
+ assert_eq!(result[4], 50.0); // Down day: 230 - 180
178
+ }
179
+
180
+ #[test]
181
+ fn test_mfi() {
182
+ let high = vec![10.0, 12.0, 14.0, 16.0, 18.0, 17.0, 19.0, 21.0, 20.0, 22.0,
183
+ 24.0, 23.0, 25.0, 27.0, 26.0, 28.0, 30.0, 29.0, 31.0, 33.0];
184
+ let low = vec![8.0, 9.0, 11.0, 13.0, 15.0, 14.0, 16.0, 18.0, 17.0, 19.0,
185
+ 21.0, 20.0, 22.0, 24.0, 23.0, 25.0, 27.0, 26.0, 28.0, 30.0];
186
+ let close = vec![9.0, 11.0, 13.0, 15.0, 17.0, 15.0, 18.0, 20.0, 18.0, 21.0,
187
+ 23.0, 21.0, 24.0, 26.0, 24.0, 27.0, 29.0, 27.0, 30.0, 32.0];
188
+ let volume = vec![100.0, 150.0, 120.0, 200.0, 180.0, 160.0, 220.0, 190.0, 170.0, 240.0,
189
+ 210.0, 180.0, 260.0, 230.0, 200.0, 280.0, 250.0, 220.0, 300.0, 270.0];
190
+
191
+ let result = mfi(&high, &low, &close, &volume, 14);
192
+
193
+ assert!(!result.is_empty());
194
+ // MFI should be between 0 and 100
195
+ for &val in &result {
196
+ assert!(val >= 0.0 && val <= 100.0);
197
+ }
198
+ }
199
+
200
+ #[test]
201
+ fn test_volume_profile() {
202
+ let high = vec![10.0, 12.0, 14.0];
203
+ let low = vec![8.0, 10.0, 12.0];
204
+ let close = vec![9.0, 11.0, 13.0];
205
+ let volume = vec![100.0, 150.0, 120.0];
206
+
207
+ let result = volume_profile(&high, &low, &close, &volume, 5);
208
+
209
+ assert!(!result.is_empty());
210
+ // Should have 6 levels (0 to 5 inclusive)
211
+ assert_eq!(result.len(), 6);
212
+ }
213
+ }
package/src/lib.rs ADDED
@@ -0,0 +1,130 @@
1
+ //! # Quant Rust - High-Performance Quantitative Finance Library
2
+ //!
3
+ //! A Rust library providing quantitative finance computations with FFI bindings for Bun/TypeScript.
4
+ //!
5
+ //! ## Modules
6
+ //! - `prediction`: Prediction market calculations (AMM, LMSR, Kelly criterion)
7
+ //! - `indicators`: Technical indicators (RSI, MACD, Bollinger Bands, etc.)
8
+ //! - `risk`: Risk management (VaR, CVaR, Sharpe ratio, etc.)
9
+ //! - `stats`: Statistical analysis (correlation, regression, distributions)
10
+ //! - `patterns`: Pattern recognition (candlestick, chart patterns, support/resistance)
11
+ //! - `utils`: Utility functions and helpers
12
+
13
+ pub mod types;
14
+ pub mod ffi;
15
+ pub mod utils;
16
+
17
+ #[cfg(feature = "prediction")]
18
+ pub mod prediction;
19
+
20
+ #[cfg(feature = "indicators")]
21
+ pub mod indicators;
22
+
23
+ #[cfg(feature = "risk")]
24
+ pub mod risk;
25
+
26
+ #[cfg(feature = "stats")]
27
+ pub mod stats;
28
+
29
+ #[cfg(feature = "patterns")]
30
+ pub mod patterns;
31
+
32
+ // Re-export types first (these are the primary definitions)
33
+ pub use types::{OHLCV, Signal, IndicatorResult, CandlePattern, PatternResult};
34
+
35
+ // Re-export utils
36
+ pub use utils::{sum, mean, median, variance, std_dev, min, max, rolling, round_to, clamp};
37
+
38
+ #[cfg(feature = "prediction")]
39
+ pub use prediction::{
40
+ Outcome,
41
+ odds::*,
42
+ kelly::KellyResult,
43
+ amm::AMMState,
44
+ lmsr::LMSRState,
45
+ };
46
+
47
+ #[cfg(feature = "indicators")]
48
+ pub use indicators::*;
49
+
50
+ #[cfg(feature = "risk")]
51
+ pub use risk::{VaRResult, DrawdownResult, SharpeResult, calculate_var, calculate_drawdown, calculate_sharpe_ratio, calculate_sortino_ratio, calculate_beta_alpha};
52
+
53
+ #[cfg(feature = "stats")]
54
+ pub use stats::{
55
+ // Types
56
+ RegressionResult,
57
+ MultipleRegressionResult,
58
+ DistributionStats,
59
+ Moments,
60
+ CorrelationResult,
61
+ RollingStats,
62
+ RollingRegressionResult,
63
+ TTestResult,
64
+ ADFResult,
65
+ AutocorrelationResult,
66
+ DoubleExponentialResult,
67
+ TripleExponentialResult,
68
+ // Correlation functions
69
+ correlation,
70
+ covariance,
71
+ pearson_correlation,
72
+ spearman_correlation,
73
+ correlation_with_p_value,
74
+ correlation_matrix,
75
+ // Regression functions
76
+ linear_regression,
77
+ multiple_regression,
78
+ // Distribution functions
79
+ distribution_stats,
80
+ moments,
81
+ distribution_statistics,
82
+ // Rolling statistics
83
+ rolling_stats,
84
+ rolling_correlation,
85
+ rolling_regression,
86
+ rolling_z_score,
87
+ // Hypothesis testing
88
+ one_sample_t_test,
89
+ two_sample_t_test,
90
+ adf_test,
91
+ // Distribution functions (CDF)
92
+ normal_cdf,
93
+ t_cdf,
94
+ gamma,
95
+ beta,
96
+ incomplete_beta,
97
+ // Time series
98
+ autocorrelation,
99
+ partial_autocorrelation,
100
+ exponential_smoothing,
101
+ double_exponential_smoothing,
102
+ triple_exponential_smoothing,
103
+ // Matrix operations
104
+ transpose,
105
+ matrix_multiply,
106
+ matrix_vector_multiply,
107
+ matrix_inverse,
108
+ determinant,
109
+ solve_linear_system,
110
+ percentile,
111
+ };
112
+
113
+ #[cfg(feature = "patterns")]
114
+ pub use patterns::{
115
+ // Config and candlestick detection
116
+ PatternConfig, detect_patterns,
117
+ // Support/Resistance
118
+ find_support_resistance, find_trend_lines,
119
+ SupportResistanceLevel, LevelType, TrendLine,
120
+ // Chart patterns
121
+ detect_all_patterns, detect_double_top, detect_double_bottom,
122
+ detect_head_and_shoulders, detect_inverse_head_and_shoulders,
123
+ detect_triangles, detect_gaps, detect_channels,
124
+ PatternMatch, PatternType, PatternDirection,
125
+ // Breakouts
126
+ detect_breakouts, detect_breakouts_from_levels,
127
+ detect_all_time_high_breakouts, detect_all_time_low_breakouts,
128
+ detect_consolidation_breakouts,
129
+ Breakout, BreakoutDirection,
130
+ };