Skip to main content

quantwave_core/indicators/
talib_wrapper.rs

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}