use polars::prelude::*;
use super::{Quant, Tic};
#[derive(Debug)]
pub struct Quantum {
quants: Vec<Quant>,
}
impl Quantum {
pub fn from_tics(tics: &[Tic]) -> Self {
assert!(!tics.is_empty());
let mut prices = Vec::new();
for tic in tics.iter() {
prices.push(tic.price);
}
let unique = Series::new("prices".into(), prices).unique().unwrap();
let mut quants = Vec::new();
for price in unique.f64().unwrap().into_no_null_iter() {
let mut quant = Quant::new(price);
for tic in tics.iter() {
if tic.price == price {
quant.add(tic);
}
}
quants.push(quant);
}
Self { quants }
}
pub fn from_quants(quants: Vec<Quant>) -> Self {
assert!(!quants.is_empty());
Self { quants }
}
pub fn schema() -> Schema {
Schema::from_iter(vec![
Field::new("price".into(), DataType::Float64),
Field::new("vol_b".into(), DataType::UInt64),
Field::new("vol_s".into(), DataType::UInt64),
Field::new("val_b".into(), DataType::Float64),
Field::new("val_s".into(), DataType::Float64),
])
}
pub fn df(&self) -> DataFrame {
let mut prices = Vec::new();
let mut vol_b = Vec::new();
let mut vol_s = Vec::new();
let mut val_b = Vec::new();
let mut val_s = Vec::new();
for quant in self.quants.iter() {
prices.push(quant.price);
vol_b.push(quant.vol_b);
vol_s.push(quant.vol_s);
val_b.push(quant.val_b);
val_s.push(quant.val_s);
}
df!(
"price" => prices,
"vol_b" => vol_b,
"vol_s" => vol_s,
"val_b" => val_b,
"val_s" => val_s,
)
.unwrap()
}
pub fn poc(&self) -> Quant {
let mut max = self.quants.first().unwrap();
for q in self.quants.iter() {
if q.vol() > max.vol() {
max = q;
}
}
max.clone()
}
pub fn quants(&self) -> &Vec<Quant> {
&self.quants
}
}
#[cfg(test)]
mod tests {
use super::*;
use avin_utils as utils;
#[test]
fn quantum() {
let path = std::path::Path::new(
"/home/alex/trading/data/MOEX/SHARE/GAZP/TIC/2025/2025-06-06.parquet",
);
let df = utils::Cmd::read_pqt(path).unwrap();
let df = df.tail(Some(10));
let tics = Tic::from_df(&df).unwrap();
let quantum = Quantum::from_tics(&tics);
let _df = quantum.df();
let poc = quantum.poc();
assert_eq!(poc.price, 125.81);
assert_eq!(poc.vol(), 905);
assert_eq!(poc.val(), 1138580.5);
}
}