1#[macro_export]
2macro_rules! talib_cdl {
3 ($name:ident, $talib_func:path) => {
4 #[derive(Debug, Clone)]
5 #[allow(non_camel_case_types)]
6 pub struct $name {
7 history_open: Vec<f64>,
8 history_high: Vec<f64>,
9 history_low: Vec<f64>,
10 history_close: Vec<f64>,
11 }
12
13 impl $name {
14 pub fn new() -> Self {
15 Self {
16 history_open: Vec::new(),
17 history_high: Vec::new(),
18 history_low: Vec::new(),
19 history_close: Vec::new(),
20 }
21 }
22 }
23
24 impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
25 type Output = f64;
26
27 fn next(&mut self, (open, high, low, close): (f64, f64, f64, f64)) -> Self::Output {
28 self.history_open.push(open);
29 self.history_high.push(high);
30 self.history_low.push(low);
31 self.history_close.push(close);
32 if let Ok(res) = $talib_func(
33 &self.history_open,
34 &self.history_high,
35 &self.history_low,
36 &self.history_close,
37 ) {
38 *res.last().unwrap_or(&0) as f64
39 } else {
40 0.0
41 }
42 }
43 }
44 };
45}
46
47#[macro_export]
48macro_rules! talib_1_in_1_out_i32 {
49 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
50 #[derive(Debug, Clone)]
51 #[allow(non_camel_case_types)]
52 pub struct $name {
53 $( pub $param: $ptype, )*
54 history: Vec<f64>,
55 }
56
57 impl $name {
58 pub fn new($( $param: $ptype ),*) -> Self {
59 Self {
60 $( $param, )*
61 history: Vec::new(),
62 }
63 }
64 }
65
66 impl $crate::traits::Next<f64> for $name {
67 type Output = f64;
68
69 fn next(&mut self, input: f64) -> Self::Output {
70 self.history.push(input);
71 if let Ok(res) = $talib_func(&self.history, $( self.$param.clone() ),*) {
72 *res.last().unwrap_or(&0) as f64
73 } else {
74 0.0
75 }
76 }
77 }
78 };
79}
80
81#[macro_export]
82macro_rules! talib_1_in_1_out_no_result {
83 ($name:ident, $talib_func:path) => {
84 #[derive(Debug, Clone)]
85 #[allow(non_camel_case_types)]
86 pub struct $name {
87 history: Vec<f64>,
88 }
89
90 impl $name {
91 pub fn new() -> Self {
92 Self {
93 history: Vec::new(),
94 }
95 }
96 }
97
98 impl $crate::traits::Next<f64> for $name {
99 type Output = f64;
100
101 fn next(&mut self, input: f64) -> Self::Output {
102 self.history.push(input);
103 let res = $talib_func(&self.history);
104 *res.last().unwrap_or(&f64::NAN)
105 }
106 }
107 };
108}
109
110#[macro_export]
111macro_rules! talib_1_in_1_out {
112 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
113 #[derive(Debug, Clone)]
114 #[allow(non_camel_case_types)]
115 pub struct $name {
116 $( pub $param: $ptype, )*
117 history: Vec<f64>,
118 }
119
120 impl $name {
121 pub fn new($( $param: $ptype ),*) -> Self {
122 Self {
123 $( $param, )*
124 history: Vec::new(),
125 }
126 }
127 }
128
129 impl $crate::traits::Next<f64> for $name {
130 type Output = f64;
131
132 fn next(&mut self, input: f64) -> Self::Output {
133 self.history.push(input);
134 let res = $talib_func(&self.history, $( self.$param.clone() ),*).unwrap_or_default();
135 *res.last().unwrap_or(&f64::NAN)
136 }
137 }
138 };
139}
140
141#[macro_export]
142macro_rules! talib_2_in_1_out {
143 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
144 #[derive(Debug, Clone)]
145 #[allow(non_camel_case_types)]
146 pub struct $name {
147 $( pub $param: $ptype, )*
148 history_high: Vec<f64>,
149 history_low: Vec<f64>,
150 }
151
152 impl $name {
153 #[allow(clippy::too_many_arguments)]
154 pub fn new($( $param: $ptype ),*) -> Self {
155 Self {
156 $( $param, )*
157 history_high: Vec::new(),
158 history_low: Vec::new(),
159 }
160 }
161 }
162
163 impl $crate::traits::Next<(f64, f64)> for $name {
164 type Output = f64;
165
166 fn next(&mut self, (high, low): (f64, f64)) -> Self::Output {
167 self.history_high.push(high);
168 self.history_low.push(low);
169 let res = $talib_func(&self.history_high, &self.history_low, $( self.$param.clone() ),*).unwrap_or_default();
170 *res.last().unwrap_or(&f64::NAN)
171 }
172 }
173 };
174}
175
176#[macro_export]
177macro_rules! talib_1_in_2_out {
178 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
179 #[derive(Debug, Clone)]
180 #[allow(non_camel_case_types)]
181 pub struct $name {
182 $( pub $param: $ptype, )*
183 history: Vec<f64>,
184 }
185
186 impl $name {
187 pub fn new($( $param: $ptype ),*) -> Self {
188 Self {
189 $( $param, )*
190 history: Vec::new(),
191 }
192 }
193 }
194
195 impl $crate::traits::Next<f64> for $name {
196 type Output = (f64, f64);
197
198 fn next(&mut self, input: f64) -> Self::Output {
199 self.history.push(input);
200 if let Ok((res1, res2)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
201 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
202 } else {
203 (f64::NAN, f64::NAN)
204 }
205 }
206 }
207 };
208}
209
210#[macro_export]
211macro_rules! talib_1_in_3_out {
212 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
213 #[derive(Debug, Clone)]
214 #[allow(non_camel_case_types)]
215 pub struct $name {
216 $( pub $param: $ptype, )*
217 history: Vec<f64>,
218 }
219
220 impl $name {
221 pub fn new($( $param: $ptype ),*) -> Self {
222 Self {
223 $( $param, )*
224 history: Vec::new(),
225 }
226 }
227 }
228
229 impl $crate::traits::Next<f64> for $name {
230 type Output = (f64, f64, f64);
231
232 fn next(&mut self, input: f64) -> Self::Output {
233 self.history.push(input);
234 if let Ok((res1, res2, res3)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
235 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN), *res3.last().unwrap_or(&f64::NAN))
236 } else {
237 (f64::NAN, f64::NAN, f64::NAN)
238 }
239 }
240 }
241 };
242}
243
244#[macro_export]
245macro_rules! talib_2_in_2_out {
246 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
247 #[derive(Debug, Clone)]
248 #[allow(non_camel_case_types)]
249 pub struct $name {
250 $( pub $param: $ptype, )*
251 history_1: Vec<f64>,
252 history_2: Vec<f64>,
253 }
254
255 impl $name {
256 pub fn new($( $param: $ptype ),*) -> Self {
257 Self {
258 $( $param, )*
259 history_1: Vec::new(),
260 history_2: Vec::new(),
261 }
262 }
263 }
264
265 impl $crate::traits::Next<(f64, f64)> for $name {
266 type Output = (f64, f64);
267
268 fn next(&mut self, (in1, in2): (f64, f64)) -> Self::Output {
269 self.history_1.push(in1);
270 self.history_2.push(in2);
271 if let Ok((res1, res2)) = $talib_func(&self.history_1, &self.history_2, $( self.$param.clone() ),*) {
272 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
273 } else {
274 (f64::NAN, f64::NAN)
275 }
276 }
277 }
278 };
279}
280
281#[macro_export]
282macro_rules! talib_3_in_1_out {
283 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
284 #[derive(Debug, Clone)]
285 #[allow(non_camel_case_types)]
286 pub struct $name {
287 $( pub $param: $ptype, )*
288 history_high: Vec<f64>,
289 history_low: Vec<f64>,
290 history_close: Vec<f64>,
291 }
292
293 impl $name {
294 pub fn new($( $param: $ptype ),*) -> Self {
295 Self {
296 $( $param, )*
297 history_high: Vec::new(),
298 history_low: Vec::new(),
299 history_close: Vec::new(),
300 }
301 }
302 }
303
304 impl $crate::traits::Next<(f64, f64, f64)> for $name {
305 type Output = f64;
306
307 fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
308 self.history_high.push(high);
309 self.history_low.push(low);
310 self.history_close.push(close);
311 let res = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*).unwrap_or_default();
312 *res.last().unwrap_or(&f64::NAN)
313 }
314 }
315 };
316}
317
318#[macro_export]
319macro_rules! talib_3_in_2_out {
320 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
321 #[derive(Debug, Clone)]
322 #[allow(non_camel_case_types)]
323 pub struct $name {
324 $( pub $param: $ptype, )*
325 history_high: Vec<f64>,
326 history_low: Vec<f64>,
327 history_close: Vec<f64>,
328 }
329
330 impl $name {
331 pub fn new($( $param: $ptype ),*) -> Self {
332 Self {
333 $( $param, )*
334 history_high: Vec::new(),
335 history_low: Vec::new(),
336 history_close: Vec::new(),
337 }
338 }
339 }
340
341 impl $crate::traits::Next<(f64, f64, f64)> for $name {
342 type Output = (f64, f64);
343
344 fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
345 self.history_high.push(high);
346 self.history_low.push(low);
347 self.history_close.push(close);
348 if let Ok((res1, res2)) = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*) {
349 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
350 } else {
351 (f64::NAN, f64::NAN)
352 }
353 }
354 }
355 };
356}
357
358#[macro_export]
359macro_rules! talib_4_in_1_out {
360 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
361 #[derive(Debug, Clone)]
362 #[allow(non_camel_case_types)]
363 pub struct $name {
364 $( pub $param: $ptype, )*
365 history_1: Vec<f64>,
366 history_2: Vec<f64>,
367 history_3: Vec<f64>,
368 history_4: Vec<f64>,
369 }
370
371 impl $name {
372 pub fn new($( $param: $ptype ),*) -> Self {
373 Self {
374 $( $param, )*
375 history_1: Vec::new(),
376 history_2: Vec::new(),
377 history_3: Vec::new(),
378 history_4: Vec::new(),
379 }
380 }
381 }
382
383 impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
384 type Output = f64;
385
386 fn next(&mut self, (in1, in2, in3, in4): (f64, f64, f64, f64)) -> Self::Output {
387 self.history_1.push(in1);
388 self.history_2.push(in2);
389 self.history_3.push(in3);
390 self.history_4.push(in4);
391 let res = $talib_func(&self.history_1, &self.history_2, &self.history_3, &self.history_4, $( self.$param.clone() ),*).unwrap_or_default();
392 *res.last().unwrap_or(&f64::NAN)
393 }
394 }
395 };
396}