Skip to main content

quantwave_plugins/
price_transform.rs

1use polars::prelude::*;
2use pyo3_polars::derive::polars_expr;
3
4use quantwave_core::indicators::incremental::price_transform::{AVGPRICE, MEDPRICE, TYPPRICE, WCLPRICE};
5use quantwave_core::traits::Next;
6
7#[polars_expr(output_type=Float64)]
8fn avgprice(inputs: &[Series]) -> PolarsResult<Series> {
9    let open = inputs[0].f64()?;
10    let high = inputs[1].f64()?;
11    let low = inputs[2].f64()?;
12    let close = inputs[3].f64()?;
13    
14    let mut indicator = AVGPRICE::new();
15    
16    let out: Float64Chunked = open.into_iter().zip(high.into_iter()).zip(low.into_iter()).zip(close.into_iter()).map(|(((o, h), l), c)| {
17        match (o, h, l, c) {
18            (Some(ov), Some(hv), Some(lv), Some(cv)) if !ov.is_nan() && !hv.is_nan() && !lv.is_nan() && !cv.is_nan() => Some(indicator.next((ov, hv, lv, cv))),
19            (Some(_), Some(_), Some(_), Some(_)) => Some(f64::NAN),
20            _ => None,
21        }
22    }).collect();
23    
24    Ok(out.into_series())
25}
26
27#[polars_expr(output_type=Float64)]
28fn medprice(inputs: &[Series]) -> PolarsResult<Series> {
29    let high = inputs[0].f64()?;
30    let low = inputs[1].f64()?;
31    
32    let mut indicator = MEDPRICE::new();
33    
34    let out: Float64Chunked = high.into_iter().zip(low.into_iter()).map(|(h, l)| {
35        match (h, l) {
36            (Some(hv), Some(lv)) if !hv.is_nan() && !lv.is_nan() => Some(indicator.next((hv, lv))),
37            (Some(_), Some(_)) => Some(f64::NAN),
38            _ => None,
39        }
40    }).collect();
41    
42    Ok(out.into_series())
43}
44
45#[polars_expr(output_type=Float64)]
46fn typprice(inputs: &[Series]) -> PolarsResult<Series> {
47    let high = inputs[0].f64()?;
48    let low = inputs[1].f64()?;
49    let close = inputs[2].f64()?;
50    
51    let mut indicator = TYPPRICE::new();
52    
53    let out: Float64Chunked = high.into_iter().zip(low.into_iter()).zip(close.into_iter()).map(|((h, l), c)| {
54        match (h, l, c) {
55            (Some(hv), Some(lv), Some(cv)) if !hv.is_nan() && !lv.is_nan() && !cv.is_nan() => Some(indicator.next((hv, lv, cv))),
56            (Some(_), Some(_), Some(_)) => Some(f64::NAN),
57            _ => None,
58        }
59    }).collect();
60    
61    Ok(out.into_series())
62}
63
64#[polars_expr(output_type=Float64)]
65fn wclprice(inputs: &[Series]) -> PolarsResult<Series> {
66    let high = inputs[0].f64()?;
67    let low = inputs[1].f64()?;
68    let close = inputs[2].f64()?;
69    
70    let mut indicator = WCLPRICE::new();
71    
72    let out: Float64Chunked = high.into_iter().zip(low.into_iter()).zip(close.into_iter()).map(|((h, l), c)| {
73        match (h, l, c) {
74            (Some(hv), Some(lv), Some(cv)) if !hv.is_nan() && !lv.is_nan() && !cv.is_nan() => Some(indicator.next((hv, lv, cv))),
75            (Some(_), Some(_), Some(_)) => Some(f64::NAN),
76            _ => None,
77        }
78    }).collect();
79    
80    Ok(out.into_series())
81}