quantaxis_rs/indicators/
bollinger_bands.rs1use std::fmt;
2
3use crate::errors::*;
4use crate::indicators::StandardDeviation as Sd;
5use crate::{Close, Next, Reset};
6
7#[derive(Debug, Clone)]
47pub struct BollingerBands {
48 length: u32,
49 multiplier: f64,
50 sd: Sd,
51}
52
53#[derive(Debug, Clone, PartialEq)]
54pub struct BollingerBandsOutput {
55 pub average: f64,
56 pub upper: f64,
57 pub lower: f64,
58}
59
60impl BollingerBands {
61 pub fn new(length: u32, multiplier: f64) -> Result<Self> {
62 if multiplier <= 0.0 {
63 return Err(Error::from_kind(ErrorKind::InvalidParameter));
64 }
65 Ok(Self {
66 length,
67 multiplier,
68 sd: Sd::new(length)?,
69 })
70 }
71
72 pub fn length(&self) -> u32 {
73 self.length
74 }
75
76 pub fn multiplier(&self) -> f64 {
77 self.multiplier
78 }
79}
80
81impl Next<f64> for BollingerBands {
82 type Output = BollingerBandsOutput;
83
84 fn next(&mut self, input: f64) -> Self::Output {
85 let sd = self.sd.next(input);
86 let mean = self.sd.mean();
87
88 Self::Output {
89 average: mean,
90 upper: mean + sd * self.multiplier,
91 lower: mean - sd * self.multiplier,
92 }
93 }
94}
95
96impl<'a, T: Close> Next<&'a T> for BollingerBands {
97 type Output = BollingerBandsOutput;
98
99 fn next(&mut self, input: &'a T) -> Self::Output {
100 self.next(input.close())
101 }
102}
103
104impl Reset for BollingerBands {
105 fn reset(&mut self) {
106 self.sd.reset();
107 }
108}
109
110impl Default for BollingerBands {
111 fn default() -> Self {
112 Self::new(9, 2_f64).unwrap()
113 }
114}
115
116impl fmt::Display for BollingerBands {
117 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118 write!(f, "BB({}, {})", self.length, self.multiplier)
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125 use crate::test_helper::*;
126 macro_rules! test_indicator {
127 ($i:tt) => {
128 #[test]
129 fn test_indicator() {
130 let bar = Bar::new();
131
132 let mut indicator = $i::default();
134
135 let first_output = indicator.next(12.3);
137
138 indicator.next(&bar);
140
141 indicator.reset();
143 assert_eq!(indicator.next(12.3), first_output);
144
145 format!("{}", indicator);
147 }
148 };
149 }
150 test_indicator!(BollingerBands);
151
152 #[test]
153 fn test_new() {
154 assert!(BollingerBands::new(0, 2_f64).is_err());
155 assert!(BollingerBands::new(1, 2_f64).is_ok());
156 assert!(BollingerBands::new(2, 2_f64).is_ok());
157 }
158
159 #[test]
160 fn test_next() {
161 let mut bb = BollingerBands::new(3, 2.0_f64).unwrap();
162
163 let a = bb.next(2.0);
164 let b = bb.next(5.0);
165 let c = bb.next(1.0);
166 let d = bb.next(6.25);
167
168 assert_eq!(round(a.average), 2.0);
169 assert_eq!(round(b.average), 3.5);
170 assert_eq!(round(c.average), 2.667);
171 assert_eq!(round(d.average), 4.083);
172
173 assert_eq!(round(a.upper), 2.0);
174 assert_eq!(round(b.upper), 6.5);
175 assert_eq!(round(c.upper), 6.066);
176 assert_eq!(round(d.upper), 8.562);
177
178 assert_eq!(round(a.lower), 2.0);
179 assert_eq!(round(b.lower), 0.5);
180 assert_eq!(round(c.lower), -0.733);
181 assert_eq!(round(d.lower), -0.395);
182 }
183
184 #[test]
185 fn test_reset() {
186 let mut bb = BollingerBands::new(5, 2.0_f64).unwrap();
187
188 let out = bb.next(3.0);
189
190 assert_eq!(out.average, 3.0);
191 assert_eq!(out.upper, 3.0);
192 assert_eq!(out.lower, 3.0);
193
194 bb.next(2.5);
195 bb.next(3.5);
196 bb.next(4.0);
197
198 let out = bb.next(2.0);
199
200 assert_eq!(out.average, 3.0);
201 assert_eq!(round(out.upper), 4.414);
202 assert_eq!(round(out.lower), 1.586);
203
204 bb.reset();
205 let out = bb.next(3.0);
206 assert_eq!(out.average, 3.0);
207 assert_eq!(out.upper, 3.0);
208 assert_eq!(out.lower, 3.0);
209 }
210
211 #[test]
212 fn test_default() {
213 BollingerBands::default();
214 }
215
216 #[test]
217 fn test_display() {
218 let bb = BollingerBands::new(10, 3.0_f64).unwrap();
219 println!("{:#?}", bb);
220 assert_eq!(format!("{}", bb), "BB(10, 3)");
221 }
222}