1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Tier 1 indicators with streaming and batch APIs.
//!
//! # Examples
//! Compute several indicators over a generated candle series:
//!
//! ```rust
//! use mantis_ta::indicators::{
//! BollingerBands, Indicator, MACD, OBV, PivotPoints, RSI, SMA, Stochastic, VolumeSMA, ATR, EMA,
//! };
//! use mantis_ta::types::Candle;
//!
//! // Build a small candle series (60 bars) for the examples.
//! let candles: Vec<Candle> = (0..60)
//! .map(|i| Candle {
//! timestamp: i,
//! open: 100.0 + i as f64 * 0.1,
//! high: 100.2 + i as f64 * 0.1,
//! low: 99.8 + i as f64 * 0.1,
//! close:100.1 + i as f64 * 0.1,
//! volume: 1_000.0 + i as f64,
//! })
//! .collect();
//!
//! // Batch calculations (Vec<Option<_>> aligned to input)
//! let sma = SMA::new(20).calculate(&candles);
//! let ema = EMA::new(20).calculate(&candles);
//! let macd = MACD::new(12, 26, 9).calculate(&candles);
//! let rsi = RSI::new(14).calculate(&candles);
//! let stoch = Stochastic::new(14, 3).calculate(&candles);
//! let bb = BollingerBands::new(20, 2.0).calculate(&candles);
//! let atr = ATR::new(14).calculate(&candles);
//! let vol_sma = VolumeSMA::new(20).calculate(&candles);
//! let obv = OBV::new().calculate(&candles);
//! let pivot = PivotPoints::new().calculate(&candles);
//!
//! // All indicators produce `None` until their warmup is reached.
//! assert!(sma.iter().take(19).all(|v| v.is_none()));
//! assert!(ema.iter().take(19).all(|v| v.is_none()));
//! assert!(rsi.iter().take(13).all(|v| v.is_none()));
//! // Stochastic warmup = k + d - 1 (14 + 3 - 1 = 16)
//! assert!(stoch.iter().take(15).all(|v| v.is_none()));
//! assert!(stoch[15].is_some());
//! assert!(bb.iter().take(19).all(|v| v.is_none()));
//! assert!(atr.iter().take(13).all(|v| v.is_none()));
//! assert!(macd.iter().all(|v| v.is_none()) || macd.iter().any(|v| v.is_some()));
//! assert!(pivot.iter().all(|v| v.is_some()));
//! assert!(obv.iter().all(|v| v.is_some()));
//! assert!(vol_sma.iter().take(19).all(|v| v.is_none()));
//!
//! // Streaming example: re-use the same indicator instance per-bar
//! let mut rsi_stream = RSI::new(14);
//! for c in &candles {
//! let _ = rsi_stream.next(c);
//! }
//! ```
use crateCandle;
use Debug;
pub use ;
pub use OBV;
pub use ;
pub use ;
pub use ;
pub use ;
/// Core interface for all streaming technical indicators.
///
/// Implementations should be stateful and cheap to `next()`. The default
/// `calculate` helper performs a streaming pass over a slice of candles.
/// Extension of [`Indicator`] that supports state snapshot/restore.
// Re-export common types for convenience.
pub use crate;