quantwave_plugins/
price_transform.rs1use 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}