Skip to main content

quantwave_plugins/
generated.rs

1use polars::prelude::*;
2use pyo3_polars::derive::polars_expr;
3use serde::Deserialize;
4
5use quantwave_core::traits::Next;
6
7#[derive(Deserialize)]
8pub struct SinglePeriodKwargs {
9    pub timeperiod: usize,
10}
11
12#[polars_expr(output_type=Float64)]
13fn acos(inputs: &[Series]) -> PolarsResult<Series> {
14    let s = inputs[0].f64()?;
15    let mut indicator = quantwave_core::ACOS::new();
16    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
17        Some(v) if !v.is_nan() => Some(indicator.next(v)),
18        Some(_) => Some(f64::NAN),
19        None => None,
20    }).collect();
21    Ok(out.into_series())
22}
23
24#[polars_expr(output_type=Float64)]
25fn asin(inputs: &[Series]) -> PolarsResult<Series> {
26    let s = inputs[0].f64()?;
27    let mut indicator = quantwave_core::ASIN::new();
28    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
29        Some(v) if !v.is_nan() => Some(indicator.next(v)),
30        Some(_) => Some(f64::NAN),
31        None => None,
32    }).collect();
33    Ok(out.into_series())
34}
35
36#[polars_expr(output_type=Float64)]
37fn atan(inputs: &[Series]) -> PolarsResult<Series> {
38    let s = inputs[0].f64()?;
39    let mut indicator = quantwave_core::ATAN::new();
40    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
41        Some(v) if !v.is_nan() => Some(indicator.next(v)),
42        Some(_) => Some(f64::NAN),
43        None => None,
44    }).collect();
45    Ok(out.into_series())
46}
47
48#[polars_expr(output_type=Float64)]
49fn ceil(inputs: &[Series]) -> PolarsResult<Series> {
50    let s = inputs[0].f64()?;
51    let mut indicator = quantwave_core::CEIL::new();
52    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
53        Some(v) if !v.is_nan() => Some(indicator.next(v)),
54        Some(_) => Some(f64::NAN),
55        None => None,
56    }).collect();
57    Ok(out.into_series())
58}
59
60#[polars_expr(output_type=Float64)]
61fn cos(inputs: &[Series]) -> PolarsResult<Series> {
62    let s = inputs[0].f64()?;
63    let mut indicator = quantwave_core::COS::new();
64    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
65        Some(v) if !v.is_nan() => Some(indicator.next(v)),
66        Some(_) => Some(f64::NAN),
67        None => None,
68    }).collect();
69    Ok(out.into_series())
70}
71
72#[polars_expr(output_type=Float64)]
73fn cosh(inputs: &[Series]) -> PolarsResult<Series> {
74    let s = inputs[0].f64()?;
75    let mut indicator = quantwave_core::COSH::new();
76    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
77        Some(v) if !v.is_nan() => Some(indicator.next(v)),
78        Some(_) => Some(f64::NAN),
79        None => None,
80    }).collect();
81    Ok(out.into_series())
82}
83
84#[polars_expr(output_type=Float64)]
85fn exp(inputs: &[Series]) -> PolarsResult<Series> {
86    let s = inputs[0].f64()?;
87    let mut indicator = quantwave_core::EXP::new();
88    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
89        Some(v) if !v.is_nan() => Some(indicator.next(v)),
90        Some(_) => Some(f64::NAN),
91        None => None,
92    }).collect();
93    Ok(out.into_series())
94}
95
96#[polars_expr(output_type=Float64)]
97fn floor(inputs: &[Series]) -> PolarsResult<Series> {
98    let s = inputs[0].f64()?;
99    let mut indicator = quantwave_core::FLOOR::new();
100    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
101        Some(v) if !v.is_nan() => Some(indicator.next(v)),
102        Some(_) => Some(f64::NAN),
103        None => None,
104    }).collect();
105    Ok(out.into_series())
106}
107
108#[polars_expr(output_type=Float64)]
109fn ln(inputs: &[Series]) -> PolarsResult<Series> {
110    let s = inputs[0].f64()?;
111    let mut indicator = quantwave_core::LN::new();
112    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
113        Some(v) if !v.is_nan() => Some(indicator.next(v)),
114        Some(_) => Some(f64::NAN),
115        None => None,
116    }).collect();
117    Ok(out.into_series())
118}
119
120#[polars_expr(output_type=Float64)]
121fn log10(inputs: &[Series]) -> PolarsResult<Series> {
122    let s = inputs[0].f64()?;
123    let mut indicator = quantwave_core::LOG10::new();
124    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
125        Some(v) if !v.is_nan() => Some(indicator.next(v)),
126        Some(_) => Some(f64::NAN),
127        None => None,
128    }).collect();
129    Ok(out.into_series())
130}
131
132#[polars_expr(output_type=Float64)]
133fn sin(inputs: &[Series]) -> PolarsResult<Series> {
134    let s = inputs[0].f64()?;
135    let mut indicator = quantwave_core::SIN::new();
136    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
137        Some(v) if !v.is_nan() => Some(indicator.next(v)),
138        Some(_) => Some(f64::NAN),
139        None => None,
140    }).collect();
141    Ok(out.into_series())
142}
143
144#[polars_expr(output_type=Float64)]
145fn sinh(inputs: &[Series]) -> PolarsResult<Series> {
146    let s = inputs[0].f64()?;
147    let mut indicator = quantwave_core::SINH::new();
148    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
149        Some(v) if !v.is_nan() => Some(indicator.next(v)),
150        Some(_) => Some(f64::NAN),
151        None => None,
152    }).collect();
153    Ok(out.into_series())
154}
155
156#[polars_expr(output_type=Float64)]
157fn sqrt(inputs: &[Series]) -> PolarsResult<Series> {
158    let s = inputs[0].f64()?;
159    let mut indicator = quantwave_core::SQRT::new();
160    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
161        Some(v) if !v.is_nan() => Some(indicator.next(v)),
162        Some(_) => Some(f64::NAN),
163        None => None,
164    }).collect();
165    Ok(out.into_series())
166}
167
168#[polars_expr(output_type=Float64)]
169fn tan(inputs: &[Series]) -> PolarsResult<Series> {
170    let s = inputs[0].f64()?;
171    let mut indicator = quantwave_core::TAN::new();
172    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
173        Some(v) if !v.is_nan() => Some(indicator.next(v)),
174        Some(_) => Some(f64::NAN),
175        None => None,
176    }).collect();
177    Ok(out.into_series())
178}
179
180#[polars_expr(output_type=Float64)]
181fn tanh(inputs: &[Series]) -> PolarsResult<Series> {
182    let s = inputs[0].f64()?;
183    let mut indicator = quantwave_core::TANH::new();
184    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
185        Some(v) if !v.is_nan() => Some(indicator.next(v)),
186        Some(_) => Some(f64::NAN),
187        None => None,
188    }).collect();
189    Ok(out.into_series())
190}
191
192#[polars_expr(output_type=Float64)]
193fn max(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
194    let s = inputs[0].f64()?;
195    let mut indicator = quantwave_core::MAX::new(kwargs.timeperiod);
196    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
197        Some(v) if !v.is_nan() => Some(indicator.next(v)),
198        Some(_) => Some(f64::NAN),
199        None => None,
200    }).collect();
201    Ok(out.into_series())
202}
203
204#[polars_expr(output_type=Float64)]
205fn maxindex(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
206    let s = inputs[0].f64()?;
207    let mut indicator = quantwave_core::MAXINDEX::new(kwargs.timeperiod);
208    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
209        Some(v) if !v.is_nan() => Some(indicator.next(v)),
210        Some(_) => Some(f64::NAN),
211        None => None,
212    }).collect();
213    Ok(out.into_series())
214}
215
216#[polars_expr(output_type=Float64)]
217fn min(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
218    let s = inputs[0].f64()?;
219    let mut indicator = quantwave_core::MIN::new(kwargs.timeperiod);
220    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
221        Some(v) if !v.is_nan() => Some(indicator.next(v)),
222        Some(_) => Some(f64::NAN),
223        None => None,
224    }).collect();
225    Ok(out.into_series())
226}
227
228#[polars_expr(output_type=Float64)]
229fn minindex(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
230    let s = inputs[0].f64()?;
231    let mut indicator = quantwave_core::MININDEX::new(kwargs.timeperiod);
232    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
233        Some(v) if !v.is_nan() => Some(indicator.next(v)),
234        Some(_) => Some(f64::NAN),
235        None => None,
236    }).collect();
237    Ok(out.into_series())
238}
239
240#[polars_expr(output_type=Float64)]
241fn sum(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
242    let s = inputs[0].f64()?;
243    let mut indicator = quantwave_core::SUM::new(kwargs.timeperiod);
244    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
245        Some(v) if !v.is_nan() => Some(indicator.next(v)),
246        Some(_) => Some(f64::NAN),
247        None => None,
248    }).collect();
249    Ok(out.into_series())
250}
251
252#[polars_expr(output_type=Float64)]
253fn ta_linearreg(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
254    let s = inputs[0].f64()?;
255    let mut indicator = quantwave_core::TaLINEARREG::new(kwargs.timeperiod);
256    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
257        Some(v) if !v.is_nan() => Some(indicator.next(v)),
258        Some(_) => Some(f64::NAN),
259        None => None,
260    }).collect();
261    Ok(out.into_series())
262}
263
264#[polars_expr(output_type=Float64)]
265fn ta_linearreg_angle(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
266    let s = inputs[0].f64()?;
267    let mut indicator = quantwave_core::TaLINEARREG_ANGLE::new(kwargs.timeperiod);
268    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
269        Some(v) if !v.is_nan() => Some(indicator.next(v)),
270        Some(_) => Some(f64::NAN),
271        None => None,
272    }).collect();
273    Ok(out.into_series())
274}
275
276#[polars_expr(output_type=Float64)]
277fn ta_linearreg_intercept(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
278    let s = inputs[0].f64()?;
279    let mut indicator = quantwave_core::TaLINEARREG_INTERCEPT::new(kwargs.timeperiod);
280    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
281        Some(v) if !v.is_nan() => Some(indicator.next(v)),
282        Some(_) => Some(f64::NAN),
283        None => None,
284    }).collect();
285    Ok(out.into_series())
286}
287
288#[polars_expr(output_type=Float64)]
289fn ta_linearreg_slope(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
290    let s = inputs[0].f64()?;
291    let mut indicator = quantwave_core::TaLINEARREG_SLOPE::new(kwargs.timeperiod);
292    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
293        Some(v) if !v.is_nan() => Some(indicator.next(v)),
294        Some(_) => Some(f64::NAN),
295        None => None,
296    }).collect();
297    Ok(out.into_series())
298}
299
300#[polars_expr(output_type=Float64)]
301fn ta_tsf(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
302    let s = inputs[0].f64()?;
303    let mut indicator = quantwave_core::TaTSF::new(kwargs.timeperiod);
304    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
305        Some(v) if !v.is_nan() => Some(indicator.next(v)),
306        Some(_) => Some(f64::NAN),
307        None => None,
308    }).collect();
309    Ok(out.into_series())
310}
311
312#[polars_expr(output_type=Float64)]
313fn wma(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
314    let s = inputs[0].f64()?;
315    let mut indicator = quantwave_core::WMA::new(kwargs.timeperiod);
316    let out: Float64Chunked = s.into_iter().map(|opt_v| match opt_v {
317        Some(v) if !v.is_nan() => Some(indicator.next(v)),
318        Some(_) => Some(f64::NAN),
319        None => None,
320    }).collect();
321    Ok(out.into_series())
322}
323
324#[polars_expr(output_type=Float64)]
325fn add(inputs: &[Series]) -> PolarsResult<Series> {
326    let in1 = inputs[0].f64()?;
327    let in2 = inputs[1].f64()?;
328    let mut indicator = quantwave_core::ADD::new();
329    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
330        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
331        (Some(_), Some(_)) => Some(f64::NAN),
332        _ => None,
333    }).collect();
334    Ok(out.into_series())
335}
336
337#[polars_expr(output_type=Float64)]
338fn div(inputs: &[Series]) -> PolarsResult<Series> {
339    let in1 = inputs[0].f64()?;
340    let in2 = inputs[1].f64()?;
341    let mut indicator = quantwave_core::DIV::new();
342    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
343        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
344        (Some(_), Some(_)) => Some(f64::NAN),
345        _ => None,
346    }).collect();
347    Ok(out.into_series())
348}
349
350#[polars_expr(output_type=Float64)]
351fn mult(inputs: &[Series]) -> PolarsResult<Series> {
352    let in1 = inputs[0].f64()?;
353    let in2 = inputs[1].f64()?;
354    let mut indicator = quantwave_core::MULT::new();
355    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
356        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
357        (Some(_), Some(_)) => Some(f64::NAN),
358        _ => None,
359    }).collect();
360    Ok(out.into_series())
361}
362
363#[polars_expr(output_type=Float64)]
364fn obv(inputs: &[Series]) -> PolarsResult<Series> {
365    let in1 = inputs[0].f64()?;
366    let in2 = inputs[1].f64()?;
367    let mut indicator = quantwave_core::OBV::new();
368    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
369        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
370        (Some(_), Some(_)) => Some(f64::NAN),
371        _ => None,
372    }).collect();
373    Ok(out.into_series())
374}
375
376#[polars_expr(output_type=Float64)]
377fn sub(inputs: &[Series]) -> PolarsResult<Series> {
378    let in1 = inputs[0].f64()?;
379    let in2 = inputs[1].f64()?;
380    let mut indicator = quantwave_core::SUB::new();
381    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
382        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
383        (Some(_), Some(_)) => Some(f64::NAN),
384        _ => None,
385    }).collect();
386    Ok(out.into_series())
387}
388
389#[polars_expr(output_type=Float64)]
390fn ta_beta(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
391    let in1 = inputs[0].f64()?;
392    let in2 = inputs[1].f64()?;
393    let mut indicator = quantwave_core::TaBETA::new(kwargs.timeperiod);
394    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
395        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
396        (Some(_), Some(_)) => Some(f64::NAN),
397        _ => None,
398    }).collect();
399    Ok(out.into_series())
400}
401
402#[polars_expr(output_type=Float64)]
403fn ta_correl(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
404    let in1 = inputs[0].f64()?;
405    let in2 = inputs[1].f64()?;
406    let mut indicator = quantwave_core::TaCORREL::new(kwargs.timeperiod);
407    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).map(|(v1, v2)| match (v1, v2) {
408        (Some(a), Some(b)) if !a.is_nan() && !b.is_nan() => Some(indicator.next((a, b))),
409        (Some(_), Some(_)) => Some(f64::NAN),
410        _ => None,
411    }).collect();
412    Ok(out.into_series())
413}
414
415#[polars_expr(output_type=Float64)]
416fn ta_trange(inputs: &[Series]) -> PolarsResult<Series> {
417    let in1 = inputs[0].f64()?;
418    let in2 = inputs[1].f64()?;
419    let in3 = inputs[2].f64()?;
420    let mut indicator = quantwave_core::TaTRANGE::new();
421    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).zip(in3.into_iter()).map(|((v1, v2), v3)| match (v1, v2, v3) {
422        (Some(a), Some(b), Some(c)) if !a.is_nan() && !b.is_nan() && !c.is_nan() => Some(indicator.next((a, b, c))),
423        (Some(_), Some(_), Some(_)) => Some(f64::NAN),
424        _ => None,
425    }).collect();
426    Ok(out.into_series())
427}
428
429#[polars_expr(output_type=Float64)]
430fn ta_atr(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
431    let in1 = inputs[0].f64()?;
432    let in2 = inputs[1].f64()?;
433    let in3 = inputs[2].f64()?;
434    let mut indicator = quantwave_core::TaATR::new(kwargs.timeperiod);
435    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).zip(in3.into_iter()).map(|((v1, v2), v3)| match (v1, v2, v3) {
436        (Some(a), Some(b), Some(c)) if !a.is_nan() && !b.is_nan() && !c.is_nan() => Some(indicator.next((a, b, c))),
437        (Some(_), Some(_), Some(_)) => Some(f64::NAN),
438        _ => None,
439    }).collect();
440    Ok(out.into_series())
441}
442
443#[polars_expr(output_type=Float64)]
444fn ta_natr(inputs: &[Series], kwargs: SinglePeriodKwargs) -> PolarsResult<Series> {
445    let in1 = inputs[0].f64()?;
446    let in2 = inputs[1].f64()?;
447    let in3 = inputs[2].f64()?;
448    let mut indicator = quantwave_core::TaNATR::new(kwargs.timeperiod);
449    let out: Float64Chunked = in1.into_iter().zip(in2.into_iter()).zip(in3.into_iter()).map(|((v1, v2), v3)| match (v1, v2, v3) {
450        (Some(a), Some(b), Some(c)) if !a.is_nan() && !b.is_nan() && !c.is_nan() => Some(indicator.next((a, b, c))),
451        (Some(_), Some(_), Some(_)) => Some(f64::NAN),
452        _ => None,
453    }).collect();
454    Ok(out.into_series())
455}
456
457#[polars_expr(output_type=Float64)]
458fn bop(inputs: &[Series]) -> PolarsResult<Series> {
459    let open = inputs[0].f64()?;
460    let high = inputs[1].f64()?;
461    let low = inputs[2].f64()?;
462    let close = inputs[3].f64()?;
463    let mut indicator = quantwave_core::BOP::new();
464    let out: Float64Chunked = open.into_iter()
465        .zip(high.into_iter())
466        .zip(low.into_iter())
467        .zip(close.into_iter())
468        .map(|(((o, h), l), c)| match (o, h, l, c) {
469            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
470                Some(indicator.next((o_, h_, l_, c_)) as f64),
471            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
472            _ => None,
473        }).collect();
474    Ok(out.into_series())
475}
476
477#[polars_expr(output_type=Float64)]
478fn cdl_2crows(inputs: &[Series]) -> PolarsResult<Series> {
479    let open = inputs[0].f64()?;
480    let high = inputs[1].f64()?;
481    let low = inputs[2].f64()?;
482    let close = inputs[3].f64()?;
483    let mut indicator = quantwave_core::CDL2CROWS::new();
484    let out: Float64Chunked = open.into_iter()
485        .zip(high.into_iter())
486        .zip(low.into_iter())
487        .zip(close.into_iter())
488        .map(|(((o, h), l), c)| match (o, h, l, c) {
489            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
490                Some(indicator.next((o_, h_, l_, c_)) as f64),
491            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
492            _ => None,
493        }).collect();
494    Ok(out.into_series())
495}
496
497#[polars_expr(output_type=Float64)]
498fn cdl_3blackcrows(inputs: &[Series]) -> PolarsResult<Series> {
499    let open = inputs[0].f64()?;
500    let high = inputs[1].f64()?;
501    let low = inputs[2].f64()?;
502    let close = inputs[3].f64()?;
503    let mut indicator = quantwave_core::CDL3BLACKCROWS::new();
504    let out: Float64Chunked = open.into_iter()
505        .zip(high.into_iter())
506        .zip(low.into_iter())
507        .zip(close.into_iter())
508        .map(|(((o, h), l), c)| match (o, h, l, c) {
509            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
510                Some(indicator.next((o_, h_, l_, c_)) as f64),
511            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
512            _ => None,
513        }).collect();
514    Ok(out.into_series())
515}
516
517#[polars_expr(output_type=Float64)]
518fn cdl_3inside(inputs: &[Series]) -> PolarsResult<Series> {
519    let open = inputs[0].f64()?;
520    let high = inputs[1].f64()?;
521    let low = inputs[2].f64()?;
522    let close = inputs[3].f64()?;
523    let mut indicator = quantwave_core::CDL3INSIDE::new();
524    let out: Float64Chunked = open.into_iter()
525        .zip(high.into_iter())
526        .zip(low.into_iter())
527        .zip(close.into_iter())
528        .map(|(((o, h), l), c)| match (o, h, l, c) {
529            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
530                Some(indicator.next((o_, h_, l_, c_)) as f64),
531            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
532            _ => None,
533        }).collect();
534    Ok(out.into_series())
535}
536
537#[polars_expr(output_type=Float64)]
538fn cdl_3linestrike(inputs: &[Series]) -> PolarsResult<Series> {
539    let open = inputs[0].f64()?;
540    let high = inputs[1].f64()?;
541    let low = inputs[2].f64()?;
542    let close = inputs[3].f64()?;
543    let mut indicator = quantwave_core::CDL3LINESTRIKE::new();
544    let out: Float64Chunked = open.into_iter()
545        .zip(high.into_iter())
546        .zip(low.into_iter())
547        .zip(close.into_iter())
548        .map(|(((o, h), l), c)| match (o, h, l, c) {
549            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
550                Some(indicator.next((o_, h_, l_, c_)) as f64),
551            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
552            _ => None,
553        }).collect();
554    Ok(out.into_series())
555}
556
557#[polars_expr(output_type=Float64)]
558fn cdl_3outside(inputs: &[Series]) -> PolarsResult<Series> {
559    let open = inputs[0].f64()?;
560    let high = inputs[1].f64()?;
561    let low = inputs[2].f64()?;
562    let close = inputs[3].f64()?;
563    let mut indicator = quantwave_core::CDL3OUTSIDE::new();
564    let out: Float64Chunked = open.into_iter()
565        .zip(high.into_iter())
566        .zip(low.into_iter())
567        .zip(close.into_iter())
568        .map(|(((o, h), l), c)| match (o, h, l, c) {
569            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
570                Some(indicator.next((o_, h_, l_, c_)) as f64),
571            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
572            _ => None,
573        }).collect();
574    Ok(out.into_series())
575}
576
577#[polars_expr(output_type=Float64)]
578fn cdl_3starsinsouth(inputs: &[Series]) -> PolarsResult<Series> {
579    let open = inputs[0].f64()?;
580    let high = inputs[1].f64()?;
581    let low = inputs[2].f64()?;
582    let close = inputs[3].f64()?;
583    let mut indicator = quantwave_core::CDL3STARSINSOUTH::new();
584    let out: Float64Chunked = open.into_iter()
585        .zip(high.into_iter())
586        .zip(low.into_iter())
587        .zip(close.into_iter())
588        .map(|(((o, h), l), c)| match (o, h, l, c) {
589            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
590                Some(indicator.next((o_, h_, l_, c_)) as f64),
591            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
592            _ => None,
593        }).collect();
594    Ok(out.into_series())
595}
596
597#[polars_expr(output_type=Float64)]
598fn cdl_3whitesoldiers(inputs: &[Series]) -> PolarsResult<Series> {
599    let open = inputs[0].f64()?;
600    let high = inputs[1].f64()?;
601    let low = inputs[2].f64()?;
602    let close = inputs[3].f64()?;
603    let mut indicator = quantwave_core::CDL3WHITESOLDIERS::new();
604    let out: Float64Chunked = open.into_iter()
605        .zip(high.into_iter())
606        .zip(low.into_iter())
607        .zip(close.into_iter())
608        .map(|(((o, h), l), c)| match (o, h, l, c) {
609            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
610                Some(indicator.next((o_, h_, l_, c_)) as f64),
611            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
612            _ => None,
613        }).collect();
614    Ok(out.into_series())
615}
616
617#[polars_expr(output_type=Float64)]
618fn cdl_abandonedbaby(inputs: &[Series]) -> PolarsResult<Series> {
619    let open = inputs[0].f64()?;
620    let high = inputs[1].f64()?;
621    let low = inputs[2].f64()?;
622    let close = inputs[3].f64()?;
623    let mut indicator = quantwave_core::CDLABANDONEDBABY::new();
624    let out: Float64Chunked = open.into_iter()
625        .zip(high.into_iter())
626        .zip(low.into_iter())
627        .zip(close.into_iter())
628        .map(|(((o, h), l), c)| match (o, h, l, c) {
629            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
630                Some(indicator.next((o_, h_, l_, c_)) as f64),
631            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
632            _ => None,
633        }).collect();
634    Ok(out.into_series())
635}
636
637#[polars_expr(output_type=Float64)]
638fn cdl_advanceblock(inputs: &[Series]) -> PolarsResult<Series> {
639    let open = inputs[0].f64()?;
640    let high = inputs[1].f64()?;
641    let low = inputs[2].f64()?;
642    let close = inputs[3].f64()?;
643    let mut indicator = quantwave_core::CDLADVANCEBLOCK::new();
644    let out: Float64Chunked = open.into_iter()
645        .zip(high.into_iter())
646        .zip(low.into_iter())
647        .zip(close.into_iter())
648        .map(|(((o, h), l), c)| match (o, h, l, c) {
649            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
650                Some(indicator.next((o_, h_, l_, c_)) as f64),
651            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
652            _ => None,
653        }).collect();
654    Ok(out.into_series())
655}
656
657#[polars_expr(output_type=Float64)]
658fn cdl_belthold(inputs: &[Series]) -> PolarsResult<Series> {
659    let open = inputs[0].f64()?;
660    let high = inputs[1].f64()?;
661    let low = inputs[2].f64()?;
662    let close = inputs[3].f64()?;
663    let mut indicator = quantwave_core::CDLBELTHOLD::new();
664    let out: Float64Chunked = open.into_iter()
665        .zip(high.into_iter())
666        .zip(low.into_iter())
667        .zip(close.into_iter())
668        .map(|(((o, h), l), c)| match (o, h, l, c) {
669            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
670                Some(indicator.next((o_, h_, l_, c_)) as f64),
671            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
672            _ => None,
673        }).collect();
674    Ok(out.into_series())
675}
676
677#[polars_expr(output_type=Float64)]
678fn cdl_breakaway(inputs: &[Series]) -> PolarsResult<Series> {
679    let open = inputs[0].f64()?;
680    let high = inputs[1].f64()?;
681    let low = inputs[2].f64()?;
682    let close = inputs[3].f64()?;
683    let mut indicator = quantwave_core::CDLBREAKAWAY::new();
684    let out: Float64Chunked = open.into_iter()
685        .zip(high.into_iter())
686        .zip(low.into_iter())
687        .zip(close.into_iter())
688        .map(|(((o, h), l), c)| match (o, h, l, c) {
689            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
690                Some(indicator.next((o_, h_, l_, c_)) as f64),
691            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
692            _ => None,
693        }).collect();
694    Ok(out.into_series())
695}
696
697#[polars_expr(output_type=Float64)]
698fn cdl_closingmarubozu(inputs: &[Series]) -> PolarsResult<Series> {
699    let open = inputs[0].f64()?;
700    let high = inputs[1].f64()?;
701    let low = inputs[2].f64()?;
702    let close = inputs[3].f64()?;
703    let mut indicator = quantwave_core::CDLCLOSINGMARUBOZU::new();
704    let out: Float64Chunked = open.into_iter()
705        .zip(high.into_iter())
706        .zip(low.into_iter())
707        .zip(close.into_iter())
708        .map(|(((o, h), l), c)| match (o, h, l, c) {
709            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
710                Some(indicator.next((o_, h_, l_, c_)) as f64),
711            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
712            _ => None,
713        }).collect();
714    Ok(out.into_series())
715}
716
717#[polars_expr(output_type=Float64)]
718fn cdl_concealbabyswall(inputs: &[Series]) -> PolarsResult<Series> {
719    let open = inputs[0].f64()?;
720    let high = inputs[1].f64()?;
721    let low = inputs[2].f64()?;
722    let close = inputs[3].f64()?;
723    let mut indicator = quantwave_core::CDLCONCEALBABYSWALL::new();
724    let out: Float64Chunked = open.into_iter()
725        .zip(high.into_iter())
726        .zip(low.into_iter())
727        .zip(close.into_iter())
728        .map(|(((o, h), l), c)| match (o, h, l, c) {
729            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
730                Some(indicator.next((o_, h_, l_, c_)) as f64),
731            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
732            _ => None,
733        }).collect();
734    Ok(out.into_series())
735}
736
737#[polars_expr(output_type=Float64)]
738fn cdl_counterattack(inputs: &[Series]) -> PolarsResult<Series> {
739    let open = inputs[0].f64()?;
740    let high = inputs[1].f64()?;
741    let low = inputs[2].f64()?;
742    let close = inputs[3].f64()?;
743    let mut indicator = quantwave_core::CDLCOUNTERATTACK::new();
744    let out: Float64Chunked = open.into_iter()
745        .zip(high.into_iter())
746        .zip(low.into_iter())
747        .zip(close.into_iter())
748        .map(|(((o, h), l), c)| match (o, h, l, c) {
749            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
750                Some(indicator.next((o_, h_, l_, c_)) as f64),
751            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
752            _ => None,
753        }).collect();
754    Ok(out.into_series())
755}
756
757#[polars_expr(output_type=Float64)]
758fn cdl_darkcloudcover(inputs: &[Series]) -> PolarsResult<Series> {
759    let open = inputs[0].f64()?;
760    let high = inputs[1].f64()?;
761    let low = inputs[2].f64()?;
762    let close = inputs[3].f64()?;
763    let mut indicator = quantwave_core::CDLDARKCLOUDCOVER::new();
764    let out: Float64Chunked = open.into_iter()
765        .zip(high.into_iter())
766        .zip(low.into_iter())
767        .zip(close.into_iter())
768        .map(|(((o, h), l), c)| match (o, h, l, c) {
769            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
770                Some(indicator.next((o_, h_, l_, c_)) as f64),
771            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
772            _ => None,
773        }).collect();
774    Ok(out.into_series())
775}
776
777#[polars_expr(output_type=Float64)]
778fn cdl_doji(inputs: &[Series]) -> PolarsResult<Series> {
779    let open = inputs[0].f64()?;
780    let high = inputs[1].f64()?;
781    let low = inputs[2].f64()?;
782    let close = inputs[3].f64()?;
783    let mut indicator = quantwave_core::CDLDOJI::new();
784    let out: Float64Chunked = open.into_iter()
785        .zip(high.into_iter())
786        .zip(low.into_iter())
787        .zip(close.into_iter())
788        .map(|(((o, h), l), c)| match (o, h, l, c) {
789            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
790                Some(indicator.next((o_, h_, l_, c_)) as f64),
791            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
792            _ => None,
793        }).collect();
794    Ok(out.into_series())
795}
796
797#[polars_expr(output_type=Float64)]
798fn cdl_dojistar(inputs: &[Series]) -> PolarsResult<Series> {
799    let open = inputs[0].f64()?;
800    let high = inputs[1].f64()?;
801    let low = inputs[2].f64()?;
802    let close = inputs[3].f64()?;
803    let mut indicator = quantwave_core::CDLDOJISTAR::new();
804    let out: Float64Chunked = open.into_iter()
805        .zip(high.into_iter())
806        .zip(low.into_iter())
807        .zip(close.into_iter())
808        .map(|(((o, h), l), c)| match (o, h, l, c) {
809            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
810                Some(indicator.next((o_, h_, l_, c_)) as f64),
811            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
812            _ => None,
813        }).collect();
814    Ok(out.into_series())
815}
816
817#[polars_expr(output_type=Float64)]
818fn cdl_dragonflydoji(inputs: &[Series]) -> PolarsResult<Series> {
819    let open = inputs[0].f64()?;
820    let high = inputs[1].f64()?;
821    let low = inputs[2].f64()?;
822    let close = inputs[3].f64()?;
823    let mut indicator = quantwave_core::CDLDRAGONFLYDOJI::new();
824    let out: Float64Chunked = open.into_iter()
825        .zip(high.into_iter())
826        .zip(low.into_iter())
827        .zip(close.into_iter())
828        .map(|(((o, h), l), c)| match (o, h, l, c) {
829            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
830                Some(indicator.next((o_, h_, l_, c_)) as f64),
831            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
832            _ => None,
833        }).collect();
834    Ok(out.into_series())
835}
836
837#[polars_expr(output_type=Float64)]
838fn cdl_engulfing(inputs: &[Series]) -> PolarsResult<Series> {
839    let open = inputs[0].f64()?;
840    let high = inputs[1].f64()?;
841    let low = inputs[2].f64()?;
842    let close = inputs[3].f64()?;
843    let mut indicator = quantwave_core::CDLENGULFING::new();
844    let out: Float64Chunked = open.into_iter()
845        .zip(high.into_iter())
846        .zip(low.into_iter())
847        .zip(close.into_iter())
848        .map(|(((o, h), l), c)| match (o, h, l, c) {
849            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
850                Some(indicator.next((o_, h_, l_, c_)) as f64),
851            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
852            _ => None,
853        }).collect();
854    Ok(out.into_series())
855}
856
857#[polars_expr(output_type=Float64)]
858fn cdl_eveningdojistar(inputs: &[Series]) -> PolarsResult<Series> {
859    let open = inputs[0].f64()?;
860    let high = inputs[1].f64()?;
861    let low = inputs[2].f64()?;
862    let close = inputs[3].f64()?;
863    let mut indicator = quantwave_core::CDLEVENINGDOJISTAR::new();
864    let out: Float64Chunked = open.into_iter()
865        .zip(high.into_iter())
866        .zip(low.into_iter())
867        .zip(close.into_iter())
868        .map(|(((o, h), l), c)| match (o, h, l, c) {
869            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
870                Some(indicator.next((o_, h_, l_, c_)) as f64),
871            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
872            _ => None,
873        }).collect();
874    Ok(out.into_series())
875}
876
877#[polars_expr(output_type=Float64)]
878fn cdl_eveningstar(inputs: &[Series]) -> PolarsResult<Series> {
879    let open = inputs[0].f64()?;
880    let high = inputs[1].f64()?;
881    let low = inputs[2].f64()?;
882    let close = inputs[3].f64()?;
883    let mut indicator = quantwave_core::CDLEVENINGSTAR::new();
884    let out: Float64Chunked = open.into_iter()
885        .zip(high.into_iter())
886        .zip(low.into_iter())
887        .zip(close.into_iter())
888        .map(|(((o, h), l), c)| match (o, h, l, c) {
889            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
890                Some(indicator.next((o_, h_, l_, c_)) as f64),
891            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
892            _ => None,
893        }).collect();
894    Ok(out.into_series())
895}
896
897#[polars_expr(output_type=Float64)]
898fn cdl_gapsidesidewhite(inputs: &[Series]) -> PolarsResult<Series> {
899    let open = inputs[0].f64()?;
900    let high = inputs[1].f64()?;
901    let low = inputs[2].f64()?;
902    let close = inputs[3].f64()?;
903    let mut indicator = quantwave_core::CDLGAPSIDESIDEWHITE::new();
904    let out: Float64Chunked = open.into_iter()
905        .zip(high.into_iter())
906        .zip(low.into_iter())
907        .zip(close.into_iter())
908        .map(|(((o, h), l), c)| match (o, h, l, c) {
909            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
910                Some(indicator.next((o_, h_, l_, c_)) as f64),
911            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
912            _ => None,
913        }).collect();
914    Ok(out.into_series())
915}
916
917#[polars_expr(output_type=Float64)]
918fn cdl_gravestonedoji(inputs: &[Series]) -> PolarsResult<Series> {
919    let open = inputs[0].f64()?;
920    let high = inputs[1].f64()?;
921    let low = inputs[2].f64()?;
922    let close = inputs[3].f64()?;
923    let mut indicator = quantwave_core::CDLGRAVESTONEDOJI::new();
924    let out: Float64Chunked = open.into_iter()
925        .zip(high.into_iter())
926        .zip(low.into_iter())
927        .zip(close.into_iter())
928        .map(|(((o, h), l), c)| match (o, h, l, c) {
929            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
930                Some(indicator.next((o_, h_, l_, c_)) as f64),
931            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
932            _ => None,
933        }).collect();
934    Ok(out.into_series())
935}
936
937#[polars_expr(output_type=Float64)]
938fn cdl_hammer(inputs: &[Series]) -> PolarsResult<Series> {
939    let open = inputs[0].f64()?;
940    let high = inputs[1].f64()?;
941    let low = inputs[2].f64()?;
942    let close = inputs[3].f64()?;
943    let mut indicator = quantwave_core::CDLHAMMER::new();
944    let out: Float64Chunked = open.into_iter()
945        .zip(high.into_iter())
946        .zip(low.into_iter())
947        .zip(close.into_iter())
948        .map(|(((o, h), l), c)| match (o, h, l, c) {
949            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
950                Some(indicator.next((o_, h_, l_, c_)) as f64),
951            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
952            _ => None,
953        }).collect();
954    Ok(out.into_series())
955}
956
957#[polars_expr(output_type=Float64)]
958fn cdl_hangingman(inputs: &[Series]) -> PolarsResult<Series> {
959    let open = inputs[0].f64()?;
960    let high = inputs[1].f64()?;
961    let low = inputs[2].f64()?;
962    let close = inputs[3].f64()?;
963    let mut indicator = quantwave_core::CDLHANGINGMAN::new();
964    let out: Float64Chunked = open.into_iter()
965        .zip(high.into_iter())
966        .zip(low.into_iter())
967        .zip(close.into_iter())
968        .map(|(((o, h), l), c)| match (o, h, l, c) {
969            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
970                Some(indicator.next((o_, h_, l_, c_)) as f64),
971            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
972            _ => None,
973        }).collect();
974    Ok(out.into_series())
975}
976
977#[polars_expr(output_type=Float64)]
978fn cdl_harami(inputs: &[Series]) -> PolarsResult<Series> {
979    let open = inputs[0].f64()?;
980    let high = inputs[1].f64()?;
981    let low = inputs[2].f64()?;
982    let close = inputs[3].f64()?;
983    let mut indicator = quantwave_core::CDLHARAMI::new();
984    let out: Float64Chunked = open.into_iter()
985        .zip(high.into_iter())
986        .zip(low.into_iter())
987        .zip(close.into_iter())
988        .map(|(((o, h), l), c)| match (o, h, l, c) {
989            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
990                Some(indicator.next((o_, h_, l_, c_)) as f64),
991            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
992            _ => None,
993        }).collect();
994    Ok(out.into_series())
995}
996
997#[polars_expr(output_type=Float64)]
998fn cdl_haramicross(inputs: &[Series]) -> PolarsResult<Series> {
999    let open = inputs[0].f64()?;
1000    let high = inputs[1].f64()?;
1001    let low = inputs[2].f64()?;
1002    let close = inputs[3].f64()?;
1003    let mut indicator = quantwave_core::CDLHARAMICROSS::new();
1004    let out: Float64Chunked = open.into_iter()
1005        .zip(high.into_iter())
1006        .zip(low.into_iter())
1007        .zip(close.into_iter())
1008        .map(|(((o, h), l), c)| match (o, h, l, c) {
1009            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1010                Some(indicator.next((o_, h_, l_, c_)) as f64),
1011            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1012            _ => None,
1013        }).collect();
1014    Ok(out.into_series())
1015}
1016
1017#[polars_expr(output_type=Float64)]
1018fn cdl_highwave(inputs: &[Series]) -> PolarsResult<Series> {
1019    let open = inputs[0].f64()?;
1020    let high = inputs[1].f64()?;
1021    let low = inputs[2].f64()?;
1022    let close = inputs[3].f64()?;
1023    let mut indicator = quantwave_core::CDLHIGHWAVE::new();
1024    let out: Float64Chunked = open.into_iter()
1025        .zip(high.into_iter())
1026        .zip(low.into_iter())
1027        .zip(close.into_iter())
1028        .map(|(((o, h), l), c)| match (o, h, l, c) {
1029            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1030                Some(indicator.next((o_, h_, l_, c_)) as f64),
1031            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1032            _ => None,
1033        }).collect();
1034    Ok(out.into_series())
1035}
1036
1037#[polars_expr(output_type=Float64)]
1038fn cdl_hikkake(inputs: &[Series]) -> PolarsResult<Series> {
1039    let open = inputs[0].f64()?;
1040    let high = inputs[1].f64()?;
1041    let low = inputs[2].f64()?;
1042    let close = inputs[3].f64()?;
1043    let mut indicator = quantwave_core::CDLHIKKAKE::new();
1044    let out: Float64Chunked = open.into_iter()
1045        .zip(high.into_iter())
1046        .zip(low.into_iter())
1047        .zip(close.into_iter())
1048        .map(|(((o, h), l), c)| match (o, h, l, c) {
1049            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1050                Some(indicator.next((o_, h_, l_, c_)) as f64),
1051            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1052            _ => None,
1053        }).collect();
1054    Ok(out.into_series())
1055}
1056
1057#[polars_expr(output_type=Float64)]
1058fn cdl_hikkakemod(inputs: &[Series]) -> PolarsResult<Series> {
1059    let open = inputs[0].f64()?;
1060    let high = inputs[1].f64()?;
1061    let low = inputs[2].f64()?;
1062    let close = inputs[3].f64()?;
1063    let mut indicator = quantwave_core::CDLHIKKAKEMOD::new();
1064    let out: Float64Chunked = open.into_iter()
1065        .zip(high.into_iter())
1066        .zip(low.into_iter())
1067        .zip(close.into_iter())
1068        .map(|(((o, h), l), c)| match (o, h, l, c) {
1069            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1070                Some(indicator.next((o_, h_, l_, c_)) as f64),
1071            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1072            _ => None,
1073        }).collect();
1074    Ok(out.into_series())
1075}
1076
1077#[polars_expr(output_type=Float64)]
1078fn cdl_homingpigeon(inputs: &[Series]) -> PolarsResult<Series> {
1079    let open = inputs[0].f64()?;
1080    let high = inputs[1].f64()?;
1081    let low = inputs[2].f64()?;
1082    let close = inputs[3].f64()?;
1083    let mut indicator = quantwave_core::CDLHOMINGPIGEON::new();
1084    let out: Float64Chunked = open.into_iter()
1085        .zip(high.into_iter())
1086        .zip(low.into_iter())
1087        .zip(close.into_iter())
1088        .map(|(((o, h), l), c)| match (o, h, l, c) {
1089            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1090                Some(indicator.next((o_, h_, l_, c_)) as f64),
1091            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1092            _ => None,
1093        }).collect();
1094    Ok(out.into_series())
1095}
1096
1097#[polars_expr(output_type=Float64)]
1098fn cdl_identical3crows(inputs: &[Series]) -> PolarsResult<Series> {
1099    let open = inputs[0].f64()?;
1100    let high = inputs[1].f64()?;
1101    let low = inputs[2].f64()?;
1102    let close = inputs[3].f64()?;
1103    let mut indicator = quantwave_core::CDLIDENTICAL3CROWS::new();
1104    let out: Float64Chunked = open.into_iter()
1105        .zip(high.into_iter())
1106        .zip(low.into_iter())
1107        .zip(close.into_iter())
1108        .map(|(((o, h), l), c)| match (o, h, l, c) {
1109            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1110                Some(indicator.next((o_, h_, l_, c_)) as f64),
1111            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1112            _ => None,
1113        }).collect();
1114    Ok(out.into_series())
1115}
1116
1117#[polars_expr(output_type=Float64)]
1118fn cdl_inneck(inputs: &[Series]) -> PolarsResult<Series> {
1119    let open = inputs[0].f64()?;
1120    let high = inputs[1].f64()?;
1121    let low = inputs[2].f64()?;
1122    let close = inputs[3].f64()?;
1123    let mut indicator = quantwave_core::CDLINNECK::new();
1124    let out: Float64Chunked = open.into_iter()
1125        .zip(high.into_iter())
1126        .zip(low.into_iter())
1127        .zip(close.into_iter())
1128        .map(|(((o, h), l), c)| match (o, h, l, c) {
1129            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1130                Some(indicator.next((o_, h_, l_, c_)) as f64),
1131            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1132            _ => None,
1133        }).collect();
1134    Ok(out.into_series())
1135}
1136
1137#[polars_expr(output_type=Float64)]
1138fn cdl_invertedhammer(inputs: &[Series]) -> PolarsResult<Series> {
1139    let open = inputs[0].f64()?;
1140    let high = inputs[1].f64()?;
1141    let low = inputs[2].f64()?;
1142    let close = inputs[3].f64()?;
1143    let mut indicator = quantwave_core::CDLINVERTEDHAMMER::new();
1144    let out: Float64Chunked = open.into_iter()
1145        .zip(high.into_iter())
1146        .zip(low.into_iter())
1147        .zip(close.into_iter())
1148        .map(|(((o, h), l), c)| match (o, h, l, c) {
1149            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1150                Some(indicator.next((o_, h_, l_, c_)) as f64),
1151            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1152            _ => None,
1153        }).collect();
1154    Ok(out.into_series())
1155}
1156
1157#[polars_expr(output_type=Float64)]
1158fn cdl_kicking(inputs: &[Series]) -> PolarsResult<Series> {
1159    let open = inputs[0].f64()?;
1160    let high = inputs[1].f64()?;
1161    let low = inputs[2].f64()?;
1162    let close = inputs[3].f64()?;
1163    let mut indicator = quantwave_core::CDLKICKING::new();
1164    let out: Float64Chunked = open.into_iter()
1165        .zip(high.into_iter())
1166        .zip(low.into_iter())
1167        .zip(close.into_iter())
1168        .map(|(((o, h), l), c)| match (o, h, l, c) {
1169            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1170                Some(indicator.next((o_, h_, l_, c_)) as f64),
1171            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1172            _ => None,
1173        }).collect();
1174    Ok(out.into_series())
1175}
1176
1177#[polars_expr(output_type=Float64)]
1178fn cdl_kickingbylength(inputs: &[Series]) -> PolarsResult<Series> {
1179    let open = inputs[0].f64()?;
1180    let high = inputs[1].f64()?;
1181    let low = inputs[2].f64()?;
1182    let close = inputs[3].f64()?;
1183    let mut indicator = quantwave_core::CDLKICKINGBYLENGTH::new();
1184    let out: Float64Chunked = open.into_iter()
1185        .zip(high.into_iter())
1186        .zip(low.into_iter())
1187        .zip(close.into_iter())
1188        .map(|(((o, h), l), c)| match (o, h, l, c) {
1189            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1190                Some(indicator.next((o_, h_, l_, c_)) as f64),
1191            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1192            _ => None,
1193        }).collect();
1194    Ok(out.into_series())
1195}
1196
1197#[polars_expr(output_type=Float64)]
1198fn cdl_ladderbottom(inputs: &[Series]) -> PolarsResult<Series> {
1199    let open = inputs[0].f64()?;
1200    let high = inputs[1].f64()?;
1201    let low = inputs[2].f64()?;
1202    let close = inputs[3].f64()?;
1203    let mut indicator = quantwave_core::CDLLADDERBOTTOM::new();
1204    let out: Float64Chunked = open.into_iter()
1205        .zip(high.into_iter())
1206        .zip(low.into_iter())
1207        .zip(close.into_iter())
1208        .map(|(((o, h), l), c)| match (o, h, l, c) {
1209            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1210                Some(indicator.next((o_, h_, l_, c_)) as f64),
1211            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1212            _ => None,
1213        }).collect();
1214    Ok(out.into_series())
1215}
1216
1217#[polars_expr(output_type=Float64)]
1218fn cdl_longleggeddoji(inputs: &[Series]) -> PolarsResult<Series> {
1219    let open = inputs[0].f64()?;
1220    let high = inputs[1].f64()?;
1221    let low = inputs[2].f64()?;
1222    let close = inputs[3].f64()?;
1223    let mut indicator = quantwave_core::CDLLONGLEGGEDDOJI::new();
1224    let out: Float64Chunked = open.into_iter()
1225        .zip(high.into_iter())
1226        .zip(low.into_iter())
1227        .zip(close.into_iter())
1228        .map(|(((o, h), l), c)| match (o, h, l, c) {
1229            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1230                Some(indicator.next((o_, h_, l_, c_)) as f64),
1231            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1232            _ => None,
1233        }).collect();
1234    Ok(out.into_series())
1235}
1236
1237#[polars_expr(output_type=Float64)]
1238fn cdl_longline(inputs: &[Series]) -> PolarsResult<Series> {
1239    let open = inputs[0].f64()?;
1240    let high = inputs[1].f64()?;
1241    let low = inputs[2].f64()?;
1242    let close = inputs[3].f64()?;
1243    let mut indicator = quantwave_core::CDLLONGLINE::new();
1244    let out: Float64Chunked = open.into_iter()
1245        .zip(high.into_iter())
1246        .zip(low.into_iter())
1247        .zip(close.into_iter())
1248        .map(|(((o, h), l), c)| match (o, h, l, c) {
1249            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1250                Some(indicator.next((o_, h_, l_, c_)) as f64),
1251            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1252            _ => None,
1253        }).collect();
1254    Ok(out.into_series())
1255}
1256
1257#[polars_expr(output_type=Float64)]
1258fn cdl_marubozu(inputs: &[Series]) -> PolarsResult<Series> {
1259    let open = inputs[0].f64()?;
1260    let high = inputs[1].f64()?;
1261    let low = inputs[2].f64()?;
1262    let close = inputs[3].f64()?;
1263    let mut indicator = quantwave_core::CDLMARUBOZU::new();
1264    let out: Float64Chunked = open.into_iter()
1265        .zip(high.into_iter())
1266        .zip(low.into_iter())
1267        .zip(close.into_iter())
1268        .map(|(((o, h), l), c)| match (o, h, l, c) {
1269            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1270                Some(indicator.next((o_, h_, l_, c_)) as f64),
1271            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1272            _ => None,
1273        }).collect();
1274    Ok(out.into_series())
1275}
1276
1277#[polars_expr(output_type=Float64)]
1278fn cdl_matchinglow(inputs: &[Series]) -> PolarsResult<Series> {
1279    let open = inputs[0].f64()?;
1280    let high = inputs[1].f64()?;
1281    let low = inputs[2].f64()?;
1282    let close = inputs[3].f64()?;
1283    let mut indicator = quantwave_core::CDLMATCHINGLOW::new();
1284    let out: Float64Chunked = open.into_iter()
1285        .zip(high.into_iter())
1286        .zip(low.into_iter())
1287        .zip(close.into_iter())
1288        .map(|(((o, h), l), c)| match (o, h, l, c) {
1289            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1290                Some(indicator.next((o_, h_, l_, c_)) as f64),
1291            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1292            _ => None,
1293        }).collect();
1294    Ok(out.into_series())
1295}
1296
1297#[polars_expr(output_type=Float64)]
1298fn cdl_mathold(inputs: &[Series]) -> PolarsResult<Series> {
1299    let open = inputs[0].f64()?;
1300    let high = inputs[1].f64()?;
1301    let low = inputs[2].f64()?;
1302    let close = inputs[3].f64()?;
1303    let mut indicator = quantwave_core::CDLMATHOLD::new();
1304    let out: Float64Chunked = open.into_iter()
1305        .zip(high.into_iter())
1306        .zip(low.into_iter())
1307        .zip(close.into_iter())
1308        .map(|(((o, h), l), c)| match (o, h, l, c) {
1309            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1310                Some(indicator.next((o_, h_, l_, c_)) as f64),
1311            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1312            _ => None,
1313        }).collect();
1314    Ok(out.into_series())
1315}
1316
1317#[polars_expr(output_type=Float64)]
1318fn cdl_morningdojistar(inputs: &[Series]) -> PolarsResult<Series> {
1319    let open = inputs[0].f64()?;
1320    let high = inputs[1].f64()?;
1321    let low = inputs[2].f64()?;
1322    let close = inputs[3].f64()?;
1323    let mut indicator = quantwave_core::CDLMORNINGDOJISTAR::new();
1324    let out: Float64Chunked = open.into_iter()
1325        .zip(high.into_iter())
1326        .zip(low.into_iter())
1327        .zip(close.into_iter())
1328        .map(|(((o, h), l), c)| match (o, h, l, c) {
1329            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1330                Some(indicator.next((o_, h_, l_, c_)) as f64),
1331            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1332            _ => None,
1333        }).collect();
1334    Ok(out.into_series())
1335}
1336
1337#[polars_expr(output_type=Float64)]
1338fn cdl_morningstar(inputs: &[Series]) -> PolarsResult<Series> {
1339    let open = inputs[0].f64()?;
1340    let high = inputs[1].f64()?;
1341    let low = inputs[2].f64()?;
1342    let close = inputs[3].f64()?;
1343    let mut indicator = quantwave_core::CDLMORNINGSTAR::new();
1344    let out: Float64Chunked = open.into_iter()
1345        .zip(high.into_iter())
1346        .zip(low.into_iter())
1347        .zip(close.into_iter())
1348        .map(|(((o, h), l), c)| match (o, h, l, c) {
1349            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1350                Some(indicator.next((o_, h_, l_, c_)) as f64),
1351            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1352            _ => None,
1353        }).collect();
1354    Ok(out.into_series())
1355}
1356
1357#[polars_expr(output_type=Float64)]
1358fn cdl_onneck(inputs: &[Series]) -> PolarsResult<Series> {
1359    let open = inputs[0].f64()?;
1360    let high = inputs[1].f64()?;
1361    let low = inputs[2].f64()?;
1362    let close = inputs[3].f64()?;
1363    let mut indicator = quantwave_core::CDLONNECK::new();
1364    let out: Float64Chunked = open.into_iter()
1365        .zip(high.into_iter())
1366        .zip(low.into_iter())
1367        .zip(close.into_iter())
1368        .map(|(((o, h), l), c)| match (o, h, l, c) {
1369            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1370                Some(indicator.next((o_, h_, l_, c_)) as f64),
1371            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1372            _ => None,
1373        }).collect();
1374    Ok(out.into_series())
1375}
1376
1377#[polars_expr(output_type=Float64)]
1378fn cdl_piercing(inputs: &[Series]) -> PolarsResult<Series> {
1379    let open = inputs[0].f64()?;
1380    let high = inputs[1].f64()?;
1381    let low = inputs[2].f64()?;
1382    let close = inputs[3].f64()?;
1383    let mut indicator = quantwave_core::CDLPIERCING::new();
1384    let out: Float64Chunked = open.into_iter()
1385        .zip(high.into_iter())
1386        .zip(low.into_iter())
1387        .zip(close.into_iter())
1388        .map(|(((o, h), l), c)| match (o, h, l, c) {
1389            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1390                Some(indicator.next((o_, h_, l_, c_)) as f64),
1391            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1392            _ => None,
1393        }).collect();
1394    Ok(out.into_series())
1395}
1396
1397#[polars_expr(output_type=Float64)]
1398fn cdl_rickshawman(inputs: &[Series]) -> PolarsResult<Series> {
1399    let open = inputs[0].f64()?;
1400    let high = inputs[1].f64()?;
1401    let low = inputs[2].f64()?;
1402    let close = inputs[3].f64()?;
1403    let mut indicator = quantwave_core::CDLRICKSHAWMAN::new();
1404    let out: Float64Chunked = open.into_iter()
1405        .zip(high.into_iter())
1406        .zip(low.into_iter())
1407        .zip(close.into_iter())
1408        .map(|(((o, h), l), c)| match (o, h, l, c) {
1409            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1410                Some(indicator.next((o_, h_, l_, c_)) as f64),
1411            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1412            _ => None,
1413        }).collect();
1414    Ok(out.into_series())
1415}
1416
1417#[polars_expr(output_type=Float64)]
1418fn cdl_risefall3methods(inputs: &[Series]) -> PolarsResult<Series> {
1419    let open = inputs[0].f64()?;
1420    let high = inputs[1].f64()?;
1421    let low = inputs[2].f64()?;
1422    let close = inputs[3].f64()?;
1423    let mut indicator = quantwave_core::CDLRISEFALL3METHODS::new();
1424    let out: Float64Chunked = open.into_iter()
1425        .zip(high.into_iter())
1426        .zip(low.into_iter())
1427        .zip(close.into_iter())
1428        .map(|(((o, h), l), c)| match (o, h, l, c) {
1429            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1430                Some(indicator.next((o_, h_, l_, c_)) as f64),
1431            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1432            _ => None,
1433        }).collect();
1434    Ok(out.into_series())
1435}
1436
1437#[polars_expr(output_type=Float64)]
1438fn cdl_separatinglines(inputs: &[Series]) -> PolarsResult<Series> {
1439    let open = inputs[0].f64()?;
1440    let high = inputs[1].f64()?;
1441    let low = inputs[2].f64()?;
1442    let close = inputs[3].f64()?;
1443    let mut indicator = quantwave_core::CDLSEPARATINGLINES::new();
1444    let out: Float64Chunked = open.into_iter()
1445        .zip(high.into_iter())
1446        .zip(low.into_iter())
1447        .zip(close.into_iter())
1448        .map(|(((o, h), l), c)| match (o, h, l, c) {
1449            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1450                Some(indicator.next((o_, h_, l_, c_)) as f64),
1451            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1452            _ => None,
1453        }).collect();
1454    Ok(out.into_series())
1455}
1456
1457#[polars_expr(output_type=Float64)]
1458fn cdl_shootingstar(inputs: &[Series]) -> PolarsResult<Series> {
1459    let open = inputs[0].f64()?;
1460    let high = inputs[1].f64()?;
1461    let low = inputs[2].f64()?;
1462    let close = inputs[3].f64()?;
1463    let mut indicator = quantwave_core::CDLSHOOTINGSTAR::new();
1464    let out: Float64Chunked = open.into_iter()
1465        .zip(high.into_iter())
1466        .zip(low.into_iter())
1467        .zip(close.into_iter())
1468        .map(|(((o, h), l), c)| match (o, h, l, c) {
1469            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1470                Some(indicator.next((o_, h_, l_, c_)) as f64),
1471            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1472            _ => None,
1473        }).collect();
1474    Ok(out.into_series())
1475}
1476
1477#[polars_expr(output_type=Float64)]
1478fn cdl_shortline(inputs: &[Series]) -> PolarsResult<Series> {
1479    let open = inputs[0].f64()?;
1480    let high = inputs[1].f64()?;
1481    let low = inputs[2].f64()?;
1482    let close = inputs[3].f64()?;
1483    let mut indicator = quantwave_core::CDLSHORTLINE::new();
1484    let out: Float64Chunked = open.into_iter()
1485        .zip(high.into_iter())
1486        .zip(low.into_iter())
1487        .zip(close.into_iter())
1488        .map(|(((o, h), l), c)| match (o, h, l, c) {
1489            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1490                Some(indicator.next((o_, h_, l_, c_)) as f64),
1491            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1492            _ => None,
1493        }).collect();
1494    Ok(out.into_series())
1495}
1496
1497#[polars_expr(output_type=Float64)]
1498fn cdl_spinningtop(inputs: &[Series]) -> PolarsResult<Series> {
1499    let open = inputs[0].f64()?;
1500    let high = inputs[1].f64()?;
1501    let low = inputs[2].f64()?;
1502    let close = inputs[3].f64()?;
1503    let mut indicator = quantwave_core::CDLSPINNINGTOP::new();
1504    let out: Float64Chunked = open.into_iter()
1505        .zip(high.into_iter())
1506        .zip(low.into_iter())
1507        .zip(close.into_iter())
1508        .map(|(((o, h), l), c)| match (o, h, l, c) {
1509            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1510                Some(indicator.next((o_, h_, l_, c_)) as f64),
1511            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1512            _ => None,
1513        }).collect();
1514    Ok(out.into_series())
1515}
1516
1517#[polars_expr(output_type=Float64)]
1518fn cdl_stalledpattern(inputs: &[Series]) -> PolarsResult<Series> {
1519    let open = inputs[0].f64()?;
1520    let high = inputs[1].f64()?;
1521    let low = inputs[2].f64()?;
1522    let close = inputs[3].f64()?;
1523    let mut indicator = quantwave_core::CDLSTALLEDPATTERN::new();
1524    let out: Float64Chunked = open.into_iter()
1525        .zip(high.into_iter())
1526        .zip(low.into_iter())
1527        .zip(close.into_iter())
1528        .map(|(((o, h), l), c)| match (o, h, l, c) {
1529            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1530                Some(indicator.next((o_, h_, l_, c_)) as f64),
1531            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1532            _ => None,
1533        }).collect();
1534    Ok(out.into_series())
1535}
1536
1537#[polars_expr(output_type=Float64)]
1538fn cdl_sticksandwich(inputs: &[Series]) -> PolarsResult<Series> {
1539    let open = inputs[0].f64()?;
1540    let high = inputs[1].f64()?;
1541    let low = inputs[2].f64()?;
1542    let close = inputs[3].f64()?;
1543    let mut indicator = quantwave_core::CDLSTICKSANDWICH::new();
1544    let out: Float64Chunked = open.into_iter()
1545        .zip(high.into_iter())
1546        .zip(low.into_iter())
1547        .zip(close.into_iter())
1548        .map(|(((o, h), l), c)| match (o, h, l, c) {
1549            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1550                Some(indicator.next((o_, h_, l_, c_)) as f64),
1551            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1552            _ => None,
1553        }).collect();
1554    Ok(out.into_series())
1555}
1556
1557#[polars_expr(output_type=Float64)]
1558fn cdl_takuri(inputs: &[Series]) -> PolarsResult<Series> {
1559    let open = inputs[0].f64()?;
1560    let high = inputs[1].f64()?;
1561    let low = inputs[2].f64()?;
1562    let close = inputs[3].f64()?;
1563    let mut indicator = quantwave_core::CDLTAKURI::new();
1564    let out: Float64Chunked = open.into_iter()
1565        .zip(high.into_iter())
1566        .zip(low.into_iter())
1567        .zip(close.into_iter())
1568        .map(|(((o, h), l), c)| match (o, h, l, c) {
1569            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1570                Some(indicator.next((o_, h_, l_, c_)) as f64),
1571            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1572            _ => None,
1573        }).collect();
1574    Ok(out.into_series())
1575}
1576
1577#[polars_expr(output_type=Float64)]
1578fn cdl_tasukigap(inputs: &[Series]) -> PolarsResult<Series> {
1579    let open = inputs[0].f64()?;
1580    let high = inputs[1].f64()?;
1581    let low = inputs[2].f64()?;
1582    let close = inputs[3].f64()?;
1583    let mut indicator = quantwave_core::CDLTASUKIGAP::new();
1584    let out: Float64Chunked = open.into_iter()
1585        .zip(high.into_iter())
1586        .zip(low.into_iter())
1587        .zip(close.into_iter())
1588        .map(|(((o, h), l), c)| match (o, h, l, c) {
1589            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1590                Some(indicator.next((o_, h_, l_, c_)) as f64),
1591            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1592            _ => None,
1593        }).collect();
1594    Ok(out.into_series())
1595}
1596
1597#[polars_expr(output_type=Float64)]
1598fn cdl_thrusting(inputs: &[Series]) -> PolarsResult<Series> {
1599    let open = inputs[0].f64()?;
1600    let high = inputs[1].f64()?;
1601    let low = inputs[2].f64()?;
1602    let close = inputs[3].f64()?;
1603    let mut indicator = quantwave_core::CDLTHRUSTING::new();
1604    let out: Float64Chunked = open.into_iter()
1605        .zip(high.into_iter())
1606        .zip(low.into_iter())
1607        .zip(close.into_iter())
1608        .map(|(((o, h), l), c)| match (o, h, l, c) {
1609            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1610                Some(indicator.next((o_, h_, l_, c_)) as f64),
1611            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1612            _ => None,
1613        }).collect();
1614    Ok(out.into_series())
1615}
1616
1617#[polars_expr(output_type=Float64)]
1618fn cdl_tristar(inputs: &[Series]) -> PolarsResult<Series> {
1619    let open = inputs[0].f64()?;
1620    let high = inputs[1].f64()?;
1621    let low = inputs[2].f64()?;
1622    let close = inputs[3].f64()?;
1623    let mut indicator = quantwave_core::CDLTRISTAR::new();
1624    let out: Float64Chunked = open.into_iter()
1625        .zip(high.into_iter())
1626        .zip(low.into_iter())
1627        .zip(close.into_iter())
1628        .map(|(((o, h), l), c)| match (o, h, l, c) {
1629            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1630                Some(indicator.next((o_, h_, l_, c_)) as f64),
1631            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1632            _ => None,
1633        }).collect();
1634    Ok(out.into_series())
1635}
1636
1637#[polars_expr(output_type=Float64)]
1638fn cdl_unique3river(inputs: &[Series]) -> PolarsResult<Series> {
1639    let open = inputs[0].f64()?;
1640    let high = inputs[1].f64()?;
1641    let low = inputs[2].f64()?;
1642    let close = inputs[3].f64()?;
1643    let mut indicator = quantwave_core::CDLUNIQUE3RIVER::new();
1644    let out: Float64Chunked = open.into_iter()
1645        .zip(high.into_iter())
1646        .zip(low.into_iter())
1647        .zip(close.into_iter())
1648        .map(|(((o, h), l), c)| match (o, h, l, c) {
1649            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1650                Some(indicator.next((o_, h_, l_, c_)) as f64),
1651            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1652            _ => None,
1653        }).collect();
1654    Ok(out.into_series())
1655}
1656
1657#[polars_expr(output_type=Float64)]
1658fn cdl_upsidegap2crows(inputs: &[Series]) -> PolarsResult<Series> {
1659    let open = inputs[0].f64()?;
1660    let high = inputs[1].f64()?;
1661    let low = inputs[2].f64()?;
1662    let close = inputs[3].f64()?;
1663    let mut indicator = quantwave_core::CDLUPSIDEGAP2CROWS::new();
1664    let out: Float64Chunked = open.into_iter()
1665        .zip(high.into_iter())
1666        .zip(low.into_iter())
1667        .zip(close.into_iter())
1668        .map(|(((o, h), l), c)| match (o, h, l, c) {
1669            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1670                Some(indicator.next((o_, h_, l_, c_)) as f64),
1671            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1672            _ => None,
1673        }).collect();
1674    Ok(out.into_series())
1675}
1676
1677#[polars_expr(output_type=Float64)]
1678fn cdl_xsidegap3methods(inputs: &[Series]) -> PolarsResult<Series> {
1679    let open = inputs[0].f64()?;
1680    let high = inputs[1].f64()?;
1681    let low = inputs[2].f64()?;
1682    let close = inputs[3].f64()?;
1683    let mut indicator = quantwave_core::CDLXSIDEGAP3METHODS::new();
1684    let out: Float64Chunked = open.into_iter()
1685        .zip(high.into_iter())
1686        .zip(low.into_iter())
1687        .zip(close.into_iter())
1688        .map(|(((o, h), l), c)| match (o, h, l, c) {
1689            (Some(o_), Some(h_), Some(l_), Some(c_)) if !o_.is_nan() && !h_.is_nan() && !l_.is_nan() && !c_.is_nan() => 
1690                Some(indicator.next((o_, h_, l_, c_)) as f64),
1691            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
1692            _ => None,
1693        }).collect();
1694    Ok(out.into_series())
1695}