Skip to main content

quantwave_plugins/
volume.rs

1use 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// OBV is missing from volume_ta.rs in core or maybe it is there but I missed it in grep.
55// Let's hold off on OBV until I double check if it's there.