use chrono::{DateTime, Utc};
use czsc_core::objects::{bar::RawBar, freq::Freq, market::Market};
use pyo3::prelude::*;
use pyo3_stub_gen::derive::gen_stub_pyfunction;
use crate::bar_generator::BarGenerator;
#[pyfunction]
#[pyo3(signature = (dt, market="astock"))]
fn is_trading_time(dt: chrono::NaiveDateTime, market: &str) -> bool {
crate::is_trading_time(dt, market)
}
#[pyfunction]
#[pyo3(signature = (dt, freq, market=Market::Default))]
fn freq_end_time(dt: DateTime<Utc>, freq: Freq, market: Market) -> PyResult<DateTime<Utc>> {
crate::freq_data::freq_end_time(dt, freq, market)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
}
#[gen_stub_pyfunction]
#[pyfunction]
#[pyo3(signature = (sequence))]
fn monotonicity(sequence: Vec<f64>) -> f64 {
crate::monotonicity::monotonicity(&sequence)
}
#[pyfunction]
#[pyo3(signature = (bars, target_freq, drop_unfinished=true))]
fn resample_bars(
py: Python<'_>,
bars: Vec<RawBar>,
target_freq: Py<PyAny>,
drop_unfinished: bool,
) -> PyResult<Vec<RawBar>> {
use std::str::FromStr;
let target_freq = if let Ok(py_str) = target_freq.cast_bound::<pyo3::types::PyString>(py) {
let s = py_str.to_string();
Freq::from_str(&s).map_err(|e| {
pyo3::exceptions::PyValueError::new_err(format!("解析 target_freq 失败: {e}"))
})?
} else if let Ok(f) = target_freq.extract::<Freq>(py) {
f
} else {
return Err(pyo3::exceptions::PyValueError::new_err(
"target_freq 必须是 Freq 枚举或中文周期字符串",
));
};
crate::resample::resample_bars(&bars, target_freq, drop_unfinished)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
}
pub fn register(py: Python<'_>, parent: &Bound<'_, PyModule>) -> PyResult<()> {
let utils = PyModule::new(py, "utils")?;
utils.add_function(wrap_pyfunction!(is_trading_time, &utils)?)?;
utils.add_function(wrap_pyfunction!(freq_end_time, &utils)?)?;
utils.add_function(wrap_pyfunction!(monotonicity, &utils)?)?;
utils.add_function(wrap_pyfunction!(resample_bars, &utils)?)?;
utils.add_class::<BarGenerator>()?;
parent.add_submodule(&utils)?;
parent.add_function(wrap_pyfunction!(is_trading_time, parent)?)?;
parent.add_function(wrap_pyfunction!(freq_end_time, parent)?)?;
parent.add_function(wrap_pyfunction!(monotonicity, parent)?)?;
parent.add_function(wrap_pyfunction!(resample_bars, parent)?)?;
parent.add_class::<BarGenerator>()?;
Ok(())
}