1#![allow(non_camel_case_types)]
4
5#[macro_export]
7macro_rules! native_pointwise_1 {
8 ($name:ident, $op:expr) => {
9 #[derive(Debug, Clone, Default)]
10 pub struct $name;
11
12 impl $name {
13 pub fn new() -> Self {
14 Self
15 }
16 }
17
18 impl $crate::traits::Next<f64> for $name {
19 type Output = f64;
20
21 fn next(&mut self, input: f64) -> Self::Output {
22 ($op)(input)
23 }
24
25 fn next_batch(&mut self, inputs: &[f64]) -> Vec<Self::Output>
26 where
27 f64: Copy,
28 {
29 inputs.iter().map(|&x| ($op)(x)).collect()
30 }
31 }
32 };
33}
34
35#[macro_export]
37macro_rules! native_binary_2 {
38 ($name:ident, $op:expr) => {
39 #[derive(Debug, Clone, Default)]
40 pub struct $name;
41
42 impl $name {
43 pub fn new() -> Self {
44 Self
45 }
46 }
47
48 impl $crate::traits::Next<(f64, f64)> for $name {
49 type Output = f64;
50
51 fn next(&mut self, (a, b): (f64, f64)) -> Self::Output {
52 ($op)(a, b)
53 }
54
55 fn next_batch(&mut self, inputs: &[(f64, f64)]) -> Vec<Self::Output>
56 where
57 (f64, f64): Copy,
58 {
59 inputs.iter().map(|&(a, b)| ($op)(a, b)).collect()
60 }
61 }
62 };
63}
64
65#[macro_export]
67macro_rules! native_cdl {
68 ($name:ident, $talib_func:path) => {
69 #[derive(Debug, Clone)]
70
71 pub struct $name {
72 open: Vec<f64>,
73 high: Vec<f64>,
74 low: Vec<f64>,
75 close: Vec<f64>,
76 }
77
78 impl $name {
79 const MAX_WINDOW: usize = 32;
80
81 pub fn new() -> Self {
82 Self {
83 open: Vec::with_capacity(Self::MAX_WINDOW),
84 high: Vec::with_capacity(Self::MAX_WINDOW),
85 low: Vec::with_capacity(Self::MAX_WINDOW),
86 close: Vec::with_capacity(Self::MAX_WINDOW),
87 }
88 }
89
90 #[inline]
91 fn trim_window(o: &mut Vec<f64>, h: &mut Vec<f64>, l: &mut Vec<f64>, c: &mut Vec<f64>) {
92 let max = Self::MAX_WINDOW;
93 if o.len() > max {
94 let drop = o.len() - max;
95 o.drain(0..drop);
96 h.drain(0..drop);
97 l.drain(0..drop);
98 c.drain(0..drop);
99 }
100 }
101
102 #[inline]
103 fn last_signal(o: &[f64], h: &[f64], l: &[f64], c: &[f64]) -> f64 {
104 $talib_func(o, h, l, c)
105 .ok()
106 .and_then(|res| res.last().copied())
107 .unwrap_or(0) as f64
108 }
109 }
110
111 impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
112 type Output = f64;
113
114 fn next(&mut self, (open, high, low, close): (f64, f64, f64, f64)) -> Self::Output {
115 self.open.push(open);
116 self.high.push(high);
117 self.low.push(low);
118 self.close.push(close);
119 Self::trim_window(
120 &mut self.open,
121 &mut self.high,
122 &mut self.low,
123 &mut self.close,
124 );
125 Self::last_signal(&self.open, &self.high, &self.low, &self.close)
126 }
127
128 fn next_batch(&mut self, inputs: &[(f64, f64, f64, f64)]) -> Vec<Self::Output>
129 where
130 (f64, f64, f64, f64): Copy,
131 {
132 self.open.clear();
133 self.high.clear();
134 self.low.clear();
135 self.close.clear();
136 for &(o, h, l, c) in inputs {
137 self.open.push(o);
138 self.high.push(h);
139 self.low.push(l);
140 self.close.push(c);
141 }
142 $talib_func(&self.open, &self.high, &self.low, &self.close)
143 .unwrap_or_default()
144 .into_iter()
145 .map(|v| v as f64)
146 .collect()
147 }
148 }
149 };
150}
151
152#[macro_export]
153macro_rules! talib_cdl {
154 ($name:ident, $talib_func:path) => {
155 #[derive(Debug, Clone)]
156
157 pub struct $name {
158 history_open: Vec<f64>,
159 history_high: Vec<f64>,
160 history_low: Vec<f64>,
161 history_close: Vec<f64>,
162 }
163
164 impl $name {
165 pub fn new() -> Self {
166 Self {
167 history_open: Vec::new(),
168 history_high: Vec::new(),
169 history_low: Vec::new(),
170 history_close: Vec::new(),
171 }
172 }
173 }
174
175 impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
176 type Output = f64;
177
178 fn next(&mut self, (open, high, low, close): (f64, f64, f64, f64)) -> Self::Output {
179 self.history_open.push(open);
180 self.history_high.push(high);
181 self.history_low.push(low);
182 self.history_close.push(close);
183 if let Ok(res) = $talib_func(
184 &self.history_open,
185 &self.history_high,
186 &self.history_low,
187 &self.history_close,
188 ) {
189 *res.last().unwrap_or(&0) as f64
190 } else {
191 0.0
192 }
193 }
194
195 fn next_batch(&mut self, inputs: &[(f64, f64, f64, f64)]) -> Vec<Self::Output>
196 where
197 (f64, f64, f64, f64): Copy,
198 {
199 self.history_open.clear();
200 self.history_high.clear();
201 self.history_low.clear();
202 self.history_close.clear();
203 for &(o, h, l, c) in inputs {
204 self.history_open.push(o);
205 self.history_high.push(h);
206 self.history_low.push(l);
207 self.history_close.push(c);
208 }
209 $talib_func(
210 &self.history_open,
211 &self.history_high,
212 &self.history_low,
213 &self.history_close,
214 )
215 .unwrap_or_default()
216 .into_iter()
217 .map(|v| v as f64)
218 .collect()
219 }
220 }
221 };
222}
223
224#[macro_export]
225macro_rules! talib_1_in_1_out_i32 {
226 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
227 #[derive(Debug, Clone)]
228
229 pub struct $name {
230 $( pub $param: $ptype, )*
231 history: Vec<f64>,
232 }
233
234 impl $name {
235 pub fn new($( $param: $ptype ),*) -> Self {
236 Self {
237 $( $param, )*
238 history: Vec::new(),
239 }
240 }
241 }
242
243 impl $crate::traits::Next<f64> for $name {
244 type Output = f64;
245
246 fn next(&mut self, input: f64) -> Self::Output {
247 self.history.push(input);
248 if let Ok(res) = $talib_func(&self.history, $( self.$param.clone() ),*) {
249 *res.last().unwrap_or(&0) as f64
250 } else {
251 0.0
252 }
253 }
254 }
255 };
256}
257
258#[macro_export]
259macro_rules! talib_1_in_1_out_no_result {
260 ($name:ident, $talib_func:path) => {
261 #[derive(Debug, Clone)]
262
263 pub struct $name {
264 history: Vec<f64>,
265 }
266
267 impl $name {
268 pub fn new() -> Self {
269 Self {
270 history: Vec::new(),
271 }
272 }
273 }
274
275 impl $crate::traits::Next<f64> for $name {
276 type Output = f64;
277
278 fn next(&mut self, input: f64) -> Self::Output {
279 self.history.push(input);
280 let res = $talib_func(&self.history);
281 *res.last().unwrap_or(&f64::NAN)
282 }
283 }
284 };
285}
286
287#[macro_export]
288macro_rules! talib_1_in_1_out {
289 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
290 #[derive(Debug, Clone)]
291
292 pub struct $name {
293 $( pub $param: $ptype, )*
294 history: Vec<f64>,
295 }
296
297 impl $name {
298 pub fn new($( $param: $ptype ),*) -> Self {
299 Self {
300 $( $param, )*
301 history: Vec::new(),
302 }
303 }
304 }
305
306 impl $crate::traits::Next<f64> for $name {
307 type Output = f64;
308
309 fn next(&mut self, input: f64) -> Self::Output {
310 self.history.push(input);
311 let res = $talib_func(&self.history, $( self.$param.clone() ),*).unwrap_or_default();
312 *res.last().unwrap_or(&f64::NAN)
313 }
314
315 fn next_batch(&mut self, inputs: &[f64]) -> Vec<Self::Output>
316 where
317 f64: Copy,
318 {
319 self.history.clear();
320 self.history.extend_from_slice(inputs);
321 $talib_func(&self.history, $( self.$param.clone() ),*).unwrap_or_default()
322 }
323 }
324 };
325}
326
327#[macro_export]
328macro_rules! talib_2_in_1_out {
329 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
330 #[derive(Debug, Clone)]
331
332 pub struct $name {
333 $( pub $param: $ptype, )*
334 history_high: Vec<f64>,
335 history_low: Vec<f64>,
336 }
337
338 impl $name {
339 #[allow(clippy::too_many_arguments)]
340 pub fn new($( $param: $ptype ),*) -> Self {
341 Self {
342 $( $param, )*
343 history_high: Vec::new(),
344 history_low: Vec::new(),
345 }
346 }
347 }
348
349 impl $crate::traits::Next<(f64, f64)> for $name {
350 type Output = f64;
351
352 fn next(&mut self, (high, low): (f64, f64)) -> Self::Output {
353 self.history_high.push(high);
354 self.history_low.push(low);
355 let res = $talib_func(&self.history_high, &self.history_low, $( self.$param.clone() ),*).unwrap_or_default();
356 *res.last().unwrap_or(&f64::NAN)
357 }
358
359 fn next_batch(&mut self, inputs: &[(f64, f64)]) -> Vec<Self::Output>
360 where
361 (f64, f64): Copy,
362 {
363 self.history_high.clear();
364 self.history_low.clear();
365 for &(h, l) in inputs {
366 self.history_high.push(h);
367 self.history_low.push(l);
368 }
369 $talib_func(&self.history_high, &self.history_low, $( self.$param.clone() ),*).unwrap_or_default()
370 }
371 }
372 };
373}
374
375#[macro_export]
376macro_rules! talib_1_in_2_out {
377 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
378 #[derive(Debug, Clone)]
379
380 pub struct $name {
381 $( pub $param: $ptype, )*
382 history: Vec<f64>,
383 }
384
385 impl $name {
386 pub fn new($( $param: $ptype ),*) -> Self {
387 Self {
388 $( $param, )*
389 history: Vec::new(),
390 }
391 }
392 }
393
394 impl $crate::traits::Next<f64> for $name {
395 type Output = (f64, f64);
396
397 fn next(&mut self, input: f64) -> Self::Output {
398 self.history.push(input);
399 if let Ok((res1, res2)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
400 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
401 } else {
402 (f64::NAN, f64::NAN)
403 }
404 }
405
406 fn next_batch(&mut self, inputs: &[f64]) -> Vec<Self::Output>
407 where
408 f64: Copy,
409 {
410 self.history.clear();
411 self.history.extend_from_slice(inputs);
412 if let Ok((r1, r2)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
413 r1.into_iter().zip(r2).map(|(a, b)| (a, b)).collect()
414 } else {
415 vec![(f64::NAN, f64::NAN); inputs.len()]
416 }
417 }
418 }
419 };
420}
421
422#[macro_export]
423macro_rules! talib_1_in_3_out {
424 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
425 #[derive(Debug, Clone)]
426
427 pub struct $name {
428 $( pub $param: $ptype, )*
429 history: Vec<f64>,
430 }
431
432 impl $name {
433 pub fn new($( $param: $ptype ),*) -> Self {
434 Self {
435 $( $param, )*
436 history: Vec::new(),
437 }
438 }
439 }
440
441 impl $crate::traits::Next<f64> for $name {
442 type Output = (f64, f64, f64);
443
444 fn next(&mut self, input: f64) -> Self::Output {
445 self.history.push(input);
446 if let Ok((res1, res2, res3)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
447 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN), *res3.last().unwrap_or(&f64::NAN))
448 } else {
449 (f64::NAN, f64::NAN, f64::NAN)
450 }
451 }
452
453 fn next_batch(&mut self, inputs: &[f64]) -> Vec<Self::Output>
454 where
455 f64: Copy,
456 {
457 self.history.clear();
458 self.history.extend_from_slice(inputs);
459 if let Ok((r1, r2, r3)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
460 r1.into_iter()
461 .zip(r2)
462 .zip(r3)
463 .map(|((a, b), c)| (a, b, c))
464 .collect()
465 } else {
466 vec![(f64::NAN, f64::NAN, f64::NAN); inputs.len()]
467 }
468 }
469 }
470 };
471}
472
473#[macro_export]
474macro_rules! talib_2_in_2_out {
475 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
476 #[derive(Debug, Clone)]
477
478 pub struct $name {
479 $( pub $param: $ptype, )*
480 history_1: Vec<f64>,
481 history_2: Vec<f64>,
482 }
483
484 impl $name {
485 pub fn new($( $param: $ptype ),*) -> Self {
486 Self {
487 $( $param, )*
488 history_1: Vec::new(),
489 history_2: Vec::new(),
490 }
491 }
492 }
493
494 impl $crate::traits::Next<(f64, f64)> for $name {
495 type Output = (f64, f64);
496
497 fn next(&mut self, (in1, in2): (f64, f64)) -> Self::Output {
498 self.history_1.push(in1);
499 self.history_2.push(in2);
500 if let Ok((res1, res2)) = $talib_func(&self.history_1, &self.history_2, $( self.$param.clone() ),*) {
501 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
502 } else {
503 (f64::NAN, f64::NAN)
504 }
505 }
506
507 fn next_batch(&mut self, inputs: &[(f64, f64)]) -> Vec<Self::Output>
508 where
509 (f64, f64): Copy,
510 {
511 self.history_1.clear();
512 self.history_2.clear();
513 for &(a, b) in inputs {
514 self.history_1.push(a);
515 self.history_2.push(b);
516 }
517 if let Ok((r1, r2)) = $talib_func(&self.history_1, &self.history_2, $( self.$param.clone() ),*) {
518 r1.into_iter().zip(r2).map(|(x, y)| (x, y)).collect()
519 } else {
520 vec![(f64::NAN, f64::NAN); inputs.len()]
521 }
522 }
523 }
524 };
525}
526
527#[macro_export]
528macro_rules! talib_3_in_1_out {
529 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
530 #[derive(Debug, Clone)]
531
532 pub struct $name {
533 $( pub $param: $ptype, )*
534 history_high: Vec<f64>,
535 history_low: Vec<f64>,
536 history_close: Vec<f64>,
537 }
538
539 impl $name {
540 pub fn new($( $param: $ptype ),*) -> Self {
541 Self {
542 $( $param, )*
543 history_high: Vec::new(),
544 history_low: Vec::new(),
545 history_close: Vec::new(),
546 }
547 }
548 }
549
550 impl $crate::traits::Next<(f64, f64, f64)> for $name {
551 type Output = f64;
552
553 fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
554 self.history_high.push(high);
555 self.history_low.push(low);
556 self.history_close.push(close);
557 let res = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*).unwrap_or_default();
558 *res.last().unwrap_or(&f64::NAN)
559 }
560
561 fn next_batch(&mut self, inputs: &[(f64, f64, f64)]) -> Vec<Self::Output>
562 where
563 (f64, f64, f64): Copy,
564 {
565 self.history_high.clear();
566 self.history_low.clear();
567 self.history_close.clear();
568 for &(h, l, c) in inputs {
569 self.history_high.push(h);
570 self.history_low.push(l);
571 self.history_close.push(c);
572 }
573 $talib_func(
574 &self.history_high,
575 &self.history_low,
576 &self.history_close,
577 $( self.$param.clone() ),*
578 )
579 .unwrap_or_default()
580 }
581 }
582 };
583}
584
585#[macro_export]
586macro_rules! talib_3_in_2_out {
587 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
588 #[derive(Debug, Clone)]
589
590 pub struct $name {
591 $( pub $param: $ptype, )*
592 history_high: Vec<f64>,
593 history_low: Vec<f64>,
594 history_close: Vec<f64>,
595 }
596
597 impl $name {
598 pub fn new($( $param: $ptype ),*) -> Self {
599 Self {
600 $( $param, )*
601 history_high: Vec::new(),
602 history_low: Vec::new(),
603 history_close: Vec::new(),
604 }
605 }
606 }
607
608 impl $crate::traits::Next<(f64, f64, f64)> for $name {
609 type Output = (f64, f64);
610
611 fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
612 self.history_high.push(high);
613 self.history_low.push(low);
614 self.history_close.push(close);
615 if let Ok((res1, res2)) = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*) {
616 (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
617 } else {
618 (f64::NAN, f64::NAN)
619 }
620 }
621
622 fn next_batch(&mut self, inputs: &[(f64, f64, f64)]) -> Vec<Self::Output>
623 where
624 (f64, f64, f64): Copy,
625 {
626 self.history_high.clear();
627 self.history_low.clear();
628 self.history_close.clear();
629 for &(h, l, c) in inputs {
630 self.history_high.push(h);
631 self.history_low.push(l);
632 self.history_close.push(c);
633 }
634 if let Ok((r1, r2)) = $talib_func(
635 &self.history_high,
636 &self.history_low,
637 &self.history_close,
638 $( self.$param.clone() ),*
639 ) {
640 r1.into_iter().zip(r2).map(|(a, b)| (a, b)).collect()
641 } else {
642 vec![(f64::NAN, f64::NAN); inputs.len()]
643 }
644 }
645 }
646 };
647}
648
649#[macro_export]
650macro_rules! talib_4_in_1_out {
651 ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
652 #[derive(Debug, Clone)]
653
654 pub struct $name {
655 $( pub $param: $ptype, )*
656 history_1: Vec<f64>,
657 history_2: Vec<f64>,
658 history_3: Vec<f64>,
659 history_4: Vec<f64>,
660 }
661
662 impl $name {
663 pub fn new($( $param: $ptype ),*) -> Self {
664 Self {
665 $( $param, )*
666 history_1: Vec::new(),
667 history_2: Vec::new(),
668 history_3: Vec::new(),
669 history_4: Vec::new(),
670 }
671 }
672 }
673
674 impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
675 type Output = f64;
676
677 fn next(&mut self, (in1, in2, in3, in4): (f64, f64, f64, f64)) -> Self::Output {
678 self.history_1.push(in1);
679 self.history_2.push(in2);
680 self.history_3.push(in3);
681 self.history_4.push(in4);
682 let res = $talib_func(&self.history_1, &self.history_2, &self.history_3, &self.history_4, $( self.$param.clone() ),*).unwrap_or_default();
683 *res.last().unwrap_or(&f64::NAN)
684 }
685
686 fn next_batch(&mut self, inputs: &[(f64, f64, f64, f64)]) -> Vec<Self::Output>
687 where
688 (f64, f64, f64, f64): Copy,
689 {
690 self.history_1.clear();
691 self.history_2.clear();
692 self.history_3.clear();
693 self.history_4.clear();
694 for &(a, b, c, d) in inputs {
695 self.history_1.push(a);
696 self.history_2.push(b);
697 self.history_3.push(c);
698 self.history_4.push(d);
699 }
700 $talib_func(
701 &self.history_1,
702 &self.history_2,
703 &self.history_3,
704 &self.history_4,
705 $( self.$param.clone() ),*
706 )
707 .unwrap_or_default()
708 }
709 }
710 };
711}