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            pub fn new($( $param: $ptype ),*) -> Self {
154                Self {
155                    $( $param, )*
156                    history_high: Vec::new(),
157                    history_low: Vec::new(),
158                }
159            }
160        }
161
162        impl $crate::traits::Next<(f64, f64)> for $name {
163            type Output = f64;
164
165            fn next(&mut self, (high, low): (f64, f64)) -> Self::Output {
166                self.history_high.push(high);
167                self.history_low.push(low);
168                let res = $talib_func(&self.history_high, &self.history_low, $( self.$param.clone() ),*).unwrap_or_default();
169                *res.last().unwrap_or(&f64::NAN)
170            }
171        }
172    };
173}
174
175#[macro_export]
176macro_rules! talib_1_in_2_out {
177    ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
178        #[derive(Debug, Clone)]
179        #[allow(non_camel_case_types)]
180        pub struct $name {
181            $( pub $param: $ptype, )*
182            history: Vec<f64>,
183        }
184
185        impl $name {
186            pub fn new($( $param: $ptype ),*) -> Self {
187                Self {
188                    $( $param, )*
189                    history: Vec::new(),
190                }
191            }
192        }
193
194        impl $crate::traits::Next<f64> for $name {
195            type Output = (f64, f64);
196
197            fn next(&mut self, input: f64) -> Self::Output {
198                self.history.push(input);
199                if let Ok((res1, res2)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
200                    (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
201                } else {
202                    (f64::NAN, f64::NAN)
203                }
204            }
205        }
206    };
207}
208
209#[macro_export]
210macro_rules! talib_1_in_3_out {
211    ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
212        #[derive(Debug, Clone)]
213        #[allow(non_camel_case_types)]
214        pub struct $name {
215            $( pub $param: $ptype, )*
216            history: Vec<f64>,
217        }
218
219        impl $name {
220            pub fn new($( $param: $ptype ),*) -> Self {
221                Self {
222                    $( $param, )*
223                    history: Vec::new(),
224                }
225            }
226        }
227
228        impl $crate::traits::Next<f64> for $name {
229            type Output = (f64, f64, f64);
230
231            fn next(&mut self, input: f64) -> Self::Output {
232                self.history.push(input);
233                if let Ok((res1, res2, res3)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
234                    (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN), *res3.last().unwrap_or(&f64::NAN))
235                } else {
236                    (f64::NAN, f64::NAN, f64::NAN)
237                }
238            }
239        }
240    };
241}
242
243#[macro_export]
244macro_rules! talib_2_in_2_out {
245    ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
246        #[derive(Debug, Clone)]
247        #[allow(non_camel_case_types)]
248        pub struct $name {
249            $( pub $param: $ptype, )*
250            history_1: Vec<f64>,
251            history_2: Vec<f64>,
252        }
253
254        impl $name {
255            pub fn new($( $param: $ptype ),*) -> Self {
256                Self {
257                    $( $param, )*
258                    history_1: Vec::new(),
259                    history_2: Vec::new(),
260                }
261            }
262        }
263
264        impl $crate::traits::Next<(f64, f64)> for $name {
265            type Output = (f64, f64);
266
267            fn next(&mut self, (in1, in2): (f64, f64)) -> Self::Output {
268                self.history_1.push(in1);
269                self.history_2.push(in2);
270                if let Ok((res1, res2)) = $talib_func(&self.history_1, &self.history_2, $( self.$param.clone() ),*) {
271                    (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
272                } else {
273                    (f64::NAN, f64::NAN)
274                }
275            }
276        }
277    };
278}
279
280#[macro_export]
281macro_rules! talib_3_in_1_out {
282    ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
283        #[derive(Debug, Clone)]
284        #[allow(non_camel_case_types)]
285        pub struct $name {
286            $( pub $param: $ptype, )*
287            history_high: Vec<f64>,
288            history_low: Vec<f64>,
289            history_close: Vec<f64>,
290        }
291
292        impl $name {
293            pub fn new($( $param: $ptype ),*) -> Self {
294                Self {
295                    $( $param, )*
296                    history_high: Vec::new(),
297                    history_low: Vec::new(),
298                    history_close: Vec::new(),
299                }
300            }
301        }
302
303        impl $crate::traits::Next<(f64, f64, f64)> for $name {
304            type Output = f64;
305
306            fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
307                self.history_high.push(high);
308                self.history_low.push(low);
309                self.history_close.push(close);
310                let res = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*).unwrap_or_default();
311                *res.last().unwrap_or(&f64::NAN)
312            }
313        }
314    };
315}
316
317#[macro_export]
318macro_rules! talib_3_in_2_out {
319    ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
320        #[derive(Debug, Clone)]
321        #[allow(non_camel_case_types)]
322        pub struct $name {
323            $( pub $param: $ptype, )*
324            history_high: Vec<f64>,
325            history_low: Vec<f64>,
326            history_close: Vec<f64>,
327        }
328
329        impl $name {
330            pub fn new($( $param: $ptype ),*) -> Self {
331                Self {
332                    $( $param, )*
333                    history_high: Vec::new(),
334                    history_low: Vec::new(),
335                    history_close: Vec::new(),
336                }
337            }
338        }
339
340        impl $crate::traits::Next<(f64, f64, f64)> for $name {
341            type Output = (f64, f64);
342
343            fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
344                self.history_high.push(high);
345                self.history_low.push(low);
346                self.history_close.push(close);
347                if let Ok((res1, res2)) = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*) {
348                    (*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
349                } else {
350                    (f64::NAN, f64::NAN)
351                }
352            }
353        }
354    };
355}
356
357#[macro_export]
358macro_rules! talib_4_in_1_out {
359    ($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
360        #[derive(Debug, Clone)]
361        #[allow(non_camel_case_types)]
362        pub struct $name {
363            $( pub $param: $ptype, )*
364            history_1: Vec<f64>,
365            history_2: Vec<f64>,
366            history_3: Vec<f64>,
367            history_4: Vec<f64>,
368        }
369
370        impl $name {
371            pub fn new($( $param: $ptype ),*) -> Self {
372                Self {
373                    $( $param, )*
374                    history_1: Vec::new(),
375                    history_2: Vec::new(),
376                    history_3: Vec::new(),
377                    history_4: Vec::new(),
378                }
379            }
380        }
381
382        impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
383            type Output = f64;
384
385            fn next(&mut self, (in1, in2, in3, in4): (f64, f64, f64, f64)) -> Self::Output {
386                self.history_1.push(in1);
387                self.history_2.push(in2);
388                self.history_3.push(in3);
389                self.history_4.push(in4);
390                let res = $talib_func(&self.history_1, &self.history_2, &self.history_3, &self.history_4, $( self.$param.clone() ),*).unwrap_or_default();
391                *res.last().unwrap_or(&f64::NAN)
392            }
393        }
394    };
395}