use polars_core::prelude::*;
use polars_ta_core::math_ops;
fn series_to_f64(s: &Series) -> PolarsResult<Vec<f64>> {
Ok(s.cast(&DataType::Float64)?
.f64()?
.into_iter()
.map(|v| v.unwrap_or(f64::NAN))
.collect())
}
fn vec_to_series(name: PlSmallStr, v: Vec<f64>) -> Series {
Float64Chunked::from_vec(name, v).into_series()
}
pub fn add_series(real0: &Series, real1: &Series) -> PolarsResult<Series> {
let a = series_to_f64(real0)?;
let b = series_to_f64(real1)?;
Ok(vec_to_series(real0.name().clone(), math_ops::add(&a, &b)))
}
pub fn div_series(real0: &Series, real1: &Series) -> PolarsResult<Series> {
let a = series_to_f64(real0)?;
let b = series_to_f64(real1)?;
Ok(vec_to_series(real0.name().clone(), math_ops::div(&a, &b)))
}
pub fn mult_series(real0: &Series, real1: &Series) -> PolarsResult<Series> {
let a = series_to_f64(real0)?;
let b = series_to_f64(real1)?;
Ok(vec_to_series(real0.name().clone(), math_ops::mult(&a, &b)))
}
pub fn sub_series(real0: &Series, real1: &Series) -> PolarsResult<Series> {
let a = series_to_f64(real0)?;
let b = series_to_f64(real1)?;
Ok(vec_to_series(real0.name().clone(), math_ops::sub(&a, &b)))
}
pub fn max_series(s: &Series, period: usize) -> PolarsResult<Series> {
let data = series_to_f64(s)?;
Ok(vec_to_series(
s.name().clone(),
math_ops::max(&data, period),
))
}
pub fn min_series(s: &Series, period: usize) -> PolarsResult<Series> {
let data = series_to_f64(s)?;
Ok(vec_to_series(
s.name().clone(),
math_ops::min(&data, period),
))
}
pub fn sum_series(s: &Series, period: usize) -> PolarsResult<Series> {
let data = series_to_f64(s)?;
Ok(vec_to_series(
s.name().clone(),
math_ops::sum(&data, period),
))
}
pub fn maxindex_series(s: &Series, period: usize) -> PolarsResult<Series> {
let data = series_to_f64(s)?;
Ok(vec_to_series(
s.name().clone(),
math_ops::maxindex(&data, period),
))
}
pub fn minindex_series(s: &Series, period: usize) -> PolarsResult<Series> {
let data = series_to_f64(s)?;
Ok(vec_to_series(
s.name().clone(),
math_ops::minindex(&data, period),
))
}
pub struct MinMaxSeriesOutput {
pub min: Series,
pub max: Series,
}
pub fn minmax_series(s: &Series, period: usize) -> PolarsResult<MinMaxSeriesOutput> {
let data = series_to_f64(s)?;
let out = math_ops::minmax(&data, period);
Ok(MinMaxSeriesOutput {
min: vec_to_series(format!("{}_min", s.name()).into(), out.min),
max: vec_to_series(format!("{}_max", s.name()).into(), out.max),
})
}
pub struct MinMaxIndexSeriesOutput {
pub min_idx: Series,
pub max_idx: Series,
}
pub fn minmaxindex_series(s: &Series, period: usize) -> PolarsResult<MinMaxIndexSeriesOutput> {
let data = series_to_f64(s)?;
let out = math_ops::minmaxindex(&data, period);
Ok(MinMaxIndexSeriesOutput {
min_idx: vec_to_series(format!("{}_min_idx", s.name()).into(), out.min_idx),
max_idx: vec_to_series(format!("{}_max_idx", s.name()).into(), out.max_idx),
})
}