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}