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