quantwave_plugins/
volume.rs1use polars::prelude::*;
2use pyo3_polars::derive::polars_expr;
3use serde::Deserialize;
4
5use quantwave_core::indicators::incremental::volume_ta::{AD, ADOSC};
6use quantwave_core::traits::Next;
7
8#[derive(Deserialize)]
9struct AdoscKwargs {
10 fastperiod: usize,
11 slowperiod: usize,
12}
13
14#[polars_expr(output_type=Float64)]
15fn ad(inputs: &[Series]) -> PolarsResult<Series> {
16 let high = inputs[0].f64()?;
17 let low = inputs[1].f64()?;
18 let close = inputs[2].f64()?;
19 let volume = inputs[3].f64()?;
20
21 let mut indicator = AD::new();
22
23 let out: Float64Chunked = high.into_iter().zip(low.into_iter()).zip(close.into_iter()).zip(volume.into_iter()).map(|(((h, l), c), v)| {
24 match (h, l, c, v) {
25 (Some(hv), Some(lv), Some(cv), Some(vv)) if !hv.is_nan() && !lv.is_nan() && !cv.is_nan() && !vv.is_nan() => Some(indicator.next((hv, lv, cv, vv))),
26 (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
27 _ => None,
28 }
29 }).collect();
30
31 Ok(out.into_series())
32}
33
34#[polars_expr(output_type=Float64)]
35fn adosc(inputs: &[Series], kwargs: AdoscKwargs) -> PolarsResult<Series> {
36 let high = inputs[0].f64()?;
37 let low = inputs[1].f64()?;
38 let close = inputs[2].f64()?;
39 let volume = inputs[3].f64()?;
40
41 let mut indicator = ADOSC::new(kwargs.fastperiod, kwargs.slowperiod);
42
43 let out: Float64Chunked = high.into_iter().zip(low.into_iter()).zip(close.into_iter()).zip(volume.into_iter()).map(|(((h, l), c), v)| {
44 match (h, l, c, v) {
45 (Some(hv), Some(lv), Some(cv), Some(vv)) if !hv.is_nan() && !lv.is_nan() && !cv.is_nan() && !vv.is_nan() => Some(indicator.next((hv, lv, cv, vv))),
46 (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
47 _ => None,
48 }
49 }).collect();
50
51 Ok(out.into_series())
52}
53
54